
//#include <cassert>
;
#include <iostream>
using namespace std;

#include <commandline.h>
#include <print.h>
#include <random.h>

#include <minimizecomparetest.h>

#include <exploreh.h>
#include <leastsqrs.h>
//#include <probparab.h>
#include <probsysequ01.h>
#include <patternsearch.h>
#include <patternsearchD2.h>
#include <explorequad.h>
#include <explorerand.h>
#include <exploreline.h>
#include <lineoptimizergold.h>
// #includ <powell02.h>
#include <probrosenbrock.h>
//#include <linepathd1.h>
#include <lineoptimizergold2.h>


void minimizecomparetest01(int argc, char** argv)
{
  cout << "Testing optimizers for a 2 variable non-linear system" << endl << endl;

  commandline cmd(argc,argv);

  uint counter(200);
  cmd.mapvar(counter,"counter");

  uint dim=1; 
  cmd.mapvar(dim,"dim" );

  uintc n(2);
  double x0[n] = { 0.5, 0.5 };


  cout << "exploreh" << endl;
  exploreh<probsysequ01,double*,double> g1(n,0.2,50000);
  for ( g1.reset(x0); g1.fn.counter<counter; )
    ++g1;
  //cout << printvecfunc(g1.xi,n) << endl;
  cout << "g1.xi[]=" << print(g1.xi,g1.xi+n) << endl;
  cout << SHOW(g1.fn.counter) << endl;
  cout << SHOW(g1.fmin) << endl;

  cout << "patternsearch" << endl;
  typedef exploreh<probsysequ01,double*,double> e1;
  e1 f2(n,0.2,5000);
  patternsearch< e1 & > g2(f2,0.2);

  for ( g2.reset(x0); g2.exp.fn.counter<counter; )
    ++g2;
  //cout << printvecfunc(g2.exp.xi,n) << endl;
  cout << "g2.exp.xi[]=" << print(g2.exp.xi,g2.exp.xi+n) << endl;
  cout << SHOW(f2.fn.counter) << endl;
  cout << SHOW(f2.fmin) << endl;

  cout << "pattern with explorequad  " <<  SHOW(dim) << endl;
  typedef explorequad< exploreh<probsysequ01,double*,double> > eh2;
  eh2 f3(n,0.2,5000);
  patternsearchD2< eh2 & > g3(f3,dim,0.2);
  for ( g3.reset(x0); f3.fn.counter<counter; )
    ++g3;
  //cout << printvecfunc(g3.exp.xi,n) << endl;
  cout << "g3.exp.xi[]=" << print(g3.exp.xi,g3.exp.xi+n) << endl;
  cout << SHOW(f3.fn.counter) << endl;
  cout << SHOW(f3.fmin) << endl;

  cout << "pattern  " << SHOW(dim) << endl;
  f2.fn.counter=0;
  patternsearchD2< e1 & > g4(f2,dim,0.2);
  for ( g4.reset(x0); f2.fn.counter<counter; )
    ++g4;
  //cout << printvecfunc(g4.exp.xi,n) << endl;
  cout << "g4.exp.xi[]=" << print(g4.exp.xi,g4.exp.xi+n) << endl;
  cout << SHOW(f2.fn.counter) << endl;
  cout << SHOW(f2.fmin) << endl;

  cout << "explorerand" << endl;
  explorerand< exploreh<probsysequ01,double*,double>, random00<> > g5(n,0.2,50000);
  for ( g5.reset(x0); g5.fn.counter<counter; )
    ++g5;
  //cout << printvecfunc(g5.xi,n) << endl;
  cout << "g5.exp.xi[]=" << print(g5.xi,g5.xi+n) << endl;
  cout << SHOW(g5.fn.counter) << endl;
  cout << SHOW(g5.fmin) << endl;

}

template< typename T >
long double const solutiondistance01(T & w)
{
  long double y0(0.2);
  long double y1((double)2.0/(double)3.0);
  return (w.xi[0]-y0)*(w.xi[0]-y0) + (w.xi[1]-y1)*(w.xi[1]-y1);
}

void minimizecomparetest02(int argc, char** argv)
{
  cout << "Testing optimizers for a 2 variable non-linear system" << endl << endl;

  commandline cmd(argc,argv);

  uint counter(200);
  cmd.mapvar(counter,"counter");

  uint dim=1; 
  cmd.mapvar(dim,"dim" );

  uintc n(2);
  double x0[n] = { 0.5, 0.5 };

  exploreh<probsysequ01,double*,double> g1(n,0.2,50000);
  for ( g1.reset(x0); g1.fn.counter<counter; )
    ++g1;
  cout << "exploreh              " << g1.fn.counter << " " << scientific;
  cout << g1.fmin << " " << solutiondistance01(g1) << endl;

//  cout << "patternsearch" << endl;
  typedef exploreh<probsysequ01,double*,double> e1;
  e1 f2(n,0.2,5000);
  patternsearch< e1 & > g2(f2,0.2);

  for ( g2.reset(x0); g2.exp.fn.counter<counter; )
    ++g2;
  cout << "patternsearch         " << g2.exp.fn.counter << " " << scientific;
  cout << g2.exp.fmin << " " << solutiondistance01(g2.exp) << endl;


  typedef explorequad< exploreh<probsysequ01,double*,double> > eh2;
  eh2 f3(n,0.2,5000);
  patternsearchD2< eh2 & > g3(f3,dim,0.2);
  for ( g3.reset(x0); f3.fn.counter<counter; )
    ++g3;
  cout << "patternD(expquad) D=" << dim << " ";
  cout << g3.exp.fn.counter << " " << scientific;
  cout << g3.exp.fmin << " " << solutiondistance01(g3.exp) << endl;

  f2.fn.counter=0;
  patternsearchD2< e1 & > g4(f2,dim,0.2);
  for ( g4.reset(x0); f2.fn.counter<counter; )
    ++g4;
  cout << "patternD(exph) D=" << dim << "    ";
  cout << g4.exp.fn.counter << " " << scientific;
  cout << g4.exp.fmin << " " << solutiondistance01(g4.exp) << endl;

  explorerand< exploreh<probsysequ01,double*,double>, random00<> > g5(n,0.2,50000);
  for ( g5.reset(x0); g5.fn.counter<counter; )
    ++g5;
  cout << "explorerand           ";
  cout << g5.fn.counter << " " << scientific;
  cout << g5.fmin << " " << solutiondistance01(g5) << endl;

  uint lineiter(10);
  cmd.mapvar(lineiter,"lineiter");

  typedef exploreh<probsysequ01,double*,double> exp2;
  typedef lineoptimizergold<probsysequ01,double*,double*,double> lnmin;

  exploreline< exp2, lnmin > g6(2,lineiter);

  cmd.mapvar(g6.linet0,"t0");
  cmd.mapvar(g6.linet1,"t1");
  for ( g6.reset(x0); g6.fn.counter<counter; )
    ++g6;
  cout << "exp(linegold) i=" << lineiter << "  ";
  cout << g6.fn.counter << " " << scientific;
  cout << g6.fmin << " " << solutiondistance01(g6) << endl;





  //typedef exploreh<probrosenbrock01,double*,double> e3;
  //typedef lineoptimizergold<probrosenbrock01,double*,double*,double> lnmin3;
  //exploreline< e3, lnmin3 > g7(2,lineiter);

  typedef lineoptimizergold<probsysequ01,double*,double*,double> lnmin2;
  exploreline< eh2, lnmin > g7(2,lineiter);

  cmd.mapvar(g7.linet0,"t0");
  cmd.mapvar(g7.linet1,"t1");
  for ( g7.reset(x0); g7.fn.counter<counter; )
    ++g7;
  cout << "expquad(linegold) i=" << lineiter << "  ";
  cout << g7.fn.counter << " " << scientific;
  cout << g7.fmin << " " << solutiondistance01(g7) << endl;


//  powell02< exp2, lnmin > g8(2,lineiter);
//  for ( g8.reset(x0); g8.exp.fn.counter<counter; )
//    ++g8;
//  cout << "powell02(linegold) i=" << lineiter << "  ";
//  cout << g8.exp.fn.counter << " " << scientific;
//  cout << g8.exp.fmin << " " << solutiondistance01(g8.exp) << endl;


  


}


void minimizecomparetest03(int argc, char** argv)
{
  cout << "Testing minimizers with the 2D Rosenbrock function." << endl;

/*
  commandline cmd(argc,argv);


  uint counter(200);
  cmd.mapvar(counter,"counter");

  uint dim=1; 
  cmd.mapvar(dim,"dim" );

  uint lineiter=15;
  cmd.mapvar(lineiter,"lineiter");

  uintc n(2);
  double x0[n] = { 0.0, 0.0 };

  typedef linepathd1< probrosenbrock01&,double*,double*,double > lpath;
  typedef lineoptimizergold2<lpath,double> lnmin; 
  typedef exploreh<probrosenbrock01,double*,double> exp2;
  powell02< exp2, lnmin > g8(2,lineiter);
*/

/*
  for ( g8.reset(x0); g8.exp.fn.counter<counter; )
    ++g8;
  cout << "powell02(linegold2) i=" << lineiter << "  ";
  cout << g8.exp.fn.counter << " " << scientific;
  cout << g8.exp.fmin << " " << solutiondistance01(g8.exp) << endl;
*/



}



