/*------------------------------------------------------------------*/
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);
}
Beispiel #2
0
/*--------------------------------------------------------*/
void NOMAD::Evaluator::compute_h ( NOMAD::Eval_Point & x ) const
{
  if ( x.get_bb_outputs().size() != _p.get_bb_nb_outputs() ) {
    std::ostringstream err;
    err << "Evaluator::compute_h(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() );
  }

  int                                        nbo  = _p.get_bb_nb_outputs();
  const std::vector<NOMAD::bb_output_type> & bbot = _p.get_bb_output_type();
  const NOMAD::Point                       & bbo  = x.get_bb_outputs();
  NOMAD::Double                              h    = 0.0 , bboi;

  x.set_EB_ok ( true );

  for ( int i = 0 ; i < nbo ; ++i ) {

    bboi = bbo[i];

    if ( bboi.is_defined()                                  &&
	 (bbot[i] == NOMAD::EB || bbot[i] == NOMAD::PEB_E ) &&
	 bboi > _p.get_h_min() ) {
      h.clear();
      x.set_h     ( h     );
      x.set_EB_ok ( false );
      return;
    }
    
    if ( bboi.is_defined() &&
	 ( bbot[i] == NOMAD::FILTER ||
	   bbot[i] == NOMAD::PB     ||
	   bbot[i] == NOMAD::PEB_P     ) ) {
      if ( bboi > _p.get_h_min() ) {
	switch ( _p.get_h_norm() ) {
	case NOMAD::L1:
	  h += bboi;
	  break;
	case NOMAD::L2:
	  h += bboi * bboi;
	  break;
	case NOMAD::LINF:
	  if ( bboi > h )
	    h = bboi;
	  break;
	}
      }
    }
  }

  if ( _p.get_h_norm() == NOMAD::L2 )
    h = h.sqrt();

  x.set_h ( h );
}
 /*--------------------------------------------------------*/
 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())] );
 }
 /*-----------------------------------------------------------------------*/
 bool NOMAD::Evaluator::interrupt_evaluations ( const NOMAD::Eval_Point & x     ,
                                               const NOMAD::Double     & h_max   ) const
 {
     int                                        nbo     = _p.get_bb_nb_outputs();
     const NOMAD::Point                       & bbo     = x.get_bb_outputs();
     const std::vector<NOMAD::bb_output_type> & bbot    = _p.get_bb_output_type();
     NOMAD::Double                              h       = 0.0;
     bool                                       check_h = h_max.is_defined();
     
     for ( int i = 0 ; i < nbo ; ++i ) {
         
         if ( bbo[i].is_defined()                                 &&
             ( bbot[i] == NOMAD::EB || bbot[i] == NOMAD::PEB_E ) &&
             bbo[i] > _p.get_h_min() )
             return true;
         
         if ( check_h && bbo[i].is_defined() &&
             (bbot[i] == NOMAD::FILTER ||
              bbot[i] == NOMAD::PB     ||
              bbot[i] == NOMAD::PEB_P     ) ) {
                 
                 if ( bbo[i] > _p.get_h_min() ) {
                     switch ( _p.get_h_norm() ) {
                         case NOMAD::L1:
                             h += bbo[i];
                             break;
                         case NOMAD::L2:
                             h += bbo[i].pow2();
                             break;
                         case NOMAD::LINF:
                             if ( bbo[i] > h )
                                 h = bbo[i];
                             break;
                     }
                     
                     if ( _p.get_h_norm() == NOMAD::L2 ) {
                         if ( h > h_max.pow2() )
                             return true;
                     }
                     else if ( h > h_max )
                         return true;
                 }
             }
     }
     return false;
 }
/*-----------------------------------------------------------------*/
void NOMAD::Cache::update ( NOMAD::Eval_Point       & cache_x ,
                           const NOMAD::Eval_Point & x         ) const
{
    const NOMAD::Point & bbo_x = x.get_bb_outputs();
    
    if ( &cache_x == &x         ||
        !x.is_eval_ok()        ||
        !cache_x.is_in_cache() ||
        bbo_x.empty()          ||
        cache_x != x              )
        return;
    
    // check the eval types:
    if ( x.get_eval_type      () != _eval_type ||
        cache_x.get_eval_type() != _eval_type    )
        throw NOMAD::Cache::Cache_Error ( "Cache.cpp" , __LINE__ ,
                                         "NOMAD::Cache:update(): problem with the eval. types" );
    
    const NOMAD::Point & bbo_cache_x = cache_x.get_bb_outputs();
    int                  m           = bbo_cache_x.size();
    
    _sizeof -= cache_x.size_of();
    
    // if the current point could not evaluate and x did,
    // or if the number of bb outputs is different, we set cache_x = x:
    if ( !cache_x.is_eval_ok() || m != bbo_x.size() )
    {
        cache_x.set_eval_status ( NOMAD::EVAL_OK     );
        cache_x.set_bb_output   ( bbo_x              );
        cache_x.set_signature   ( x.get_signature () );
        cache_x.set_direction   ( x.get_direction () );
        
        _sizeof += cache_x.size_of();
        return;
    }
    
    // we complete _bb_outputs:
    int c1 = 0;
    int c2 = 0;
    
    for ( int i = 0 ; i < m ; ++i ) {
        
        if ( bbo_cache_x[i].is_defined() )
            ++c1;
        
        if ( bbo_x[i].is_defined() )
            ++c2;
        
        if ( !bbo_cache_x[i].is_defined() && bbo_x[i].is_defined() )
            cache_x.set_bb_output ( i , bbo_x[i] );
    }
    
    // the two points are 'eval_ok' and have comparable outputs:
    // we select the best as the one with the more defined bb_outputs:
    if ( c2 > c1 ) {
        cache_x.set_signature  ( x.get_signature () );
        cache_x.set_direction  ( x.get_direction () );
        
    }
    
    _sizeof += cache_x.size_of();
}
Beispiel #6
0
/*---------------------------------------------------------------------*/
NOMAD::Cache_File_Point::Cache_File_Point(const NOMAD::Eval_Point &x)
    : _n(x.size()) ,
      _m(0) ,
      _m_def(0) ,
      _coords(NULL) ,
      _bbo_def(NULL) ,
      _bbo_index(NULL)
{
    int i;

    // eval_status:
    switch (x.get_eval_status())
    {
        case NOMAD::EVAL_FAIL:
            _eval_status = 0;
            break;
        case NOMAD::EVAL_OK:
            _eval_status = 1;
            break;
        case NOMAD::EVAL_IN_PROGRESS:
            _eval_status = 2;
            break;
        case NOMAD::UNDEFINED_STATUS:
            _eval_status = 3;
            break;
        case NOMAD::EVAL_USER_REJECT:
            _eval_status = 3;
            break;
    }

    // inputs:
    if (_n > 0)
    {
        _coords = new double [_n];
        for (i = 0 ; i < _n ; ++i)
            _coords[i] = x[i].value();
    }
    else
        _n = 0;

    // outputs:
    const NOMAD::Point &bbo = x.get_bb_outputs();
    _m = bbo.size();
    if (_m > 0)
    {

        std::vector<double> vd;
        std::vector<int>    vi;

        for (i = 0 ; i < _m ; ++i)
            if (bbo[i].is_defined())
            {
                vd.push_back(bbo[i].value());
                vi.push_back(i);
            }

        _m_def = static_cast<int>(vd.size());
        if (_m_def > 0)
        {
            _bbo_def   = new double [_m_def];
            _bbo_index = new int    [_m_def];
            for (i = 0 ; i < _m_def ; ++i)
            {
                _bbo_def  [i] = vd[i];
                _bbo_index[i] = vi[i];
            }
        }
    }
    else
        _m = 0;

#ifdef MEMORY_DEBUG
    ++NOMAD::Cache_File_Point::_cardinality;
    if (NOMAD::Cache_File_Point::_cardinality >
        NOMAD::Cache_File_Point::_max_cardinality)
        ++NOMAD::Cache_File_Point::_max_cardinality;
#endif
}
/*--------------------------------------------------------*/
void NOMAD::Barrier::check_PEB_constraints ( const NOMAD::Eval_Point & x , bool display )
{
    const NOMAD::Double                      & h_min = _p.get_h_min();
    const std::vector<NOMAD::bb_output_type> & bbot  = _p.get_bb_output_type();
    const NOMAD::Point                       & bbo   = x.get_bb_outputs();
    int                                        nb    = static_cast<int>(bbot.size());
    std::list<int>                             ks;
    
    for ( int k = 0 ; k < nb ; ++k )
    {
        if ( bbot[k] == NOMAD::PEB_P && bbo[k] <= h_min )
        {
            if ( display )
                _p.out() << std::endl
                << "change status of blackbox output " << k
                << " from progressive barrier constraint to extreme barrier constraint"
                << std::endl;
            ++_peb_changes;
            _p.change_PEB_constraint_status (k);
            ks.push_back(k);
        }
    }
    
    // at least one constraint changed status, so we have to update the filter
    // and remove all points that have their h value changed to infinity
    // (it can add new dominant points from the list _peb_lop):
    if ( !ks.empty() )
    {
        
        std::list<int>::const_iterator it_k , end_k = ks.end() , begin_k = ks.begin();
        
        // we inspect the filter points if some have to be removed; if so,
        // all filter candidates (stored in _peb_lop) will be re-inserted
        // into the filter:
        bool reset_filter = false;
        std::set<NOMAD::Filter_Point>::const_iterator end = _filter.end() , it;
        
        for ( it = _filter.begin() ; it != end ; ++it )
        {
            
            const NOMAD::Point & bbo_cur = it->get_point()->get_bb_outputs();
            for ( it_k = begin_k ; it_k != end_k ; ++it_k )
                if ( bbo_cur[*it_k] > h_min )
                {
                    reset_filter = true;
                    break;
                }
            if ( reset_filter )
                break;
        }
        
        if ( reset_filter )
        {
            
            if ( display )
                _p.out() << std::endl << "PEB change of status: filter reset" << std::endl;
            
            ++_peb_filter_reset;
            
            _filter.clear();
            bool insert;
            
            std::list<const NOMAD::Eval_Point *>::const_iterator end2 = _peb_lop.end  ();
            std::list<const NOMAD::Eval_Point *>::iterator       it2  = _peb_lop.begin();
            
            while ( it2 != end2 )
            {
                
                insert = true;
                const NOMAD::Point & bbo_cur = (*it2)->get_bb_outputs();
                
                for ( it_k = begin_k ; it_k != end_k ; ++it_k )
                    if ( bbo_cur[*it_k] > h_min )
                    {
                        insert = false;
                        break;
                    }
                
                // if insert==true: this point is potentially a new filter point:
                if ( insert )
                {
                    filter_insertion ( **it2 , insert );
                    ++it2;
                }
                
                // if insert==false: it means that the current filter point
                // has to be removed from filter and from _peb_lop, and
                // in addition, its h is put to INF:
                else
                {
                    
                    NOMAD::Cache::get_modifiable_point ( **it2 ).set_h ( NOMAD::Double() );
                    _peb_lop.erase(it2++);
                }
            }
        }
    }
}
    /*-------------------------------------------------------------------*/
    bool NOMAD::Evaluator::eval_x ( NOMAD::Eval_Point	& x          ,
                                   const NOMAD::Double	& h_max      ,
                                   bool					& count_eval   ) const
    {
        count_eval = false;
        
        if ( _bb_exe.empty() || !x.is_complete() )
            throw NOMAD::Exception ( "Evaluator.cpp" , __LINE__ ,
                                    "Evaluator: no BB_EXE is defined (blackbox executable names)" );
        
        bool sgte = x.get_eval_type() == NOMAD::SGTE;
        if ( sgte && _sgte_exe.empty() )
            throw NOMAD::Exception ( "Evaluator.cpp" , __LINE__ ,
                                    "Evaluator: no SGTE_EXE is defined (surrogate executable names)" );
        
        int         pid     = NOMAD::get_pid();
        int         seed    = _p.get_seed();
        std::string tmp_dir = _p.get_tmp_dir();
        
        std::ostringstream oss;
        oss << "." << seed;
        if ( pid != seed )
            oss << "." << pid;
        oss << "." << x.get_tag() << ".";
        const std::string & sint = oss.str();
        
        // for the parallel version: no need to include the process rank in the names
        // as the point tags are unique for all the processes: each process creates
        // its own points and uses Eval_Point::set_tag()
        
        // blackbox input file writing:
        // ----------------------------
        std::string bb_input_file_name =
        tmp_dir + NOMAD::BLACKBOX_INPUT_FILE_PREFIX
        + sint + NOMAD::BLACKBOX_INPUT_FILE_EXT;
        
        std::string bb_output_file_name =
        tmp_dir + NOMAD::BLACKBOX_OUTPUT_FILE_PREFIX
        + sint + NOMAD::BLACKBOX_OUTPUT_FILE_EXT;
        
        std::ofstream fout ( bb_input_file_name.c_str() );
        if ( fout.fail() )
        {
            std::string err = "could not create file blackbox input file " + bb_input_file_name + ". \n \n #### Please check that write permission are granted for the working directory. #### ";
            throw NOMAD::Exception ( "Evaluator.cpp" , __LINE__ , err );
       }
        
        // include seed:
        if ( _p.get_bb_input_include_seed() )
            fout << seed << " ";
        
        // include tag:
        if ( _p.get_bb_input_include_tag() )
            fout << x.get_tag() << " ";
        
        fout.setf ( std::ios::fixed );
        fout.precision ( NOMAD::DISPLAY_PRECISION_BB );
        x.Point::display ( fout , " " , -1 , -1 );
        fout << std::endl;
        
        fout.close();
        
        if ( fout.fail() )
            return false;
        
        x.set_eval_status ( NOMAD::EVAL_IN_PROGRESS );
        
        std::string   cmd , bb_exe;
        std::ifstream fin;
        bool          failed;
        NOMAD::Double d;
        int           j , nbbok;
        int           ibbo = 0;
        
        // system call to evaluate the blackbox:
        // -------------------------------------
        size_t bn = _bb_exe.size();
        for ( size_t k = 0 ; k < bn ; ++k )
        {
            
            // executable name:
            bb_exe = ( sgte ) ? _sgte_exe[k] : _bb_exe[k];
            
            // system command:
            cmd = bb_exe + " " + bb_input_file_name;
            
            // redirection ? if no, the blackbox has to create
            // the output file 'bb_output_file_name':
            if ( _p.get_bb_redirection() )
                cmd += " > " + bb_output_file_name;
            
#ifdef DEBUG
#ifdef USE_MPI
            int rank;
            MPI_Comm_rank ( MPI_COMM_WORLD, &rank);
            _p.out() << "command(rank=" << rank
            << ") = \'" << cmd << "\'" << std::endl;
#else
            _p.out() << "command=\'" << cmd << "\'" << std::endl;
#endif
#endif
            
            // the evaluation:
            {
                int signal = system ( cmd.c_str() );
                
                // catch the ctrl-c signal:
                if ( signal == SIGINT )
                    raise ( SIGINT );
                
                // other evaluation error:
                failed = ( signal != 0 );
                count_eval = true;
            }
            
            // the evaluation failed (we stop the evaluations):
            if ( failed )
            {
                x.set_eval_status ( NOMAD::EVAL_FAIL );
                break;
            }
            
            // reading of the blackbox output file:
            // ------------------------------------
            else
            {
                
                // bb-output file reading:
                fin.open ( bb_output_file_name.c_str() );
                
                failed          = false;
                bool is_defined = true;
                bool is_inf     = false;
                
                // loop on the number of outputs for this blackbox:
                nbbok = _bb_nbo[k];
                for ( j = 0 ; j < nbbok ; ++j )
                {
                    
                    fin >> d;
                    
                    if ( !d.is_defined() )
                    {
                        is_defined = false;
                        break;
                    }
                    
                    if ( fin.fail() )
                    {
                        failed = true;
                        break;
                    }
                    
                    if ( d.value() >= NOMAD::INF )
                    {
                        is_inf = true;
                        break;
                    }
                    
                    x.set_bb_output ( ibbo++ , d );
                }
                
                fin.close();
                
                // the evaluation failed:
                if ( failed || !is_defined || is_inf )
                {
                    x.set_eval_status ( NOMAD::EVAL_FAIL );
                    break;
                }
                
                // stop the evaluations if h > h_max or if a 'EB' constraint is violated:
                if ( k < _bb_exe.size() - 1 && interrupt_evaluations ( x , h_max ) )
                    break;
            }
        }
        
        if ( x.get_eval_status() == NOMAD::EVAL_IN_PROGRESS )
            x.set_eval_status ( NOMAD::EVAL_OK );
        
        // delete the blackbox input and output files:
        // -------------------------------------------
        remove ( bb_input_file_name.c_str () );
        remove ( bb_output_file_name.c_str() );
        
        // check the CNT_EVAL output:
        // --------------------------
        int index_cnt_eval = _p.get_index_cnt_eval();
        if ( index_cnt_eval >= 0 && x.get_bb_outputs()[index_cnt_eval] == 0.0 )
            count_eval = false;
        
        return x.is_eval_ok();
    }
/*-------------------------------------------------------------*/
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]] );
}