//----------------------------------------------------------------------------------------------- // evaluates the model //----------------------------------------------------------------------------------------------- bool LshNomadEvaluator::eval_x(NOMAD::Eval_Point &x, const NOMAD::Double &h_max, bool &count_eval) const { // generating a case from the evaluation point Case *c = generateCase(x); CaseQueue *cq = new CaseQueue(); cq->push_back(c); // sending the case off for evaluation p_optimizer->sendCasesToOptimizer(cq); ///p_optimizer->runCase(c); // extracting the objective x.set_bb_output(0, -c->objectiveValue()); // extracting the constraint values // the constraints in NOMAD must be on the form: c <= 0 for(int i = 0; i < c->numberOfConstraints(); ++i) { double val_input; double val = c->constraintValue(i); double max = p_optimizer->runner()->model()->constraints().at(i)->max(); double min = p_optimizer->runner()->model()->constraints().at(i)->min(); if(val > max) val_input = val - max; else if(val < min) val_input = min - val; else { double u_slack = max - val; double l_slack = val - min; val_input = (u_slack > l_slack) ? -u_slack : -l_slack; } x.set_bb_output(i+1, val_input); } // deleting the case from the heap delete c; delete cq; return true; }
bool eval_x ( NOMAD::Eval_Point & x , const NOMAD::Double & h_max , bool & count_eval ) const { R_CheckUserInterrupt(); double *x0; int n = x.get_n(); int m = x.get_m(); x0 = (double *)malloc(sizeof(double)*n); for(int i=0;i<n;i++) { x0[i]=x[i].value(); } double *ret_value = eval_f(m, n, x0); for(int i=0;i<m;i++) x.set_bb_output ( i , ret_value[i] ); // objective value count_eval = true; // count a black-box evaluation free(x0); free(ret_value); return true; // the evaluation succeeded }
bool CMADSEvaluator::eval_x(NOMAD::Eval_Point &_x, const NOMAD::Double &_h_max, bool &_count_eval) const { int i,M=pOP->constraintsSize(); NOMAD::Point y(M+2); ArrayXd op,ep; op=CMADS::NOMADPoint2ArrayXd(_x); y[1]=(pOP->evaluate(op,ep))?0.:1.; y[0]=(pOP->isMinimization())?ep(0):-ep(0); for ( i=2; i<M+2; i++ ) { y[i]=1.-ep(i-1); } _x.set_bb_output(y); bool tohist=true; for ( i=1; tohist && i<M+2; i++ ) { if ( y[i]>0. ) tohist=false; } if ( tohist ) { pOP->writeHistory(op,ep(0)); } _count_eval=true; return true; }
//Function + Constraint Evaluation bool eval_x(NOMAD::Eval_Point &x, const NOMAD::Double &h_max, bool &count_eval) { char errstr[1024]; bool stop = false; int i, j, n = x.size(), status; double *xm, *fvals; mxLogical *sur; count_eval = true; //mexErrMsgTxt will kill MEX //Check for Ctrl-C if (utIsInterruptPending()) { utSetInterruptPending(false); /* clear Ctrl-C status */ mexPrintf("\nCtrl-C Detected. Exiting NOMAD...\n\n"); count_eval = false; raise(SIGINT); return false; } //Blackbox / Objective Evaluation fun->plhs[0] = NULL; xm = mxGetPr(fun->prhs[fun->xrhs]); for(i=0;i<n;i++) xm[i] = x[i].value(); //Add Surrogate if present and requested if(hasSur) { sur=mxGetLogicals(fun->prhs[fun->xrhs+1]); (x.get_eval_type()==NOMAD::SGTE)? *sur=true:*sur=false; } //Call MATLAB Objective try { status = mexCallMATLAB(1, fun->plhs, fun->nrhs, fun->prhs, fun->f); } //Note if these errors occur it is due to errors in MATLAB code, no way to recover? catch(exception &e) { sprintf(errstr,"Unrecoverable Error from Objective / Blackbox Callback:\n%sExiting NOMAD...\n\n",e.what()); mexWarnMsgTxt(errstr); //Force exit raise(SIGINT); return false; } catch(...) { mexWarnMsgTxt("Unrecoverable Error from Objective / Blackbox Callback, Exiting NOMAD...\n\n"); //Force exit raise(SIGINT); return false; } if(status) { mexWarnMsgTxt("Unrecoverable Error from Objective / Blackbox Callback, Exiting NOMAD...\n\n"); raise(SIGINT); return false; } #ifdef OPTI_VERSION //Check we got the correct number back if(mxGetM(fun->plhs[0]) != nobj) mexErrMsgTxt("Incorrect number of elements returned from the objective function"); //Set Objective (Or multi-objective) fvals = mxGetPr(fun->plhs[0]); for(i=0;i<nobj;i++) x.set_bb_output(i,fvals[i]); //Constraint Evaluation if(ncon) { //Add Surrogate if present and requested if(hasSur) { sur=mxGetLogicals(con->prhs[con->xrhs+1]); (x.get_eval_type()==NOMAD::SGTE)? *sur=true:*sur=false; } con->plhs[0] = NULL; xm = mxGetPr(con->prhs[con->xrhs]); for(i=0;i<n;i++) xm[i] = x[i].value(); //Call MATLAB Constraint try { status = mexCallMATLAB(1, con->plhs, con->nrhs, con->prhs, con->f); } catch(...) { mexWarnMsgTxt("Unrecoverable Error from Constraint Callback, Exiting NOMAD...\n\n"); //Force exit raise(SIGINT); return false; } if(status) { mexWarnMsgTxt("Unrecoverable Error from Constraint Callback, Exiting NOMAD...\n\n"); raise(SIGINT); return false; } //Check we got the correct number back if(mxGetM(con->plhs[0]) != ncon) mexErrMsgTxt("Incorrect number of elements returned from nonlinear constraint function"); //Set Constraints double *cons = mxGetPr(con->plhs[0]); for(i=0,j=nobj;i<ncon;i++,j++) x.set_bb_output(j,cons[i] - con->nlrhs[i]); //subtract nlrhs // Clean up LHS Ptr mxDestroyArray(con->plhs[0]); } #else //GERAD VERSION //Check we got the correct number of elements back if(mxGetNumberOfElements(fun->plhs[0]) > nobj+ncon) mexWarnMsgTxt("Black box returns more elements than required. Please provide a BB_OUTPUT_TYPE consistent with your black box function"); else if(mxGetNumberOfElements(fun->plhs[0]) < nobj+ncon) { mexErrMsgTxt("Insufficient outputs provided by the black box function. Exiting NOMAD...\n\n"); raise(SIGINT); return false; } //Assign bb output fvals = mxGetPr(fun->plhs[0]); for(i=0;i<(nobj+ncon);i++) x.set_bb_output(i,fvals[i]); #endif //Iteration Callback if(iterF->enabled) { iterF->plhs[0] = NULL; memcpy(mxGetData(iterF->prhs[1]), &citer, sizeof(int)); memcpy(mxGetPr(iterF->prhs[2]), fvals, sizeof(double)); memcpy(mxGetPr(iterF->prhs[3]), xm, n * sizeof(double)); try { status = mexCallMATLAB(1, iterF->plhs, 4, iterF->prhs, iterF->f); } catch (...) { mexWarnMsgTxt("Unrecoverable Error from Iteration Callback, Exiting NOMAD...\n\n"); //Force exit raise(SIGINT); return false; } if(status) { mexWarnMsgTxt("Unrecoverable Error from Iteration Callback, Exiting NOMAD...\n\n"); raise(SIGINT); return false; } //Collect return argument stop = *(bool*)mxGetData(iterF->plhs[0]); //Clean up Ptr mxDestroyArray(iterF->plhs[0]); } //Add Function Eval Counter citer++; // Clean up LHS Fun Ptr mxDestroyArray(fun->plhs[0]); //Check for iterfun stop if(stop) { mexPrintf("\nIterFun Called Stop. Exiting NOMAD...\n\n"); count_eval = false; raise(SIGINT); return false; } else return true; }
/*-----------------------------------------------------------------*/ 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(); }
/*--------------------------------------------*/ bool NOMAD::TGP_Model::predict(NOMAD::Eval_Point &x , bool pred_outside_bnds) { if (!_error_str.empty()) return false; if (!_model_computed) { _error_str = "NOMAD::TGP_Model::compute() has not been called"; return false; } int i , i0 , ix , m = x.get_m() , nx = x.size(); // reset point outputs: x.set_eval_status(NOMAD::EVAL_FAIL); for (i = 0 ; i < m ; ++i) x.set_bb_output(i , NOMAD::Double()); // check dimensions: if (m != static_cast<int>(_bbot.size()) || (nx != _n0 && nx != _n)) { _error_str = "predict error: bad x dimensions"; return false; } double ZZ , * XX = new double[_n]; // set the coordinates and check the bounds: for (i = 0 ; i < _n ; ++i) { ix = (nx == _n0) ? _fv_index[i] : i; if (!pred_outside_bnds) { i0 = _fv_index[i]; if (x[ix] < _lb[i0] || x[ix] > _ub[i0]) { delete [] XX; return false; // this is not an error } } XX[i] = x[ix].value(); } // predictions (one for each output): for (i = 0 ; i < m ; ++i) if (_tgp_models[i]) { if (!_tgp_models[i]->predict(XX , _n , ZZ , _tgp_rect)) { std::ostringstream oss; oss << "predict error: problem with model #" << i; _error_str = oss.str(); break; } x.set_bb_output(i , ZZ); } delete [] XX; if (!_error_str.empty()) { x.set_eval_status(NOMAD::EVAL_FAIL); return false; } x.set_eval_status(NOMAD::EVAL_OK); return true; }
/*-------------------------------------------------------------------*/ 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(); }