// Main Entry Function // ----------------------------------------------------------------- void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //Input Args usrFcn fun, con; double *x0, *lb = NULL, *ub = NULL; char *xtype = NULL; //Outputs Args double *x, *fval, *exitflag, *iter, *nfval; //Internal Vars size_t ndec; int i, nobj = 1, ncon = 0; char errstr[1024]; //used for returning error info iter_fun_data iterF; //Check user inputs if(!checkInputs(prhs,nrhs,plhs,nlhs)) return; //Redirect cout printfbuf buf; std::streambuf *cout_sbuf = std::cout.rdbuf(); //keep existing buffer std::cout.rdbuf(&buf); //redirect buffer //NOMAD Vars NOMAD::Mads *mads; NOMAD::Display out(std::cout); NOMAD::Parameters p(out); NOMAD::Point px0; NOMAD::Double *nx0; NOMAD::stop_type stopflag; //Evaluator Vars matlabEval *mSEval = NULL; matlabMEval *mBEval = NULL; //Set Option Defaults int printLevel = 0; char *paramfile = NULL; mxArray *bb_out_type = NULL; iterF.enabled = false; //Get Size ndec = mxGetNumberOfElements(pX0); //Get Blackbox / Objective Function Handle if (mxIsChar(pFUN)) { if(mxGetString(pFUN, fun.f, FLEN) != 0) mexErrMsgTxt("error reading objective name string"); fun.nrhs = 1; fun.xrhs = 0; } else { fun.prhs[0] = (mxArray*)pFUN; strcpy(fun.f, "feval"); fun.nrhs = 2; fun.xrhs = 1; } fun.prhs[fun.xrhs] = mxCreateDoubleMatrix(ndec, 1, mxREAL); //x //Get x0 x0 = mxGetPr(pX0); //Get xtype if(nrhs > eXTYPE && !mxIsEmpty(pXTYPE)) xtype = mxArrayToString(pXTYPE); //Get MEX Options if specified if(nrhs > eOPTS && !mxIsEmpty(pOPTS)) { if(mxGetField(pOPTS,0,"display_degree") && !mxIsEmpty(mxGetField(pOPTS,0,"display_degree"))) printLevel = (int)*mxGetPr(mxGetField(pOPTS,0,"display_degree")); if(mxGetField(pOPTS,0,"param_file") && !mxIsEmpty(mxGetField(pOPTS,0,"param_file"))) paramfile = mxArrayToString(mxGetField(pOPTS,0,"param_file")); if(mxGetField(pOPTS,0,"bb_output_type") && !mxIsEmpty(mxGetField(pOPTS,0,"bb_output_type"))) bb_out_type = mxGetField(pOPTS,0,"bb_output_type"); if(mxGetField(pOPTS,0,"iterfun") && !mxIsEmpty(mxGetField(pOPTS,0,"iterfun"))) { iterF.prhs[0] = (mxArray*)mxGetField(pOPTS,0,"iterfun"); strcpy(iterF.f, "feval"); iterF.enabled = true; iterF.prhs[1] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL); iterF.prhs[2] = mxCreateDoubleMatrix(1,1,mxREAL); iterF.prhs[3] = mxCreateDoubleMatrix(ndec,1,mxREAL); } } //Create Outputs (note x and fval created below, due to allowing bi-objective) plhs[2] = mxCreateDoubleMatrix(1,1, mxREAL); plhs[3] = mxCreateDoubleMatrix(1,1, mxREAL); plhs[4] = mxCreateDoubleMatrix(1,1, mxREAL); exitflag = mxGetPr(plhs[2]); iter = mxGetPr(plhs[3]); nfval = mxGetPr(plhs[4]); //Setup ndec p.set_DIMENSION((int)ndec); //Warn if >1000 if(ndec > 1000 && printLevel) { sprintf(errstr,"Warning: NOMAD is designed problems less than 1000 variables. Your model has %d.\nWhile unlikely, it is possible NOMAD may not perform as intended on this problem.",static_cast<int>(ndec)); mexWarnMsgTxt(errstr); } //Setup Lower Bounds if(nrhs > eLB && !mxIsEmpty(pLB)) { NOMAD::Point ptLB; NOMAD::Double *dLB = new NOMAD::Double[ndec]; lb = mxGetPr(pLB); for(i=0;i<ndec;i++) { if(!mxIsInf(lb[i])) //if not initialized will not be used dLB[i] = lb[i]; } ptLB.set((int)ndec,dLB); p.set_LOWER_BOUND(ptLB); delete [] dLB; } //Setup Upper Bounds if(nrhs > eUB && !mxIsEmpty(pUB)) { NOMAD::Point ptUB; NOMAD::Double *dUB = new NOMAD::Double[ndec]; ub = mxGetPr(pUB); for(i=0;i<ndec;i++) { if(!mxIsInf(ub[i])) //if not initialized will not be used dUB[i] = ub[i]; } ptUB.set((int)ndec,dUB); p.set_UPPER_BOUND(ptUB); delete [] dUB; } //Setup x0 nx0 = new NOMAD::Double[ndec]; #ifdef OPTI_VERSION double xl, xu; //If integer variables declared, need to ensure x0[i] is an integer if(xtype) { for(i=0;i<ndec;i++) { switch(tolower(xtype[i])) { case 'c': //Ensure within bounds if(lb && x0[i] < lb[i]) nx0[i] = lb[i]; else if(ub && x0[i] > ub[i]) nx0[i] = ub[i]; else nx0[i] = x0[i]; //no rounding break; case 'i': case 'b': xl = floor(x0[i]); //First round is a floor //If lower bounds exist if(lb) { //if lower bound broken if(xl < lb[i]) { xu = ceil(x0[i]); //If upper bounds exist, check bound directions if(ub && xu > ub[i]) { //if broken, no integer x0 exists sprintf(errstr,"x0[%d] cannot be rounded to an integer value between lb: %g, ub %g",i,lb[i],ub[i]); mexErrMsgTxt(errstr); } if(xu != x0[i]) { //If we changed something, warn user sprintf(errstr,"x0[%d] was rounded up to %g to suit NOMAD interface",i,xu); mexWarnMsgTxt(errstr); } //Save ceil value nx0[i] = xu; } //Floor value did not break lower bounds, value OK else { if(xl != x0[i]) { //If we changed something, warn user sprintf(errstr,"x0[%d] was rounded down to %g to suit NOMAD interface",i,xl); mexWarnMsgTxt(errstr); } //Save floor value nx0[i] = xl; } } //No lower bounds, floor value assumed OK else { if(xl != x0[i]) { //If we changed something, warn user sprintf(errstr,"x0[%d] was rounded down to %g to suit NOMAD interface",i,xl); mexWarnMsgTxt(errstr); } //Save floor value nx0[i] = xl; } break; case 'r': mexErrMsgTxt("Please specify continuous (real) variables using 'c' (as opposed to 'r') when using the OPTI version"); break; default: sprintf(errstr,"Unknown xtype[%d] character: %c\n\nValid options are 'C', 'I', or 'B'\n",i,xtype[i]); mexErrMsgTxt(errstr); } } } //Else user start position within bounds else { for(i=0;i<ndec;i++) { if(lb && x0[i] < lb[i]) nx0[i] = lb[i]; else if(ub && x0[i] > ub[i]) nx0[i] = ub[i]; else nx0[i] = x0[i]; } } #else //GERAD VERSION - no x0 checking for(i=0;i<ndec;i++) nx0[i] = x0[i]; #endif px0.set((int)ndec,nx0); p.set_X0(px0); delete [] nx0; #ifdef OPTI_VERSION //Setup Nonlinear Constraints if(nrhs > eNLCON && !mxIsEmpty(pNLCON)) { if (mxIsChar(pNLCON)) { if(mxGetString(pNLCON, con.f, FLEN) != 0) mexErrMsgTxt("error reading constraint name string"); con.nrhs = 1; con.xrhs = 0; } else { con.prhs[0] = (mxArray*)pNLCON; strcpy(con.f, "feval"); con.nrhs = 2; con.xrhs = 1; } con.prhs[con.xrhs] = mxCreateDoubleMatrix(ndec, 1, mxREAL); //x if(nrhs < eNLRHS+1 || mxIsEmpty(pNLRHS)) {//we will default to <= 0 ncon = -1; con.nlrhs = NULL; } else { ncon = (int)mxGetNumberOfElements(pNLRHS); con.nlrhs = mxGetPr(pNLRHS); } } //Setup Input Variable Types if(xtype) p.set_BB_INPUT_TYPE(detInTypes(xtype,ndec)); //Setup Evaluation Return Types + #'s of Obj + Con p.set_BB_OUTPUT_TYPE(detRetTypes(&fun,bb_out_type,&nobj,&con,&ncon,x0,ndec)); //Set All Normal NOMAD Options p.set_DISPLAY_DEGREE(0); //default #endif //GERAD Version does not have a separate constraint handler and handles input and output types using options //Set User Options if(nrhs > eOPTS && !mxIsEmpty(pOPTS)) setNOMADopts(p,pOPTS); else setNOMADopts(p,NULL); //If the user has specified a parameter file to read, see if it exists, and if so, read and parse it. if(paramfile) { FILE *pFile = fopen(paramfile,"r"); if(pFile==NULL) { sprintf(errstr,"Cannot open parameter file: %s\n\nEnsure it exists!",paramfile); mexErrMsgTxt(errstr); } else{ fclose(pFile); //close file pointer (we don't need it) try { p.read(paramfile); } catch(exception &e) { sprintf(errstr,"NOMAD Parameter File Read Error:\n\n%s",e.what()); mexErrMsgTxt(errstr); } } } //Check NOMAD parameters try { p.check(); } catch(exception &e) { sprintf(errstr,"NOMAD Parameter Error:\n\n%s",e.what()); mexErrMsgTxt(errstr); } //Check for categorical variables if (p.get_signature()->has_categorical()) mexErrMsgTxt("The MATLAB version of NOMAD does not support categorical variables yet! Check BB_INPUT_TYPE parameter."); //If GERAD version, obtain number of objectives and constraints from parameters #ifndef OPTI_VERSION nobj=p.get_nb_obj(); ncon=(int)p.get_bb_output_type().size()-nobj; #endif //If user has requested surrogates, setup extra input arg to callbacks if (p.has_sgte()) { fun.prhs[fun.xrhs+1] = mxCreateLogicalMatrix(1,1); //extra logical indicating surrogate or not fun.nrhs++; #ifdef OPTI_VERSION con.prhs[con.xrhs+1] = mxCreateLogicalMatrix(1,1); con.nrhs++; #endif } //Print Header if(printLevel) { mexPrintf("\n------------------------------------------------------------------\n"); mexPrintf(" This is NOMAD v%s\n",NOMAD::VERSION.c_str()); mexPrintf(" Authors: M. Abramson, C. Audet, G. Couture, J. Dennis, S. Le Digabel, C. Tribes\n\n"); mexPrintf(" Problem Properties:\n"); mexPrintf(" # Decision Variables: %4d\n",ndec); mexPrintf(" # Number of Objectives: %4d\n",nobj); mexPrintf(" # Number of Nonlinear Constraints: %4d\n",ncon); mexPrintf("------------------------------------------------------------------\n"); mexEvalString("drawnow;"); //flush draw buffer } //Let this file sort out errors mexSetTrapFlag(1); //Reset tags and bbe (C.Tribes 3/14) NOMAD::Eval_Point::reset_tags_and_bbes(); //Create evaluator and run mads based on number of objectives try { if(nobj > 1) { mBEval = new matlabMEval(p,&fun,nobj,&con,ncon,&iterF); //Bi-Objective Evaluator mads = new NOMAD::Mads(p, mBEval); //Run NOMAD stopflag = mads->multi_run(); } else { mSEval = new matlabEval(p,&fun,nobj,&con,ncon,&iterF); //Single Objective Evaluator mads = new NOMAD::Mads(p, mSEval); //Run NOMAD stopflag = mads->run(); } } catch(exception &e) { //Free Memory (C.Tribes 3/14) if(mSEval) delete mSEval; mSEval = NULL; if(mBEval) delete mBEval; mBEval = NULL; delete mads; if(xtype) mxFree(xtype); xtype = NULL; //Report Error sprintf(errstr,"NOMAD Run Error:\n\n%s",e.what()); mexErrMsgTxt(errstr); } if(printLevel) mexPrintf("------------------------------------------------------------------\n"); //Obtain Solution based on Single or Multi-Objective (C.Tribes oct 09, 2013 --- changed to deal with pareto output) if(nobj>1) { NOMAD::Pareto_Front * pareto_front=mads->get_pareto_front(); if (pareto_front) { int nb_pareto_pts = pareto_front->size(); plhs[0] = mxCreateDoubleMatrix(ndec,nb_pareto_pts, mxREAL); plhs[1] = mxCreateDoubleMatrix(nobj,nb_pareto_pts, mxREAL); x = mxGetPr(plhs[0]); fval = mxGetPr(plhs[1]); const NOMAD::Eval_Point * cur = pareto_front->begin(); int i=0; while ( cur ) { //mexPrintf("i %d OK: %d FEAS: %d\n",i,cur->is_eval_ok(),cur->is_feasible ( p.get_h_min() )); if ( cur->is_eval_ok() && cur->is_feasible ( p.get_h_min() ) ) { const std::list<int> & index_obj = p.get_index_obj(); std::list<int>::const_iterator it , end = index_obj.end(); const NOMAD::Point & bbo = cur->get_bb_outputs(); int j = 0; NOMAD::Point multi_obj ( static_cast<int>(index_obj.size()) ); for ( it = index_obj.begin() ; it != end ; ++it,j++ ) fval[nobj*i+j] = bbo[*it].value(); for(j=0;j<ndec;j++) x[ndec*i+j] = (*cur)[j].value(); } cur = pareto_front->next(); i++; } *exitflag = getStatus(stopflag); } else { stopflag = (NOMAD::stop_type)10; *exitflag = -1; //No solution } } else { //Create single objective outputs plhs[0] = mxCreateDoubleMatrix(ndec,1, mxREAL); plhs[1] = mxCreateDoubleMatrix(1,1, mxREAL); x = mxGetPr(plhs[0]); fval = mxGetPr(plhs[1]); const NOMAD::Eval_Point *bestSol = mads->get_best_feasible(); if(bestSol == NULL) { bestSol = mads->get_best_infeasible(); //manually set as infeasible (no infeasible stop flag) stopflag = (NOMAD::stop_type)10; } if(bestSol == NULL) *exitflag = -1; //No solution //If we have a solution, save it if(*exitflag != -1) { //Save x NOMAD::Point pt(*bestSol); for(i=0;i<ndec;i++) x[i] = pt[i].value(); //Save fval *fval = bestSol->get_f().value(); //Save Status *exitflag = getStatus(stopflag); } } //Common outputs *iter = mads->get_stats().get_iterations(); *nfval = mads->get_stats().get_bb_eval(); //Return cout to initial buffer std::cout.rdbuf(cout_sbuf); //Return error control to default mexSetTrapFlag(0); //Free Memory if(mSEval) delete mSEval; mSEval = NULL; if(mBEval) delete mBEval; mBEval = NULL; delete mads; if(xtype) mxFree(xtype); xtype = NULL; }
/*------------------------------------------*/ int main ( int argc , char ** argv ) { // display: NOMAD::Display out ( NOMAD::rout ); //zhenghua out.precision ( NOMAD::DISPLAY_PRECISION_STD ); std::string error; { // NOMAD initializations: NOMAD::begin ( argc , argv ); // usage: if ( argc < 2 ) { NOMAD::display_usage ( out); //zhenghua NOMAD::end(); return EXIT_FAILURE; } // parameters file: std::string param_file_name = argv[1]; std::string opt = param_file_name; NOMAD::toupper ( opt ); // display version if option '-v' has been specified: if ( opt == "-U" ) { NOMAD::display_usage ( out ); NOMAD::end(); return EXIT_SUCCESS; } // display version if option '-v' has been specified: if ( opt == "-V" || opt =="-VERSION") { NOMAD::display_version ( out ); NOMAD::end(); return EXIT_SUCCESS; } // display info if option '-i' has been specified: if ( opt == "-I" || opt == "-INFO" ) { NOMAD::display_info ( out ); NOMAD::display_usage ( out ); //zhenghua NOMAD::end(); return EXIT_SUCCESS; } // parameters creation: NOMAD::Parameters p ( out ); // display help on parameters if option '-h' has been specified: if ( opt == "-H" || opt == "-HELP" ) { p.help ( argc , argv ); NOMAD::end(); return EXIT_SUCCESS; } // display developer help on parameters if option '-d' has been specified: if ( opt == "-D" ) { p.help ( argc , argv,true ); NOMAD::end(); return EXIT_SUCCESS; } // check the number of processess: #ifdef USE_MPI if ( NOMAD::Slave::get_nb_processes() < 2 ) { NOMAD::rout << "ERROR: Incorrect command to run with MPI." << std::endl; //zhenghua NOMAD::display_usage ( out ); //zhenghua NOMAD::end(); return EXIT_FAILURE; } #endif try { // read parameters file: p.read ( param_file_name ); // parameters check: p.check(); // display NOMAD info: if ( p.get_display_degree() > NOMAD::MINIMAL_DISPLAY) NOMAD::display_info ( out ); // parameters display: if ( NOMAD::Slave::is_master() && p.get_display_degree() == NOMAD::FULL_DISPLAY ) out << std::endl << NOMAD::open_block ( "parameters" ) << std::endl << p << NOMAD::close_block(); // algorithm creation and execution: NOMAD::Mads mads ( p , NULL ); if ( p.get_nb_obj() == 1 ) mads.run(); else mads.multi_run(); #ifdef MODEL_STATS mads.display_model_stats ( out ); #endif } catch ( std::exception & e ) { if ( NOMAD::Slave::is_master() ) { error = std::string ( "NOMAD has been interrupted: " ) + e.what(); NOMAD::rout << std::endl << error << std::endl << std::endl; //zhenghua } } NOMAD::Slave::stop_slaves ( out ); NOMAD::end(); } #ifdef MEMORY_DEBUG NOMAD::display_cardinalities ( out ); #endif return ( error.empty() ) ? EXIT_SUCCESS : EXIT_FAILURE; }
/*-----------------------------------------------------------*/ void NOMAD::LH_Search::search ( NOMAD::Mads & mads , int & nb_search_pts , bool & stop , NOMAD::stop_type & stop_reason , NOMAD::success_type & success , bool & count_search , const NOMAD::Eval_Point *& new_feas_inc , const NOMAD::Eval_Point *& new_infeas_inc ) { new_feas_inc = new_infeas_inc = NULL; nb_search_pts = 0; success = NOMAD::UNSUCCESSFUL; count_search = !stop; if ( stop ) return; // initial display: const NOMAD::Display & out = _p.out(); NOMAD::dd_type display_degree = out.get_search_dd(); if ( display_degree == NOMAD::FULL_DISPLAY ) { std::ostringstream oss; oss << NOMAD::LH_SEARCH; out << std::endl << NOMAD::open_block ( oss.str() ) << std::endl; } // active barrier: const NOMAD::Barrier & barrier = mads.get_active_barrier(); // Evaluator_Control: NOMAD::Evaluator_Control & ev_control = mads.get_evaluator_control(); // current incumbents: const NOMAD::Eval_Point * feas_inc = barrier.get_best_feasible (); const NOMAD::Eval_Point * infeas_inc = barrier.get_best_infeasible(); // get a reference point and a signature: const NOMAD::Eval_Point * ref = (feas_inc) ? feas_inc : infeas_inc; NOMAD::Signature * signature = _p.get_signature(); // check the number of points: int p = _initial_search ? _p.get_LH_search_p0() : _p.get_LH_search_pi(); if ( p <= 0 ) { if ( display_degree == NOMAD::FULL_DISPLAY ) { std::ostringstream oss; oss << "end of LH " << ( _initial_search ? "initial " : "") << "search (number of points <= 0)"; out << std::endl << NOMAD::close_block ( oss.str() ) << std::endl; } return; } // no reference point is available (we consider the standard signature): if ( !ref ) { // it is not sufficient with categorical variables: if ( signature->has_categorical() ) { if ( display_degree == NOMAD::FULL_DISPLAY ) { std::ostringstream oss; oss << "end of LH " << ( _initial_search ? "initial " : "") << "search (no available reference point)"; out << std::endl << NOMAD::close_block ( oss.str() ) << std::endl; } return; } } else signature = ref->get_signature(); // Change Display stats style const std::list<std::string> old_ds = _p.get_display_stats(); std::list<std::string> ds = old_ds; ds.push_back ( " (LH)" ); _p.set_DISPLAY_STATS ( ds ); // check the parameters: _p.check ( false , // remove_history_file = false false , // remove_solution_file = false false ); // remove_stats_file = false int i; NOMAD::Eval_Point * x; int n = signature->get_n(); int m = _p.get_bb_nb_outputs(); int pm1 = p-1; // mesh size: NOMAD::Point delta_max = signature->get_mesh()->get_delta_max (); NOMAD::Double delta_i; NOMAD::Point delta; if ( !_initial_search ) signature->get_mesh()->get_delta ( delta ); // fixed variables: const NOMAD::Point & fixed_variables = signature->get_fixed_variables(); // bb input types: const std::vector<NOMAD::bb_input_type> & bbit = signature->get_input_types(); // bounds: const NOMAD::Point & lb = signature->get_lb(); const NOMAD::Point & ub = signature->get_ub(); // pts contains n points of dimension p: each of these points contains // p different values for each variable: NOMAD::Point ** pts = new NOMAD::Point * [n]; // creation of p search points: for ( int k = 0 ; k < p ; ++k ) { x = new NOMAD::Eval_Point ( n , m ); x->set_signature ( signature ); for ( i = 0 ; i < n ; ++i ) { if ( k==0 ) { if ( fixed_variables[i].is_defined() ) pts[i] = new NOMAD::Point ( p , fixed_variables[i] ); else if ( bbit[i] == NOMAD::CATEGORICAL ) { pts[i] = new NOMAD::Point ( p , (*ref)[i] ); } else { pts[i] = new NOMAD::Point ( p ); if ( !_initial_search ) delta_i = delta[i]; values_for_var_i ( p , delta_i , delta_max[i] , bbit [i] , lb [i] , ub [i] , *pts [i] ); } } (*x)[i] = (*pts[i])[k]; if ( k == pm1 ) delete pts[i]; } if ( display_degree == NOMAD::FULL_DISPLAY ) { out << "LH point #" << x->get_tag() << ": ( "; x->Point::display ( out , " " , 2 , NOMAD::Point::get_display_limit() ); out << " )" << std::endl; } // add the new point to the ordered list of search trial points: ev_control.add_eval_point ( x , display_degree , false , // snap_to_bounds = false NOMAD::Double() , NOMAD::Double() , NOMAD::Double() , NOMAD::Double() ); } delete [] pts; nb_search_pts = ev_control.get_nb_eval_points(); // eval_list_of_points: // -------------------- new_feas_inc = new_infeas_inc = NULL; ev_control.eval_list_of_points ( _type , mads.get_true_barrier() , mads.get_sgte_barrier() , mads.get_pareto_front() , stop , stop_reason , new_feas_inc , new_infeas_inc , success ); _p.get_display_stats(); // restore stats style _p.set_DISPLAY_STATS ( old_ds ); _p.check ( false , // remove_history_file = false false , // remove_solution_file = false false ); // remove_stats_file = false // final displays: if ( display_degree == NOMAD::FULL_DISPLAY ) { std::ostringstream oss; oss << "end of LH search (" << success << ")"; out << std::endl << NOMAD::close_block ( oss.str() ) << std::endl; } }
SEXP smultinomadRSolve( SEXP args ) { R_CheckUserInterrupt(); SEXP solution; // showArgs1(args); PROTECT(solution=args); NOMAD::Display out(rout); out.precision(NOMAD::DISPLAY_PRECISION_STD); theenv = getListElement(args, "snomadr.environment"); thefun = getListElement(args, "eval.f"); unsigned int seed; SEXP rseed = getListElement(args, "random.seed"); if(isNull(rseed)) seed = unsigned(time(NULL)); else seed = INTEGER(rseed)[0]; if(seed == 0) seed = unsigned(time(NULL)); srand(seed); try{ R_CheckUserInterrupt(); vector<NOMAD::Point*> x0_pts; NOMAD::Parameters param(out); SEXP sN = getListElement(args,"n"); int N = INTEGER(sN)[0]; int i; SEXP snmulti = getListElement(args, "nmulti"); int nmulti= INTEGER(snmulti)[0]; param.set_DIMENSION(N); // Default options // param.set_DIRECTION_TYPE(NOMAD::GPS_2N_RAND); // param.set_OPPORTUNISTIC_EVAL(true); // param.set_MIN_POLL_SIZE(0.001); // param.set_MIN_MESH_SIZE(0.001); // param.set_INITIAL_MESH_SIZE(0.01); param.set_MAX_BB_EVAL(10000); vector<NOMAD::bb_input_type> bbin(N); NOMAD::Point lb(N); NOMAD::Point ub(N); SEXP sbbin = getListElement(args, "bbin"); SEXP slb = getListElement(args, "lower.bounds"); SEXP sub = getListElement(args, "upper.bounds"); int print_output = INTEGER(getListElement(args, "print.output"))[0]; for( i= 0;i<N;i++) { R_CheckUserInterrupt(); switch(INTEGER(sbbin)[i]) { case 0: default: bbin[i]= NOMAD::CONTINUOUS; lb[i]= REAL(slb)[i]; ub[i]= REAL(sub)[i]; break; case 1: bbin[i]= NOMAD::INTEGER; lb[i]= (int)(REAL(slb)[i]); ub[i]= (int)(REAL(sub)[i]); break; case 2: bbin[i]= NOMAD::CATEGORICAL ; lb[i]= (int)(REAL(slb)[i]); ub[i]= (int)(REAL(sub)[i]); break; case 3: bbin[i]= NOMAD::BINARY; lb[i]= (int)(REAL(slb)[i]); ub[i]= (int)(REAL(sub)[i]); break; } } param.set_BB_INPUT_TYPE(bbin); param.set_LOWER_BOUND(lb); param.set_UPPER_BOUND(ub); /* initial points */ LH_x0(N,nmulti,x0_pts, lb, ub, bbin); SEXP sx0 = getListElement(args, "x0"); //we may use this as best_x if(!isNull(sx0)) { if(LENGTH(sx0) == N) /* x0 as the first initial point. */ { for( i=0;i<N;i++) { (*x0_pts[0])[i]= REAL(sx0)[i]; } } /* all initial points are input. please note the memory order of an array ( it seems that R uses the Fortran style.).*/ else if((LENGTH(sx0) >= N*nmulti) && (nmulti > 1) ) { for (int j=0; j< nmulti; j++) { for( i=0;i<N;i++) { (*x0_pts[j])[i]= REAL(sx0)[j+i*nmulti]; } } } } else { // read best_x.txt: ifstream fin ( "best_x.txt"); if ( !fin.fail() ) for ( i = 0 ; i < N ; ++i ) fin >> (*x0_pts[0])[i]; fin.close(); } SEXP sbbout = getListElement(args, "bbout"); vector<NOMAD::bb_output_type> bbot(LENGTH(sbbout)); for( i=0;i<LENGTH(sbbout);i++){ bbot[i] = NOMAD::bb_output_type(INTEGER(sbbout)[i]); } param.set_BB_OUTPUT_TYPE(bbot); param.set_DISPLAY_DEGREE (0); param.set_DISPLAY_STATS("bbe ( sol ) obj"); /* set other options in R */ SEXP opts; opts = getListElement(args, "options"); setApplicationOptions(param, opts ); /* set other options in nomad.opt */ if(file_exists("nomad.opt")) param.read("nomad.opt"); param.set_X0 ( *x0_pts[0] ); param.check(); // display all starting points: if(print_output > 0 ){ out << endl; for ( int j = 0 ; j < nmulti ; ++j ) out << "starting point # " << j << ": ( " << *x0_pts[j] << " )" << endl; out << endl; } RMy_Evaluator ev(param); const NOMAD::Eval_Point * cur_x; NOMAD::Point best_x (N); NOMAD::Double best_f = NOMAD::INF , worst_f = 0.0 , avg_f = 0.0; // MADS runs: // ---------- int bbe = 0; int iter = 0; i = 0; NOMAD::stop_type status ; while ( true ) { R_CheckUserInterrupt(); // algorithm creation: NOMAD::Mads mads ( param , &ev ); status = mads.run(); if ( status == NOMAD::CTRL_C ) R_CheckUserInterrupt(); //)exit(-1); bbe += mads.get_cache().size(); /* the number of evaluations of the objectibve function. */ iter += mads.get_stats().get_iterations(); // displays and remember the best point: if( print_output > 0 ) out << "\rrun #" << setw(2) << i << ": "; cur_x = mads.get_best_feasible(); if ( cur_x ) { if(print_output > 0 ) out << "f=" << cur_x->get_f() << endl; if ( cur_x->get_f() < best_f ) { best_f = cur_x->get_f(); best_x = *cur_x; } if ( cur_x->get_f() > worst_f ) worst_f = cur_x->get_f(); avg_f += cur_x->get_f(); } else{ if(print_output > 0 ) out << "NULL" << endl; } if ( ++i == nmulti ) break; // preparation of next run: mads.reset(); param.reset_X0(); param.set_X0 ( *x0_pts[i] ); param.check(); } // display the solution: if(print_output > 0 ) { out << endl << "bb eval : " << bbe << endl << "best : " << best_f; out << endl << "worst : " << worst_f << endl << "solution: "; out << "x = ( "; best_x.display ( out , " " , -1 , -1 ); out << " ) f(x) = " << best_f.value(); out << endl << endl; } //ofstream fout ( "best_x.txt" ); //fout << setprecision(32); //best_x.display ( fout , " " , -1 , -1 ); //fout.close(); // delete x0 points: for ( i = 0 ; i < nmulti ; ++i ) delete x0_pts[i]; double obj_value = best_f.value(); double *sol_x; sol_x = (double *)malloc(sizeof(double)*N); for(int i=0;i<N;i++) { sol_x[i]= best_x[i].value(); } solution = print_solution(obj_value, sol_x, N, bbe, iter, nmulti, status); free(sol_x); } catch(std::exception &e){ error("\nNOMAD has been interrupted ( %s )\n\n", e.what()); } NOMAD::Slave::stop_slaves(out); NOMAD::end(); UNPROTECT(1); return(solution); }
/*-------------------------------------------------------------*/ void NOMAD::Speculative_Search::search ( NOMAD::Mads & mads , int & nb_search_pts , bool & stop , NOMAD::stop_type & stop_reason , NOMAD::success_type & success , bool & count_search , const NOMAD::Eval_Point *& new_feas_inc , const NOMAD::Eval_Point *& new_infeas_inc ) { // new_feas_inc and new_infeas_inc are used as inputs, // so do not initialize them to NULL here nb_search_pts = 0; success = NOMAD::UNSUCCESSFUL; count_search = !stop; if ( stop ) return; const NOMAD::Display & out = _p.out(); NOMAD::dd_type display_degree = out.get_search_dd(); if ( display_degree == NOMAD::FULL_DISPLAY ) { std::ostringstream oss; oss << NOMAD::SPEC_SEARCH; out << std::endl << NOMAD::open_block ( oss.str() ) << std::endl; } int lkm1; // l_{k-1} int lk; // l_k int n; NOMAD::Signature * signature; NOMAD::Point delta_m_k; NOMAD::Point delta_m_km1; NOMAD::Point factor; NOMAD::Point xkm1; NOMAD::Eval_Point * sk; const NOMAD::Eval_Point * x[2]; x[0] = new_feas_inc; x[1] = new_infeas_inc; // Evaluator_Control: NOMAD::Evaluator_Control & ev_control = mads.get_evaluator_control(); for ( int i = 0 ; i < 2 ; ++i ) { if ( x[i] && x[i]->get_mesh_index() ) { const NOMAD::Direction * dir = x[i]->get_direction(); if ( dir && ( dir->is_mads() || dir->get_type()==NOMAD::MODEL_SEARCH_DIR ) ) { // get the x_k's signature: signature = x[i]->get_signature(); if ( !signature ) throw NOMAD::Exception ( "Speculative_Search.cpp" , __LINE__ , "Speculative_Search::search(): could not get the signature" ); xkm1 = *x[i] - *dir; lk = lkm1 = *x[i]->get_mesh_index(); NOMAD::Mesh::update ( NOMAD::FULL_SUCCESS , lk ); n = signature->get_n(); delta_m_k = NOMAD::Point ( n ); delta_m_km1 = NOMAD::Point ( n ); factor = NOMAD::Point ( n ); signature->get_mesh().get_delta_m ( delta_m_k , lk ); signature->get_mesh().get_delta_m ( delta_m_km1 , lkm1 ); // multiplicative factor: takes into account the fact that // the direction contains \Delta^m_k: try { // factor = delta_m_k / delta_m_km1 : for ( int k = 0 ; k < n ; ++k ) { if ( delta_m_k[k].is_defined() && delta_m_km1[k].is_defined() && delta_m_k[k].value() != 0.0 && delta_m_km1[k].value() != 0.0 ) factor[k] = delta_m_k[k] / delta_m_km1[k]; else factor[k] = 0.0; } } catch ( NOMAD::Double::Invalid_Value & ) { if ( display_degree == NOMAD::FULL_DISPLAY ) out << "could not compute " << _type << " point: stop" << std::endl << NOMAD::close_block ( "end of speculative search" ); stop = true; stop_reason = NOMAD::MESH_PREC_REACHED; return; } if ( lkm1 <= 0 ) factor *= NOMAD::Mesh::get_mesh_update_basis(); // speculative search point: NOMAD::Direction new_dir ( n , 0.0 , dir->get_type() ); new_dir.Point::operator = ( factor * *dir ); sk = new NOMAD::Eval_Point; sk->set ( n , _p.get_bb_nb_outputs() ); sk->set_signature ( signature ); sk->set_direction ( &new_dir ); sk->set_mesh_index ( &lk ); sk->Point::operator = ( xkm1 + new_dir ); if ( display_degree == NOMAD::FULL_DISPLAY ) { out << "trial point #" << sk->get_tag() << ": ( "; sk->Point::display ( out ," " , 2 , NOMAD::Point::get_display_limit() ); out << " )" << std::endl; } // add the new point to the list of search trial points: ev_control.add_eval_point ( sk , display_degree , _p.get_snap_to_bounds() , NOMAD::Double() , NOMAD::Double() , NOMAD::Double() , NOMAD::Double() ); } } } nb_search_pts = ev_control.get_nb_eval_points(); // eval_list_of_points: // -------------------- new_feas_inc = new_infeas_inc = NULL; ev_control.eval_list_of_points ( _type , mads.get_true_barrier() , mads.get_sgte_barrier() , mads.get_pareto_front() , stop , stop_reason , new_feas_inc , new_infeas_inc , success ); if ( display_degree == NOMAD::FULL_DISPLAY ) { std::ostringstream oss; oss << "end of speculative search (" << success << ")"; out << NOMAD::close_block ( oss.str() ) << std::endl; } }
//----------------------------------------------------------------------------------------------- // Starts the optimization //----------------------------------------------------------------------------------------------- void NomadIpoptOptimizer::start() { cout << "Starting the NOMAD optimizer..." << endl; if(p_disp == 0) initialize(); try { // NOMAD initializations: NOMAD::begin(0, 0); // hope this works, was: begin(argc, argv) // parameters creation: generateParameters(); // custom evaluator creation: p_evaluator = new NomadIpoptEvaluator(*p_param, this); // algorithm creation and execution: NOMAD::Mads mads ( *p_param , p_evaluator ); mads.run(); // getting the best feasible solution, sending it to the runner if exists const NOMAD::Eval_Point *best_feas = mads.get_best_feasible(); if(best_feas != NULL) { const NOMAD::Point outputs = best_feas->get_bb_outputs(); // setting the variable values Case *c = p_evaluator->generateCase(*best_feas); // trying to find a result case in the evaluator Case *res = p_evaluator->findResult(c); if(res != 0) sendBestCaseToRunner(res); else { // the objective c->setObjectiveValue(-outputs[0].value()); // sending it to the runner sendBestCaseToRunner(c); } delete c; } } catch(exception &e) { cerr << "\nNOMAD has been interrupted (" << e.what() << ")\n\n"; } NOMAD::Slave::stop_slaves (*p_disp); NOMAD::end(); emit finished(); }