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

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

#include <probsysequ01.h>
#include <explorepd1.h>
#include <lineoptimizergold.h>
#include <exploreh.h>

#include <explorepdtest.h>

static double h0step=0.2;

void explorepdtest01(int argc, char** argv)
{
  cout << "explore 1st order partial derivative with the 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");

  explorepd1< exp2, lnmin > w(2,lineiter,h0step);

  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;
  }
  cout << left << setw(4) << "k";
  cout << left << setw(15) << "fmin";
  cout << "function counter" << endl;
  cout << left << setw(4) << k;
  cout << left << setw(15) << scientific << w.fmin;
  cout << left << setw(4) << w.fn.counter << endl;
  //cout << scientific << SHOW(w.fmin) << endl;
  //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;
*/

}


void explorepdtest02(int argc, char** argv)
{
  commandline cmd(argc,argv);
  uint k(3);
  cmd.mapvar(k,"k");

  exploreh<probsysequ01,double*,double> g(2,h0step,50000);

  double x0[2] = { 0.5, 0.5 };

  g.reset(x0);

  //g.print(cout);

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

  //cout << scientific << SHOW(g.fmin) << endl;

  //g.print(cout);
  //cout << SHOW(g.fn.counter) << endl;


  cout << left << setw(4) << "k";
  cout << left << setw(15) << "fmin";
  cout << "function counter" << endl;
  cout << left << setw(4) << k;
  cout << left << setw(15) << scientific << g.fmin;
  cout << left << setw(4) << g.fn.counter << endl;
}





