/*-----------------------------------------------*/ int NOMAD::Priority_Eval_Point::compare_hf_values ( const NOMAD::Double & hx1 , const NOMAD::Double & fx1 , const NOMAD::Double & hx2 , const NOMAD::Double & fx2 ) const { if ( fx1.is_defined() && fx2.is_defined() ) { if ( hx1.is_defined() && hx2.is_defined() ) { // x1 is feasible: if ( hx1 <= _h_min ) { // both points are feasible: if ( hx2 <= _h_min ) { if ( fx1 < fx2 ) return 1; if ( fx2 < fx1 ) return -1; } // x1 feasible and x2 infeasible: else return 1; } // x1 is infeasible: else { // x2 is feasible: if ( hx2 <= _h_min ) return -1; // both points are infeasible: if ( ( hx1 < hx2 && fx1 < fx2 ) || ( hx1 == hx2 && fx1 < fx2 ) || ( hx1 < hx2 && fx1 == fx2 ) ) return 1; if ( ( hx2 < hx1 && fx2 < fx1 ) || ( hx2 == hx1 && fx2 < fx1 ) || ( hx2 < hx1 && fx2 == fx1 ) ) return -1; } } // we only have f values: else { if ( fx1 < fx2 ) return 1; if ( fx2 < fx1 ) return -1; } } return 0; }
/*-----------------------------------------------*/ int NOMAD::Priority_Eval_Point::compare_h_values ( const NOMAD::Double & hx1 , const NOMAD::Double & hx2 ) const { if ( hx1.is_defined() && hx2.is_defined() ) { if ( hx1 < hx2 ) return 1; if ( hx2 < hx1 ) return -1; } return 0; }
/*---------------------------------------------------------*/ void NOMAD::TGP_Model::get_Ds2x_points(std::set<int> &pts_indexes) const { pts_indexes.clear(); if (!_Ds2x || _n_XX == 0) return; int i , j , k , m = _bbot.size(); for (i = 0 ; i < m ; ++i) if (_Ds2x[i]) { NOMAD::Double max; k = -1; for (j = 0 ; j < _n_XX ; ++j) if (!max.is_defined() || _Ds2x[i][j] > max) { max = _Ds2x[i][j]; k = j; } if (k >= 0) pts_indexes.insert(k); } }
NOMAD::Double NOMAD::TGP_Model::get_Yw(void) const { NOMAD::Double Yw , tmp; for (int i = 0 ; i < _n0 ; ++i) { tmp = _ub[i]-_lb[i]; if (!Yw.is_defined() || tmp > Yw) Yw = tmp; } return Yw; }
/*-----------------------------------------------------------------------*/ 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::LH_Search::values_for_var_i ( int p , const NOMAD::Double & delta , const NOMAD::Double & delta_max , const NOMAD::bb_input_type & bbit , const NOMAD::Double & lb , const NOMAD::Double & ub , NOMAD::Point & x ) const { // categorical variables have already been treated as fixed variables: if ( bbit == NOMAD::CATEGORICAL ) return; int i; NOMAD::Double v; NOMAD::Random_Pickup rp (p); bool rounding = ( bbit != NOMAD::CONTINUOUS ); bool lb_def = lb.is_defined(); bool ub_def = ub.is_defined(); double w = ( ( lb_def && ub_def ) ? ub.value()-lb.value() : 1.0 ) / p; // main loop: for ( i = 0 ; i < p ; ++i ) { // both bounds exist: if ( lb_def && ub_def ) v = lb + ( i + NOMAD::RNG::rand()/NOMAD::D_INT_MAX ) * w; // one of the bounds does not exist: else { // lb exists, and ub not: mapping [0;1] --> [lb;+INF[ if ( lb_def ) v = lb + 10 * delta_max * sqrt ( - log ( NOMAD::DEFAULT_EPSILON + ( i + NOMAD::RNG::rand()/NOMAD::D_INT_MAX ) * w ) ); // lb does not exist: else { // ub exists, and lb not: mapping [0;1] --> ]-INF;ub] if ( ub_def ) v = ub - delta_max * 10 * sqrt ( -log ( NOMAD::DEFAULT_EPSILON + ( i +NOMAD::RNG::rand()/NOMAD::D_INT_MAX ) * w ) ); // there are no bounds: mapping [0;1] --> ]-INF;+INF[ else v = (NOMAD::RNG::rand()%2 ? -1.0 : 1.0) * delta_max * 10 * sqrt ( - log ( NOMAD::DEFAULT_EPSILON + ( i + NOMAD::RNG::rand()/NOMAD::D_INT_MAX ) * w ) ); } } // rounding: if ( rounding ) v = v.round(); // projection to mesh (with ref=0): v.project_to_mesh ( 0.0 , delta , lb , ub ); // affectation + permutation: x[rp.pickup()] = v; } }
/*--------------------------------------------------*/ bool NOMAD::Eval_Point::check(int m , NOMAD::check_failed_type &cf) const { if (size() <= 0 || !_signature || m != _bb_outputs.size()) { std::string err = "Eval_Point::check() could not procede"; if (!_signature) err += " (no signature)"; else if (m != _bb_outputs.size()) err += " (wrong number of blackbox outputs)"; else err += " (point size <= 0 !)"; throw NOMAD::Exception("Eval_Point.cpp" , __LINE__ , err); } cf = NOMAD::CHECK_OK; const std::vector<NOMAD::bb_input_type> &input_types = _signature->get_input_types(); const NOMAD::Point &lb = _signature->get_lb(); const NOMAD::Point &ub = _signature->get_ub(); const NOMAD::Point &fv = _signature->get_fixed_variables(); int n = size(); NOMAD::bb_input_type iti; for (int i = 0 ; i < n ; ++i) { const NOMAD::Double xi = (*this)[i]; // undefined coordinates ? if (!xi.is_defined()) throw NOMAD::Exception("Eval_Point.cpp" , __LINE__ , "Eval_Point::check() could not procede (undefined coordinates)"); // check the bounds: const NOMAD::Double &lbi = lb[i]; if (lbi.is_defined() && xi < lbi) { cf = NOMAD::LB_FAIL; return false; } const NOMAD::Double &ubi = ub[i]; if (ubi.is_defined() && xi > ubi) { cf = NOMAD::UB_FAIL; return false; } // check the integer/categorical/binary variables: iti = input_types[i]; if (iti == NOMAD::BINARY && !xi.is_binary()) { cf = NOMAD::BIN_FAIL; return false; } if ((iti == NOMAD::INTEGER || iti == NOMAD::CATEGORICAL) && !xi.is_integer()) { cf = (iti == NOMAD::INTEGER) ? NOMAD::INT_FAIL : NOMAD::CAT_FAIL; return false; } // check the fixed-variables: const NOMAD::Double &fvi = fv[i]; if (fvi.is_defined() && fvi != xi) { cf = NOMAD::FIX_VAR_FAIL; return false; } } return true; }
/*------------------------------------------------*/ bool NOMAD::Priority_Eval_Point::dominates ( const NOMAD::Set_Element<NOMAD::Eval_Point> & x ) const { if ( this == &x ) return false; const NOMAD::Eval_Point * x1 = get_element(); const NOMAD::Eval_Point * x2 = x.get_element(); // criterion 0: lexicographic order if (_lexicographic_order) return NOMAD::Point(*x1) < NOMAD::Point(*x2); // criterion 1: user criterion: // ------------ const NOMAD::Double uep1 = x1->get_user_eval_priority(); if ( uep1.is_defined() ) { const NOMAD::Double uep2 = x2->get_user_eval_priority(); if ( uep2.is_defined() ) { if ( uep1 > uep2 ) return true; if ( uep2 > uep1 ) return false; } } // specific Priority_Eval_Point elements of comparison: NOMAD::Double x_f_sgte; NOMAD::Double x_h_sgte; NOMAD::Double x_f_model; NOMAD::Double x_h_model; NOMAD::Double x_angle_success_dir; NOMAD::Double x_angle_simplex_grad; x.get_priority_criteria ( x_f_sgte , x_h_sgte , x_f_model , x_h_model , x_angle_success_dir , x_angle_simplex_grad ); // criterion 2: give priority to already evaluated cache points: // ------------ if ( x1->is_in_cache() && !x2->is_in_cache() ) return true; if ( x2->is_in_cache() && !x1->is_in_cache() ) return false; // criterion 3: give priority to already evaluated points // ------------ that are eval_ok: if ( x1->is_eval_ok() && !x2->is_eval_ok() ) return true; if ( x2->is_eval_ok() && !x1->is_eval_ok() ) return false; // criterion 4: true f and h values: // ----------- int flag = compare_hf_values ( x1->get_h() , x1->get_f() , x2->get_h() , x2->get_f() ); if ( flag ) return ( flag > 0 ); // criterion 5: surrogate f and h values: // ------------ flag = compare_hf_values ( _h_sgte , _f_sgte , x_h_sgte , x_f_sgte ); if ( flag ) return ( flag > 0 ); // criterion 6: model f and h values: // ------------ flag = compare_hf_values ( _h_model , _f_model , x_h_model , x_f_model ); if ( flag ) return ( flag > 0 ); // criterion 7: check the angle with the last successful direction: // ------------ if ( _angle_success_dir.is_defined() && x_angle_success_dir.is_defined() ) { if ( _angle_success_dir < x_angle_success_dir ) return true; if ( x_angle_success_dir < _angle_success_dir ) return false; } // criterion 8: take the point with the best h value: // ------------ flag = compare_h_values ( x1->get_h() , x2->get_h() ); if ( flag ) return ( flag > 0 ); flag = compare_h_values ( _h_sgte , x_h_sgte ); if ( flag ) return ( flag > 0 ); flag = compare_h_values ( _h_model , x_h_model ); if ( flag ) return ( flag > 0 ); // criterion 9: random criterion for randomly generated directions: // ------------- const NOMAD::Double rep1 = x1->get_rand_eval_priority(); if ( rep1.is_defined() ) { const NOMAD::Double rep2 = x2->get_rand_eval_priority(); if ( rep2.is_defined() ) { if ( rep1 < rep2 ) return true; if ( rep2 < rep1 ) return false; } } // criterion 10: compare the tags: // ------------- return x1->get_tag() < x2->get_tag(); }
/*----------------------------------------------------------------*/ void NOMAD::TGP_Model::eval_hf(const NOMAD::Point &bbo , const NOMAD::Double &h_min , NOMAD::hnorm_type h_norm , NOMAD::Double &h , NOMAD::Double &f) const { f.clear(); h = 0.0; int m = bbo.size(); if (m != static_cast<int>(_bbot.size())) throw NOMAD::Exception("TGP_Model.cpp" , __LINE__ , "TGP_Model::eval_hf() called with an invalid bbo argument"); NOMAD::Double bboi; for (int i = 0 ; i < m ; ++i) { bboi = bbo[i]; if (bboi.is_defined()) { if (_bbot[i] == NOMAD::EB || _bbot[i] == NOMAD::PEB_E) { if (bboi > h_min) { h.clear(); return; } } else if ((_bbot[i] == NOMAD::FILTER || _bbot[i] == NOMAD::PB || _bbot[i] == NOMAD::PEB_P)) { if (bboi > h_min) { switch (h_norm) { case NOMAD::L1: h += bboi; break; case NOMAD::L2: h += bboi * bboi; break; case NOMAD::LINF: if (bboi > h) h = bboi; break; } } } else if (_bbot[i] == NOMAD::OBJ) f = bboi; } } if (h_norm == NOMAD::L2) h = h.sqrt(); }
/*-------------------------------------------------------------------*/ bool NOMAD::Evaluator::eval_x ( std::list<NOMAD::Eval_Point *> & list_eval, const NOMAD::Double & h_max , std::list<bool> & list_count_eval) const { std::list<NOMAD::Eval_Point *>::iterator it; std::list<NOMAD::Eval_Point *>::iterator it_begin=list_eval.begin(); std::list<NOMAD::Eval_Point *>::iterator it_end=list_eval.end(); std::list<bool>::iterator it_count=list_count_eval.begin(); if ( list_eval.size() !=list_count_eval.size()) throw NOMAD::Exception ( "Evaluator.cpp" , __LINE__ , "Evaluator: inconsistent size of list" ); if ( _bb_exe.empty()) throw NOMAD::Exception ( "Evaluator.cpp" , __LINE__ , "Evaluator: no BB_EXE is defined (blackbox executable names)" ); bool sgte = ((*it_begin)->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; for (it=it_begin;it!=it_end;++it) { if (!(*it)->is_complete() ) throw NOMAD::Exception ( "Evaluator.cpp" , __LINE__ , "Evaluator: points provided for evaluations are incomplete " ); } // add the tag of the first point oss << "." << (*it_begin)->get_tag(); oss << "." ; 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 open file blackbox input file " + bb_input_file_name; throw NOMAD::Exception ( "Evaluator.cpp" , __LINE__ , err ); } for (it=it_begin;it!=it_end;++it) { // include seed: if ( _p.get_bb_input_include_seed() ) fout << seed << " "; // include tag: if ( _p.get_bb_input_include_tag() ) fout << (*it)->get_tag() << " "; fout.setf ( std::ios::fixed ); fout.precision ( NOMAD::DISPLAY_PRECISION_BB ); (*it)->Point::display ( fout , " " , -1 , -1 ); fout << std::endl; } fout.close(); if ( fout.fail() ) return false; for (it=it_begin;it!=it_end;++it) (*it)->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 blackboxes: // ------------------------------------- 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; // the evaluation: { int signal = system ( cmd.c_str() ); // catch the ctrl-c signal: if ( signal == SIGINT ) raise ( SIGINT ); // other evaluation error: failed = ( signal != 0 ); } // the evaluation failed (we stop the evaluations): if ( failed ) { it_count=list_count_eval.begin(); for (it=it_begin;it!=it_end;++it,++it_count) { (*it)->set_eval_status ( NOMAD::EVAL_FAIL ); (*it_count)=true; // } break; } // reading of the blackbox output file: // ------------------------------------ else { // bb-output file reading: fin.open ( bb_output_file_name.c_str() ); string s; bool is_defined,is_inf; bool list_all_failed_eval=true; bool list_all_interrupt=true; // loop on the points it_count=list_count_eval.begin(); for (it=it_begin;it!=it_end;++it,++it_count) { failed = false; is_defined = true; is_inf = false; // loop on the number of outputs for this blackbox: nbbok = _bb_nbo[k]; ibbo=0; for ( j = 0 ; j < nbbok ; ++j ) { fin >> s; if ( fin.fail() ) { failed = true; break; } toupper(s); if (s.compare("REJECT")==0) { *it_count=false; // Rejected points are not counted (*it)->set_eval_status(NOMAD::EVAL_USER_REJECT); break; } else { d.atof(s); (*it_count)=true; } // if (s.compare("FAIL")==0) { failed = true; break; } if ( !d.is_defined() ) { is_defined = false; break; } if ( d.value() >= NOMAD::INF ) { is_inf = true; break; } (*it)->set_bb_output ( ibbo++ , d ); } // the evaluation failed: if ( failed || !is_defined || is_inf ) { (*it)->set_eval_status ( NOMAD::EVAL_FAIL ); } else list_all_failed_eval=false; // stop the evaluations if h > h_max or if a 'EB' constraint is violated: if ( !( k < _bb_exe.size() - 1 && interrupt_evaluations ( *(*it) , h_max ) && list_all_interrupt )) list_all_interrupt=false; } fin.close(); if (list_all_failed_eval || list_all_interrupt) break; } } // delete the blackbox input and output files: // ------------------------------------------- remove ( bb_input_file_name.c_str () ); remove ( bb_output_file_name.c_str() ); bool at_least_one_eval_ok=false; int index_cnt_eval = _p.get_index_cnt_eval(); // update eval status and check that at least one was ok it_count=list_count_eval.begin(); for (it=it_begin;it!=it_end;++it,++it_count) { if ( (*it)->get_eval_status() == NOMAD::EVAL_IN_PROGRESS ) (*it)->set_eval_status ( NOMAD::EVAL_OK ); if (!at_least_one_eval_ok && (*it)->is_eval_ok()) at_least_one_eval_ok=true; // count_eval from bb_outputs: // -------------------------- if ( index_cnt_eval >= 0 && (*it)->get_bb_outputs()[index_cnt_eval]==0) *it_count=false; } return at_least_one_eval_ok; }
/*-------------------------------------------------------------------*/ 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(); }