/*------------------------------------------------------------------*/
void NOMAD::Phase_One_Evaluator::compute_f(NOMAD::Eval_Point &x) const
{
    if (x.get_bb_outputs().size() != _p.get_bb_nb_outputs())
    {
        std::ostringstream err;
        err << "Phase_One_Evaluator::compute_f(x): "
            << "x has a wrong number of blackbox outputs ("
            << x.get_bb_outputs().size() <<  " != " << _p.get_bb_nb_outputs() << ")";
        throw NOMAD::Exception("Phase_One_Evaluator.cpp" , __LINE__ , err.str());
    }

    // objective value for MADS phase 1: the squared sum of all EB constraint violations
    // (each EB constraint has been previously transformed into OBJ values):
    const std::list<int>                &index_obj = _p.get_index_obj();
    const std::list<int>::const_iterator end       = index_obj.end();
    const NOMAD::Point                  &bbo       = x.get_bb_outputs();
    NOMAD::Double                        h_min     = _p.get_h_min();
    NOMAD::Double                        sum       = 0.0;
    NOMAD::Double                        v;

    for (std::list<int>::const_iterator it = index_obj.begin() ; it != end ; ++it)
    {
        v = bbo[*it];
        if (v > h_min)
            sum += v.pow2();
    }

    x.set_f(sum);
}
 /*--------------------------------------------------------*/
 void NOMAD::Evaluator::compute_f ( NOMAD::Eval_Point & x ) const
 {
     if ( x.get_bb_outputs().size() != _p.get_bb_nb_outputs() ) {
         std::ostringstream err;
         err << "Evaluator::compute_f(x): x has a wrong number of blackbox outputs ("
         << x.get_bb_outputs().size() << " != "
         << _p.get_bb_nb_outputs() << ")";
         throw NOMAD::Exception ( "Evaluator.cpp" , __LINE__ , err.str() );
     }
     
     x.set_f ( x.get_bb_outputs()[*(_p.get_index_obj().begin())] );
 }
/*-------------------------------------------------------------*/
void NOMAD::Multi_Obj_Evaluator::compute_f ( NOMAD::Eval_Point & x ) const
{
  if ( _i1 < 0 || _i2 < 0 )
    throw NOMAD::Exception ( "Multi_Obj_Evaluator.cpp" , __LINE__ ,
	  "Multi_Obj_Evaluator::compute_f(): no objective indexes defined" );

  int obj_index [2];
  obj_index[0] = _i1;
  obj_index[1] = _i2;

  const NOMAD::Point & bbo = x.get_bb_outputs();

  // a reference is available:
  if ( _ref ) 
  {
      
	  NOMAD::multi_formulation_type mft = _p.get_multi_formulation();
	  
	  if ( mft == NOMAD::UNDEFINED_FORMULATION )
		  throw NOMAD::Exception ( "Multi_Obj_Evaluator.cpp" , __LINE__ ,
								  "Multi_Obj_Evaluator::compute_f(): no formulation type is defined" );
	  
	  // normalized formulation:
	  if ( mft == NOMAD::NORMALIZED || mft == NOMAD::DIST_LINF ) {
		  
		  // f1 - r1:
		  NOMAD::Double d = bbo[obj_index[0]] - (*_ref)[0];
		  
		  // f2 - r2:
		  NOMAD::Double f2mr2 = bbo[obj_index[1]] - (*_ref)[1];
		  
		  // we take the max:
		  if ( f2mr2 > d )
			  d = f2mr2;
		  
		  x.set_f ( d );
	  }
	  
	  // product formulation:
	  else if ( mft == NOMAD::PRODUCT ) {
		  
		  NOMAD::Double prod = 1.0 , ri , fi;
		  
		  for ( int i = 0 ; i < 2 ; ++i ) {
			  
			  ri = (*_ref)[i];
			  fi = bbo[obj_index[i]];
			  
			  if ( fi > ri ) {
				  prod = 0.0;
				  break;
			  }
			  prod = prod * (ri-fi).pow2();
		  }
		  
		  x.set_f ( -prod );
	  }
	  
	  // distance formulation:
	  else {
		  
		  NOMAD::Double d;  
		  NOMAD::Double r1mf1 = (*_ref)[0] - bbo[obj_index[0]];
		  NOMAD::Double r2mf2 = (*_ref)[1] - bbo[obj_index[1]];
		  
		  if ( r1mf1 >= 0.0 && r2mf2 >= 0.0 ) {
			  d = r1mf1.pow2();
			  NOMAD::Double tmp = r2mf2.pow2();
			  if ( tmp < d )
				  d = tmp;
			  d = -d;
		  }
		  else if ( r1mf1 <= 0.0 && r2mf2 <= 0.0 ) {
			  
			  // with L2 norm:
			  if ( mft == NOMAD::DIST_L2 )
				  d = r1mf1.pow2() + r2mf2.pow2();
			  
			  // with L1 norm:
			  else
				  d = (r1mf1.abs() + r2mf2.abs()).pow2();
			  
			  // Linf norm: treated as NORMALIZED
		  }
		  else if ( r1mf1 > 0.0 )
			  d = r2mf2.pow2();
		  else
			  d = r1mf1.pow2();
		  
		  x.set_f ( d );
	  }
  }
    
  // no reference is available (use weights):
  else
    x.set_f ( _w1 * bbo[obj_index[0]] + _w2 * bbo[obj_index[1]] );
}