예제 #1
1
파일: nomadmex.cpp 프로젝트: ZiiCee/OPTI
// 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;
}
예제 #2
1
/*------------------------------------------*/
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;
}
예제 #3
0
/*-----------------------------------------------------------*/
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;
    }
    
}
예제 #4
0
		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;
  }
}
예제 #6
0
//-----------------------------------------------------------------------------------------------
// 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();


}