#ifndef EXPLORERAND_H
#define EXPLORERAND_H

/*!
  \brief random search in the interval (xi[k]-h[k],xi[k]+hi[k]).

  A search is made in both directions about xi[k].

  EXP is expected to support exploreh or one of its derivations. 

  This method became comparable to the others with a higher
  number of iterations.
*/
template < typename EXP, typename RND >
class explorerand : public EXP
{
public:

  RND rnd;

  typedef typename typeop<EXP>::Targ::FNtype FN;
  typedef typename typeop<EXP>::Tbare::Ttype T;

  /** Construct a N dimensional direct search object on FN */
  explorerand
  (
    uintc N_, 
    T const h0step=20.0, 
    uintc indexmax_=500
  )
    : EXP(N_,h0step,indexmax_) {}

  /** FN can be a reference. */
  explorerand
  (
    FN fn_,
    uintc N_, 
    T const h0step=20.0, 
    uintc indexmax_=500
  )
    : EXP(fn_,N_,h0step,indexmax_) {}

  /** Iterate towards the minimum. */
  void operator ++ ();

};


template < typename EXP, typename RND >
void explorerand<EXP,RND>::operator ++ ()
{
  EXP::hasStateChanged=false;

  if (!EXP::valid)
    return;

  if (EXP::index>EXP::indexmax)
  {
    EXP::valid=false;
#ifndef NDEBUG
cout << "error: indexmax reached  " << SHOW(EXP::index) << endl;
#endif
    return;
  }

  ++EXP::index;

  static T tmp;

  for (uint i=0; i<EXP::N; ++i)
  {
    tmp = EXP::xi[i];

bool flag=false;
for (uint k=0; k<1; ++k)
{
if (flag==false)
{
    EXP::xi[i] += EXP::hi[i]*rnd();
    if (EXP::evaluate())
    {
      flag=true;
//      cout << "***" << endl;
      continue;
    }

    EXP::xi[i] = tmp - EXP::hi[i]*rnd();
    if (EXP::evaluate())
    {
      flag=true;
//      cout << "###" << endl;
      continue;
    }
}
}

if (flag==true)
  continue;


    EXP::xi[i] = tmp;

/*

    EXP::xi[i] += EXP::hi[i];
    if (EXP::evaluate())
      continue;

    EXP::hi[i] *= -1;
    EXP::xi[i] += EXP::hi[i];
    EXP::xi[i] += EXP::hi[i];
    if (EXP::evaluate())
      continue;

    tmp = EXP::xi[i];
    
    // Try find a random solution with the interval. 
    EXP::xi[i] += EXP::hi[i]*2.0*rnd();
    if (EXP::evaluate())
    {
cout << "success" << endl;
      continue;
    }

cout << "fuck" << endl;
 
    EXP::xi[i] = tmp; 

    EXP::xi[i] -= EXP::hi[i];
*/

    EXP::hi[i] *= 0.61803398875; 
  }
}



#endif



