#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

#include <commandline.h>
#include <exploreh.h>
#include <exploreline.h>
#include <explorelinetest.h>
#include <explorequad.h>
#include <lineoptimizergold.h>
#include <print.h>
#include <probparab.h>
#include <probsysequ01.h>



void explorelinetest01(int argc, char** argv)
{
  cout << "explore and golden ratio line search" << endl;
  cout << "  k=3 lineiter=10 are defaults." << endl;


  typedef exploreh<probparab2,double*,double> exp2;
  typedef lineoptimizergold<probparab2&,double*,double*,double> lnmin;

  commandline cmd(argc,argv);
  uint lineiter(10);
  cmd.mapvar(lineiter,"lineiter");
  uint k(3);
  cmd.mapvar(k,"k");

  exploreline< exp2, lnmin > w(3,lineiter);

  cmd.mapvar(w.linet0,"t0");
  cmd.mapvar(w.linet1,"t1");

  double x0[3] = { 0.0, 0.0, 0.0 };
  w.reset(x0);
  //cout << printvecfunc(w.xi,3) << endl;

  for (uint i=0; i<k; ++i)
  {
    ++w;
  }

  double dist=0.0;
  dist = abs(w.xi[0]-1.0) + abs(w.xi[1]-2.0) + abs(w.xi[2]-5.0);

  cout << "Compare with true solution" << endl;
  cout << "fn-count, k, lineiter, distance" << endl;
  cout << w.fn.counter << "  ";
  cout << k << "  ";
  cout << lineiter << "  ";
  cout << scientific << dist << endl;


  //uintc imax=5;
  //for (uint i=0; i<imax; ++i)
  //  ++w;
  //cout << printvecfunc(w.xi,3) << endl;

}


void explorelinetest02(int argc, char** argv)
{
  cout << "exploreh with quad and golden ratio line search" << endl;
  cout << "  k=3 lineiter=10 are defaults." << endl;


  typedef explorequad< exploreh<probparab2,double*,double> > eh2;
//  typedef exploreh<probparab2,double*,double> exp2;
  typedef lineoptimizergold<probparab2&,double*,double*,double> lnmin;

  commandline cmd(argc,argv);
  uint lineiter(10);
  cmd.mapvar(lineiter,"lineiter");
  uint k(3);
  cmd.mapvar(k,"k");

  exploreline< eh2, lnmin > w(3,lineiter);

  cmd.mapvar(w.linet0,"t0");
  cmd.mapvar(w.linet1,"t1");

  double x0[3] = { 0.0, 0.0, 0.0 };
  w.reset(x0);
  //cout << printvecfunc(w.xi,3) << endl;

  
  //w.move();


  for (uint i=0; i<k; ++i)
    ++w;


  double dist=0.0;
  dist = abs(w.xi[0]-1.0) + abs(w.xi[1]-2.0) + abs(w.xi[2]-5.0);

  cout << "Compare with true solution" << endl;
  cout << "fn-count, k, lineiter, distance" << endl;
  cout << w.fn.counter << "  ";
  cout << k << "  ";
  cout << lineiter << "  ";
  cout << scientific << dist << endl;
}




void explorelinetest03(int argc, char** argv)
{
  cout << "explore and golden ratio line search" << endl;
  cout << "  k=3 lineiter=10 are defaults." << endl;

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

  commandline cmd(argc,argv);
  uint lineiter(10);
  cmd.mapvar(lineiter,"lineiter");
  uint k(3);
  cmd.mapvar(k,"k");

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

  cmd.mapvar(w.linet0,"t0");
  cmd.mapvar(w.linet1,"t1");

  double x0[2] = { 0.5, 0.5 };
  w.reset(x0);

  for (uint i=0; i<k; ++i)
  {
//cout << printvecfunc(w.xi,2) << endl;
    ++w;
//    cout << SHOW(w.fn.counter) << endl;
  }

  long double y0((long double)0.2);
  long double y1((long double)2.0/(long double)3.0);
  long double dist = (y0-w.xi[0])*(y0-w.xi[0]) + (y1-w.xi[1])*(y1-w.xi[1]);

  cout << "Compare with true solution" << endl;
  cout << "fn-count, k, lineiter, distance" << endl;
  cout << w.fn.counter << "  ";
  cout << k << "  ";
  cout << lineiter << "  ";
  cout << scientific << dist << endl;

}





