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

#include <commandline.h>
#include <minexpdim.h>
#include <minexpdimtest.h>
#include <minpatternsearch.h>
#include <minpatternsearchorder2.h>
#include <print.h>
#include <prob_func.h>


void minexpdimtest::test01()
{
  minexpdim<double> mn(* new prob_f001,0.3);
  //minexpdim<double> mn(* new prob_f002,0.3);
  mn.fn->xi[0]=1;
  mn.fn->xi[1]=1;
  double error = 1e-4;
  mn.reset();
  cout << printvecfunc(mn.xi,3) << endl;
  //for ( ; !mn && (abs(mn.hi[0])+abs(mn.hi[1])>error); ++mn );
  for ( ; !mn && (mn.himax()>error); ++mn );

  cout << printvecfunc(mn.xi,3) << endl;

  cout << SHOW(mn.fn->counter) << endl;

  cout << "exploratory with magnitude increase for successive search." <<
endl;
  mn.fn->counter=0;
  mn.fn->xi[0]=1;
  mn.fn->xi[1]=1;
  mn.magnitude_increase=true;
  mn.reset();
  for ( ; !mn && (mn.himax()>error); ++mn );
  cout << printvecfunc(mn.xi,3) << endl;
  cout << SHOW(mn.fn->counter) << endl;
}


void minexpdimtest::test02()
{
  cout << "Looking at moveOrder1 functions." << endl;

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

//  funcstate<double> * f01 = ;
  minexpdim<double> mn(* new prob_f001,0.3);
  copy(x0,x0+2,mn.fn->xi);
  mn.reset();

  uint imax=4;
  cout << "mn" << endl;
  for (uint i=0; i<imax; ++i)
  {
    cout << printvecfunc(mn.xi,3) << " "; 
    mn.moveOrder1();
    cout << mn.fn->counter << endl;
  }

  //funcstate<double> * f02 = new prob_f001;
  minexpdim<double> mn2(* new prob_f001,0.3);
  copy(x0,x0+2,mn2.fn->xi);
  mn2.reset();

  cout << "mn2" << endl;
  for (uint i=0; i<imax; ++i)
  {
    cout << printvecfunc(mn2.xi,3) << " "; 
    mn2.moveOrder1();
    cout << mn2.fn->counter << endl;
  }
}


void minexpdimtest::test03(int argc, char** argv)
{
  cout << "Using ++ with first order approximator explicitly - minexpdimN class" << endl;
//  cout << "Terminating with himax(), an inner product error measure" << endl;

  commandline cmd(argc,argv);

  minexpdimN<double> mn(*new prob_f001,0.3);
  double x0[2] = {1.0,1.0};
  double error = 1e-4;
  cmd.mapvar(error,"error");
  cout << SHOW(error) << endl;

  copy(x0,x0+2,mn.fn->xi);
  mn.reset();
  cout << printvecfunc(mn.xi,3) << endl;

  bool hfixed=false;
  cmd.mapvar(hfixed,"hfixed");

  uint i=0;
  uint imax=80;
  do
  {
    ++mn;
    cout << setw(3) << i << " " << printvecfunc(mn.xi,3);
    cout << " " << mn.fn->counter << " " << mn.himax() << endl;
    ++i;

    if (hfixed==true)
      mn.hiset(mn.himaxtol());

  } while ((mn.xi[2] > error)&&(i<imax));

}


void minexpdimtest::test04(int argc, char** argv)
{
  commandline cmd(argc,argv);

  double x0[2] = {1.0,1.0};
  minpatternsearch<double> mn(*new prob_f001,0.3);
  copy(x0,x0+2,mn.fn->xi);
  //cout << "mn  " << printvecfunc(mn.xi,3) << endl; 

  mn.reset();

  bool hfixed=false;
  cmd.mapvar(hfixed,"hfixed");
  bool summary=false;
  cmd.mapvar(summary,"summary");

  double error = 1e-4;

  cmd.mapvar(error,"error");
  if (summary==false)
  {
    cout << "xk1 " << printvecfunc(mn.fh[1],3) << endl;
    cout << "xk0 " << printvecfunc(mn.fh[0],3) << endl;
    cout << "iter x0 x1 f(X) fn's max(hi)" << endl;
  }
  //for (uint i=0; mn.xi[2] > error; ++i, ++mn)
  uint i=0;
  uintc imax=20;
  bool cond(true);
  do  
  {
    ++mn;
    cond = ((mn.xi[2] > error)&&(i<imax));
    if (summary==false || cond==false)
    {
      cout << setw(3) << i << " " << printvecfunc(mn.xi,3);
      cout << " " << mn.fn->counter << " " << mn.himax() << endl;
    }
    ++i;

    if (hfixed==true)
      mn.hiset(mn.himaxtol());

  } while (cond);

}

void minexpdimtest::test05(int argc, char** argv)
{
  commandline cmd(argc,argv);

  double x0[2] = {1.0,1.0};
  minpatternsearchorder2<double> mn(*new prob_f001,0.3);
  copy(x0,x0+2,mn.fn->xi);

  mn.reset();

  bool hfixed=false;
  cmd.mapvar(hfixed,"hfixed");
  bool summary=false;
  cmd.mapvar(summary,"summary");

  double error = 1e-4;

  cmd.mapvar(error,"error");
  if (summary==false)
  {
    cout << "xk2 " << printvecfunc(mn.fh[2],3) << endl;
    cout << "xk1 " << printvecfunc(mn.fh[1],3) << endl;
    cout << "xk0 " << printvecfunc(mn.fh[0],3) << endl;
    cout << "iter x0 x1 f(X) fn's max(hi)" << endl;
  }
  uint i=0;
  uintc imax=20;
  bool cond(true);
  do  
  {
    ++mn;
    cond = ((mn.xi[2] > error)&&(i<imax));
    if (summary==false || cond==false)
    {
      cout << setw(3) << i << " " << printvecfunc(mn.xi,3);
      cout << " " << mn.fn->counter << " " << mn.himax() << endl;
    }
    ++i;

    if (hfixed==true)
      mn.hiset(mn.himaxtol());

  } while (cond);

}




