#ifndef LINEPATHD1_H
#define LINEPATHD1_H

//#include <cassert>
//#include <iostream>

//using namespace std;

#include <typeop.h>

/*!
\brief  This is a 1D line in N dimensions.

  The function has been templated as FN.
  The function state has been templated as XI.
  The initial position and direction templated with X type.

  While XI and X are both N dimensional vectors with elements of
  the same type they are different types to support complex functions fn.
  For most applications this generality will not be needed.
*/
template< typename FN, typename XI, typename X, typename T >
class linepath_d1
{
public:

  /** Dimension. */
  uintc dim;

  /** The function being minimized. */
  typename typeop<FN>::Tref fn;
  /** The function state. */
  XI xi;
  /** Line constant. */
  X x0;
  /** Direction. */
  X di;

  linepath_d1
  (
    uintc dim_, 
    typename typeop<FN>::Tref fn_, 
    XI xi_, 
    X x0_, 
    X di_ 
  );

  /** Set xi by t. */
  void eval(T const t)
  {
    for (uint i=0; i<dim; ++i)
      xi[i] = x0[i]+di[i]*t;
//cout << "***";
//cout << printvecfunc(xi,dim) << endl;
  }
  /** Evaluate the function on the line at t. */
  void eval(T& fval, T const t)
    { eval(t); fn(fval); }
  /** Evaluate the function. */
  //void fneval(T& fval)
  //  { fn(fval); }

  /** Look at the current state. */
  ostream & print(ostream & os) const;

};


//-----------------------------------------------
//  Implementation


template< typename FN, typename XI, typename X, typename T >
ostream & linepath_d1<FN,XI,X,T>::print(ostream & os) const
{
  os << "dim=" << dim << endl;
  os << "xi[]=" << printvecfunc(xi,dim) << endl;
  os << "x0[]=" << printvecfunc(x0,dim) << endl;
  os << "di[]=" << printvecfunc(di,dim) << endl;

  return os;
}

template< typename FN, typename XI, typename X, typename T >
linepath_d1<FN,XI,X,T>::linepath_d1
(
  uintc dim_, 
  typename typeop<FN>::Tref fn_, 
  XI xi_, 
  X x0_, 
  X di_ 
)
  : dim(dim_), fn(fn_), xi(xi_), x0(x0_), di(di_)
{
}






#endif



