1 /*-------------------------------------------------------------------------------------*/
2 /*  NOMAD - Nonlinear Optimization by Mesh Adaptive Direct search - version 3.7.2      */
3 /*                                                                                     */
4 /*  Copyright (C) 2001-2015  Mark Abramson        - the Boeing Company, Seattle        */
5 /*                           Charles Audet        - Ecole Polytechnique, Montreal      */
6 /*                           Gilles Couture       - Ecole Polytechnique, Montreal      */
7 /*                           John Dennis          - Rice University, Houston           */
8 /*                           Sebastien Le Digabel - Ecole Polytechnique, Montreal      */
9 /*                           Christophe Tribes    - Ecole Polytechnique, Montreal      */
10 /*                                                                                     */
11 /*  funded in part by AFOSR and Exxon Mobil                                            */
12 /*                                                                                     */
13 /*  Author: Sebastien Le Digabel                                                       */
14 /*                                                                                     */
15 /*  Contact information:                                                               */
16 /*    Ecole Polytechnique de Montreal - GERAD                                          */
17 /*    C.P. 6079, Succ. Centre-ville, Montreal (Quebec) H3C 3A7 Canada                  */
18 /*    e-mail: nomad@gerad.ca                                                           */
19 /*    phone : 1-514-340-6053 #6928                                                     */
20 /*    fax   : 1-514-340-5665                                                           */
21 /*                                                                                     */
22 /*  This program is free software: you can redistribute it and/or modify it under the  */
23 /*  terms of the GNU Lesser General Public License as published by the Free Software   */
24 /*  Foundation, either version 3 of the License, or (at your option) any later         */
25 /*  version.                                                                           */
26 /*                                                                                     */
27 /*  This program is distributed in the hope that it will be useful, but WITHOUT ANY    */
28 /*  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A    */
29 /*  PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.   */
30 /*                                                                                     */
31 /*  You should have received a copy of the GNU Lesser General Public License along     */
32 /*  with this program. If not, see <http://www.gnu.org/licenses/>.                     */
33 /*                                                                                     */
34 /*  You can find information on the NOMAD software at www.gerad.ca/nomad               */
35 /*-------------------------------------------------------------------------------------*/
36 /**
37   \file   Evaluator_Control.cpp
38   \brief  Control of the blackbox evaluations (implementation)
39   \author Sebastien Le Digabel
40   \date   2010-04-15
41   \see    Evaluator_Control.hpp
42 */
43 #include "Evaluator_Control.hpp"
44 #include "Multi_Obj_Quad_Model_Evaluator.hpp"
45 #include "Single_Obj_Quad_Model_Evaluator.hpp"
46 
47 /*-----------------------------------*/
48 /*   static members initialization   */
49 /*-----------------------------------*/
50 bool NOMAD::Evaluator_Control::_force_quit = false;
51 bool NOMAD::Evaluator_Control::_force_evaluation_failure = false;
52 
53 
54 /*---------------------------------------------------------*/
55 /*                       constructor                       */
56 /*---------------------------------------------------------*/
Evaluator_Control(const NOMAD::Parameters & p,NOMAD::Stats & stats,NOMAD::Evaluator * ev,NOMAD::Cache * cache,NOMAD::Cache * sgte_cache)57 NOMAD::Evaluator_Control::Evaluator_Control
58 ( const NOMAD::Parameters & p          ,
59   NOMAD::Stats            & stats      ,
60   NOMAD::Evaluator        * ev         ,   // can be NULL
61   NOMAD::Cache            * cache      ,   // can be NULL
62   NOMAD::Cache            * sgte_cache   ) // can be NULL
63   : _p                ( p          ) ,
64     _ev               ( ev         ) ,
65     _cache            ( cache      ) ,
66     _sgte_cache       ( sgte_cache ) ,
67     _model_eval_sort  ( true       ) ,
68     _del_ev           ( false      ) ,
69     _del_cache        ( false      ) ,
70     _del_sgte_cache   ( false      ) ,
71 #ifdef USE_MPI
72     _eval_in_progress ( NULL       ) ,
73     _nb_in_progress   ( 0          ) ,
74     _elop_tag         ( 0          ) ,
75     _slaves_elop_tags ( NULL       ) ,
76     _slave            ( NULL       ) ,
77 #endif
78 #ifdef USE_TGP
79     _last_TGP_model   ( NULL       ) ,
80 #endif
81     _stats            ( stats      ) ,
82     _last_stats_tag   ( -1         ) ,
83     _last_stats_bbe   ( -1         ) ,
84     _last_history_bbe ( -1         )
85 {
86   NOMAD::Evaluator_Control::_force_quit = false;
87 
88   // Evaluator init:
89   if ( !_ev ) {
90     _ev = ( _p.get_index_obj().size() > 1 ) ? new NOMAD::Multi_Obj_Evaluator ( p ):
91                                               new NOMAD::Evaluator           ( p );
92     _del_ev = true;
93   }
94 
95   if ( NOMAD::Slave::is_master() ) {
96 
97 #ifdef USE_MPI
98 
99     int np = NOMAD::Slave::get_nb_processes();
100 
101     _eval_in_progress = new NOMAD::Eval_Point * [np];
102     _slaves_elop_tags = new int                 [np];
103     for ( int i = 0 ; i < np ; ++i ) {
104       _eval_in_progress[i] = NULL;
105       _slaves_elop_tags[i] = -1;
106     }
107 
108     _slave = new NOMAD::Slave ( _p , _ev );
109 
110 #endif
111 
112     const NOMAD::Display & out = _p.out();
113 
114     // caches creation:
115     if ( !_cache ) {
116       _cache     = new NOMAD::Cache ( out , NOMAD::TRUTH );
117       _del_cache = true;
118     }
119     if ( !_sgte_cache ) {
120       _sgte_cache     = new NOMAD::Cache ( out , NOMAD::SGTE );
121       _del_sgte_cache = true;
122     }
123 
124     // caches init (we only load cache file points with m blackbox outputs):
125     std::string    file_name;
126     int            m              = p.get_bb_nb_outputs();
127     NOMAD::dd_type display_degree = out.get_gen_dd();
128 
129     if ( !_p.get_cache_file().empty() ) {
130       file_name = _p.get_problem_dir() + _p.get_cache_file();
131       if ( !_cache->load ( file_name , &m , display_degree == NOMAD::FULL_DISPLAY )
132 	   && display_degree != NOMAD::NO_DISPLAY && display_degree != NOMAD::MINIMAL_DISPLAY)
133 	out << std::endl
134 	    << "Warning (" << "Evaluator_Control.cpp" << ", " << __LINE__
135 	    << "): could not load (or create) the cache file " << file_name
136 	    << std::endl << std::endl;
137     }
138 
139     if ( !_p.get_sgte_cache_file().empty() ) {
140       file_name = _p.get_problem_dir() + _p.get_sgte_cache_file();
141       if ( !_sgte_cache->load ( file_name , &m , display_degree==NOMAD::FULL_DISPLAY ) &&
142 			display_degree != NOMAD::NO_DISPLAY && display_degree != NOMAD::MINIMAL_DISPLAY )
143 	out << std::endl << "Warning (" << "Evaluator_Control.cpp" << ", " << __LINE__
144 	    << "): could not load (or create) the surrogate cache file "
145 	    << file_name << std::endl << std::endl;
146     }
147 
148 #ifdef MODEL_STATS
149     if ( _p.has_model_search() ||
150 	 ( _model_eval_sort &&
151 	   _p.get_model_eval_sort() != NOMAD::NO_MODEL ) ) {
152       out << std::endl
153 	  << "MODEL_STATS is active. Displayed model stats are:"
154 	  << std::endl
155 	  << "mode ell nY wY cond";
156       if ( _p.has_constraints() )
157 	out << " h mh eh";
158       out << " f mf ef" << std::endl
159 	  << NOMAD::open_block()
160 	  << "mode: model search (1) or model ordering (2)" << std::endl
161 	  << "ell : mesh_index"                             << std::endl
162 	  << "nY  : cardinality of the interpolation set Y" << std::endl
163 	  << "wY  : width of Y"                             << std::endl
164 	  << "cond: Y condition number"                     << std::endl;
165       if ( _p.has_constraints() )
166 	out << "h   : h value"           << std::endl
167 	    << "mh  : model value for h" << std::endl
168 	    << "eh  : relative error(%)" << std::endl;
169       out << "f   : f value"             << std::endl
170 	  << "mf  : model value for f"   << std::endl
171 	  << "ef  : relative error(%)"   << std::endl
172 	  << NOMAD::close_block()        << std::endl;
173     }
174 #endif
175   }
176 }
177 
178 /*---------------------------------------------------------*/
179 /*                        destructor                       */
180 /*---------------------------------------------------------*/
~Evaluator_Control(void)181 NOMAD::Evaluator_Control::~Evaluator_Control ( void )
182 {
183   if ( _del_ev )
184     delete _ev;
185 
186   if ( _del_cache )
187     delete _cache;
188 
189   if ( _del_sgte_cache )
190     delete _sgte_cache;
191 
192   clear_eval_lop();
193 
194 #ifdef USE_MPI
195 
196   if ( _eval_in_progress ) {
197     int np = NOMAD::Slave::get_nb_processes();
198     for ( int i = 0 ; i < np ; ++i )
199       if ( _eval_in_progress[i] && !_eval_in_progress[i]->is_in_cache() )
200 	delete _eval_in_progress[i];
201     delete [] _eval_in_progress;
202   }
203   if ( _slaves_elop_tags )
204     delete [] _slaves_elop_tags;
205 
206   delete _slave;
207 
208 #endif
209 }
210 
211 /*---------------------------------------------------------*/
212 /*                           reset                         */
213 /*---------------------------------------------------------*/
reset(void)214 void NOMAD::Evaluator_Control::reset ( void )
215 {
216   _last_stats_tag = _last_stats_bbe = -1;
217 #ifdef USE_TGP
218   _last_TGP_model = NULL;
219 #endif
220 }
221 
222 /*---------------------------------------------------------*/
223 /*                     save the caches                     */
224 /*---------------------------------------------------------*/
save_caches(bool overwrite)225 bool NOMAD::Evaluator_Control::save_caches ( bool overwrite )
226 {
227   const NOMAD::Display    & out = _p.out();
228   NOMAD::dd_type display_degree = out.get_gen_dd();
229 
230   bool b1 = _cache->save      ( overwrite , display_degree == NOMAD::FULL_DISPLAY );
231   bool b2 = _sgte_cache->save ( overwrite , display_degree == NOMAD::FULL_DISPLAY );
232 
233   if ( !b1 && display_degree != NOMAD::NO_DISPLAY && display_degree != NOMAD::MINIMAL_DISPLAY)
234     out << std::endl << "Warning (" << "Evaluator_Control.cpp" << ", " << __LINE__
235 	<< "): could not save the cache file "
236 	<< _p.get_problem_dir() << _p.get_cache_file()
237 	<< std::endl << std::endl;
238 
239   if ( !b2 && display_degree != NOMAD::NO_DISPLAY && display_degree != NOMAD::MINIMAL_DISPLAY)
240     out << std::endl
241 	<< "Warning (" << "Evaluator_Control.cpp" << ", " << __LINE__
242 	<< "): could not save the surrogate cache file "
243 	<< _p.get_problem_dir() << _p.get_sgte_cache_file()
244 	<< std::endl << std::endl;
245   return b1 && b2;
246 }
247 
248 /*---------------------------------------------------------*/
249 /*    process an already evaluated Eval_Point (private)    */
250 /*---------------------------------------------------------*/
process_eval_point(const NOMAD::Eval_Point & x,NOMAD::Barrier & barrier,NOMAD::Pareto_Front * pareto_front) const251 void NOMAD::Evaluator_Control::process_eval_point
252 ( const NOMAD::Eval_Point & x            ,
253   NOMAD::Barrier          & barrier      ,
254   NOMAD::Pareto_Front     * pareto_front ) const
255 {
256   // insertion of the Eval_Point in the barriers:
257   barrier.insert(x);
258 
259   if ( x.get_eval_type() == NOMAD::TRUTH || _p.get_opt_only_sgte() )
260   {
261 
262     // multi-objective:
263     if ( pareto_front )
264 	{
265 
266       // insertion of the Eval_Point in the Pareto front:
267       if ( x.is_feasible ( _p.get_h_min() ) &&
268 		  pareto_front->insert ( x )       &&
269 		  _p.get_user_calls_enabled()         )
270 			_ev->update_success ( _stats , x );
271 
272     }
273 
274     // single-objective: call virtual method Evaluator::update_success():
275     else if ( _p.get_user_calls_enabled() &&
276 	      barrier.get_one_eval_succ() == NOMAD::FULL_SUCCESS )
277       _ev->update_success ( _stats , x );
278   }
279 }
280 
281 /*---------------------------------------------------------*/
282 /*  update barrier b1 from points in barrier b2 and treat  */
283 /*  these points as evaluations (used in VNS search)       */
284 /*---------------------------------------------------------*/
process_barrier_points(NOMAD::Barrier & b1,const NOMAD::Barrier & b2,NOMAD::Pareto_Front * pareto_front,NOMAD::dd_type display_degree,NOMAD::search_type search) const285 NOMAD::success_type NOMAD::Evaluator_Control::process_barrier_points
286 ( NOMAD::Barrier       & b1             ,
287   const NOMAD::Barrier & b2             ,
288   NOMAD::Pareto_Front  * pareto_front   ,
289   NOMAD::dd_type         display_degree ,
290   NOMAD::search_type     search           ) const
291 {
292 	b1.reset_success();
293 
294 	NOMAD::Eval_Point                       *	modifiable_x;
295 	NOMAD::success_type							one_eval_succ;
296 	const NOMAD::Eval_Point                 *	last_success  = NULL;
297 	const std::list<const NOMAD::Eval_Point *>	& all_inserted  = b2.get_all_inserted();
298 	std::list<const NOMAD::Eval_Point *>::const_iterator it , end = all_inserted.end();
299 	for ( it = all_inserted.begin() ; it != end ; ++it )
300 	{
301 
302 		// insertion in barrier:
303 		modifiable_x = &NOMAD::Cache::get_modifiable_point ( **it );
304 
305 		modifiable_x->set_direction          ( NULL                              );
306 		modifiable_x->set_poll_center_type   ( NOMAD::UNDEFINED_POLL_CENTER_TYPE );
307 		modifiable_x->set_user_eval_priority ( NOMAD::Double()                   );
308 		modifiable_x->set_rand_eval_priority ( NOMAD::Double()                   );
309 
310 		// process evaluation point:
311 		process_eval_point ( **it , b1 , pareto_front );
312 
313 		one_eval_succ = b1.get_one_eval_succ();
314 		if ( one_eval_succ != NOMAD::UNSUCCESSFUL && one_eval_succ >= b1.get_success() )
315 			last_success = *it;
316 
317 	}
318 
319 	NOMAD::success_type success = b1.get_success();
320 
321 	// display and save only the last success:
322 	if ( last_success && display_degree == NOMAD::FULL_DISPLAY)
323 		display_eval_result ( *last_success  ,
324 							 display_degree ,
325 							 search         ,
326 							 success        ,
327 							 success          );
328 
329 	// barrier update:
330 	b1.update_and_reset_success();
331 
332 	return success;
333 }
334 
335 /*---------------------------------------------------------*/
336 /*      count the output stats (STAT_SUM and STAT_AVG)     */
337 /*      (private)                                          */
338 /*---------------------------------------------------------*/
count_output_stats(const NOMAD::Eval_Point & x)339 void NOMAD::Evaluator_Control::count_output_stats ( const NOMAD::Eval_Point & x )
340 {
341   const NOMAD::Point & bbo   = x.get_bb_outputs();
342   int                  i_sum = _p.get_index_stat_sum();
343   int                  i_avg = _p.get_index_stat_avg();
344 
345   // STAT_SUM:
346   if ( i_sum >= 0 )
347     _stats.update_stat_sum ( bbo[i_sum] );
348 
349   // STAT_AVG:
350   if ( i_avg >= 0 )
351     _stats.update_stat_avg ( bbo[i_avg] );
352 }
353 
354 /*-------------------------------------------------------------------*/
355 /*                file displays for parameter STATS_FILE             */
356 /*-------------------------------------------------------------------*/
stats_file(const std::string & file_name,const NOMAD::Eval_Point * x,bool feasible,const NOMAD::Point * multi_obj) const357 void NOMAD::Evaluator_Control::stats_file ( const std::string       & file_name ,
358 					    const NOMAD::Eval_Point * x         ,
359 					    bool                      feasible  ,
360 					    const NOMAD::Point      * multi_obj   ) const
361 {
362   std::string   fn = _p.get_problem_dir() + file_name;
363   std::ofstream fout ( fn.c_str() , std::ios::app );
364 
365   if ( !fout.fail() )
366   {
367     fout.setf      ( std::ios::fixed             );
368     fout.precision ( NOMAD::DISPLAY_PRECISION_BB );
369     display_stats  ( false , fout , _p.get_stats_file() , x , feasible , multi_obj );
370   }
371   else
372   {
373     const NOMAD::Display & out = _p.out();
374     if ( out.get_gen_dd() != NOMAD::NO_DISPLAY && out.get_gen_dd() != NOMAD::MINIMAL_DISPLAY)
375       out << std::endl
376 	  << "Warning (" << "Evaluator_Control.cpp" << ", " << __LINE__
377 	  << "): could not save information in stats file \'"
378 	  << file_name << "\'" << std::endl << std::endl;
379   }
380   fout.close();
381 }
382 
383 /*-------------------------------------------------------------------*/
384 /*  display stats during Mads::run() for minimal and normal display  */
385 /*-------------------------------------------------------------------*/
display_stats(bool header,const NOMAD::Display & out,const std::list<std::string> & stats,const NOMAD::Eval_Point * x,bool feasible,const NOMAD::Point * multi_obj) const386 void NOMAD::Evaluator_Control::display_stats
387 ( bool                           header    ,
388   const NOMAD::Display         & out       ,
389   const std::list<std::string> & stats     ,
390   const NOMAD::Eval_Point      * x         ,
391   bool                           feasible  ,
392   const NOMAD::Point           * multi_obj   ) const
393 {
394 	if ( stats.empty() )
395 	{
396 #ifndef R_VERSION
397 		out << std::endl;
398 #endif
399 		return;
400 	}
401 
402 	if ( header )
403 	{
404 #ifndef R_VERSION
405 		out << std::endl;
406 #endif
407 	}
408 
409 	NOMAD::Double            f;
410 	const NOMAD::Point     * sol		= NULL;
411 	const NOMAD::Point     * bbo		= NULL;
412 	const NOMAD::Signature * signature	= NULL;
413 	int                      bbe		= _stats.get_bb_eval();
414 	int						real_time	= _stats.get_real_time();
415 	int						blk_bbe		= _stats.get_block_eval();
416 	int                      i;
417 
418 	// this integer is used for the default width display
419 	// of the various stats on the number of evaluations:
420 	int max_bbe = _p.get_max_bb_eval();
421 	if ( _p.get_max_sgte_eval() > max_bbe )
422 		max_bbe = _p.get_max_sgte_eval();
423 	if ( _p.get_max_sim_bb_eval() > max_bbe )
424 		max_bbe = _p.get_max_sim_bb_eval();
425 	if ( _p.get_max_eval() > max_bbe )
426 		max_bbe = _p.get_max_eval();
427 
428 	if ( x )
429 	{
430 		signature       = x->get_signature();
431 		f               = (feasible) ? x->get_f() : NOMAD::INF;
432 		sol             = x;
433 		bbo             = &(x->get_bb_outputs());
434 
435 		if (bbe < _last_stats_bbe && ! multi_obj)
436 			return;
437 
438 		_last_stats_tag = x->get_tag();
439 		_last_stats_bbe = bbe;
440 	}
441 
442 
443 
444 	std::string s1 , format;
445 	std::list<std::string>::const_iterator it , end = stats.end();
446 	for ( it = stats.begin() ; it != end ; ++it )
447 	{
448 
449 		if ( it->empty() )
450 		{
451 #ifndef R_VERSION
452 			out << "\t";
453 #endif
454 		}
455 		else {
456 
457 			if ( header )
458 			{
459 #ifndef R_VERSION
460 				s1 = *it;
461 				NOMAD::Display::extract_display_format ( s1 , format );
462 				out << s1;
463 #endif
464 			}
465 
466 			else
467 			{
468 
469 				// get the stats type:
470 				NOMAD::display_stats_type dst
471 				= NOMAD::Display::get_display_stats_type ( *it );
472 
473 				// some stats types are disables in the multi-objective case:
474 				if ( multi_obj &&
475 					( dst == NOMAD::DS_SIM_BBE  ||
476 					 dst == NOMAD::DS_BBE      ||
477 					 dst == NOMAD::DS_SGTE     ||
478 					 dst == NOMAD::DS_EVAL     ||
479 					 dst == NOMAD::DS_TIME     ||
480 					 dst == NOMAD::DS_STAT_SUM ||
481 					 dst == NOMAD::DS_STAT_AVG    ) )
482 					dst = NOMAD::DS_UNDEFINED;
483 
484 				// display the stats:
485 				switch ( dst )
486                 {
487 					case NOMAD::DS_UNDEFINED:
488 						s1 = *it;
489 						NOMAD::Display::extract_display_format ( s1 , format );
490 						out << s1;
491 						break;
492 					case NOMAD::DS_OBJ:
493 						if ( multi_obj )
494 							display_stats_point ( out , stats , it , multi_obj );
495 						else
496                         {
497 #ifdef R_VERSION
498 							{
499 								std::ostringstream oss;
500 								display_stats_real ( oss , f , format );
501 								Rprintf ( "%s" , oss.str().c_str() );
502 							}
503 #else
504 							display_stats_real ( out , f , format );
505 #endif
506 							format.clear();
507 						}
508 						break;
509 					case NOMAD::DS_MESH_INDEX:
510 					{
511 						if ( signature )
512 						{
513 							NOMAD::Point mesh_indices=signature->get_mesh()->get_mesh_indices();
514 							display_stats_point ( out , stats , it , &mesh_indices );
515 						}
516 						else
517 							out << "-";
518 
519 
520 						break;
521 					}
522 					case NOMAD::DS_DELTA_M:
523 					case NOMAD::DS_MESH_SIZE:
524 					{
525 						if ( signature )
526 						{
527 							NOMAD::Point delta;
528 							signature->get_mesh()->get_delta ( delta );
529 							display_stats_point ( out , stats , it , &delta );
530 						}
531 						else
532 							out << "-";
533 					}
534 						break;
535 					case NOMAD::DS_DELTA_P:
536 					case NOMAD::DS_POLL_SIZE:
537 					{
538 						if ( signature )
539 						{
540 							NOMAD::Point Delta;
541 							signature->get_mesh()->get_Delta ( Delta );
542 							display_stats_point ( out , stats , it , &Delta );
543 
544 						}
545 						else
546 							out << "-";
547 					}
548 						break;
549 					case NOMAD::DS_SIM_BBE:
550 						display_stats_int ( out , _stats.get_sim_bb_eval() , max_bbe , format );
551 						format.clear();
552 						break;
553 					case NOMAD::DS_BBE:
554 
555 #ifdef R_VERSION
556 					{
557 							std::ostringstream oss;
558 							display_stats_int ( oss , bbe , max_bbe , format );
559 							Rprintf ( "\t%s " , oss.str().c_str() );
560 					}
561 #else
562 					{
563 							display_stats_int ( out , bbe , max_bbe , format );
564 					}
565 #endif
566 						format.clear();
567 						break;
568                     case NOMAD::DS_BLK_EVA:
569 					{
570 						display_stats_int ( out , blk_bbe , max_bbe , format );
571 					}
572 						format.clear();
573 						break;
574 
575 					case NOMAD::DS_SGTE:
576 						//display_stats_int ( out , sgte_bbe , max_bbe , format );
577 						 display_stats_int ( out , _stats.get_sgte_eval() , max_bbe , format );
578 						format.clear();
579 						break;
580 					case NOMAD::DS_EVAL:
581 						display_stats_int ( out , _stats.get_eval() , max_bbe , format );
582 						format.clear();
583 						break;
584 					case NOMAD::DS_TIME:
585 						display_stats_int ( out , real_time , 3600 , format );
586 						format.clear();
587 						break;
588 					case NOMAD::DS_STAT_SUM:
589 						display_stats_real ( out , _stats.get_stat_sum() , format );
590 						format.clear();
591 						break;
592 					case NOMAD::DS_STAT_AVG:
593 						display_stats_real ( out , _stats.get_stat_avg() , format );
594 						format.clear();
595 						break;
596 					case NOMAD::DS_BBO:
597 						display_stats_point ( out , stats , it , bbo );
598 						break;
599 					case NOMAD::DS_SOL:
600 						display_stats_point ( out , stats , it , sol , signature->get_input_type() );
601 						break;
602 					case NOMAD::DS_VAR:
603 						++it;
604 						NOMAD::atoi ( *it , i );
605 						if ( sol )
606 							if (format.empty())
607 								display_stats_type ( out , (*sol)[i] , (signature->get_input_type())[i] );
608 							else
609 								display_stats_real ( out , (*sol)[i] , format );
610 							else
611 								out << "-";
612 						format.clear();
613 						break;
614 				}
615 			}
616 		}
617 	}
618 
619 	if ( !header )
620 #ifdef R_VERSION
621 		Rprintf("\n");
622 #else
623 	out << std::endl;
624 #endif
625 }
626 
627 /*-----------------------------------------------------*/
628 /*  display a number with type                         */
629 /*-----------------------------------------------------*/
display_stats_type(const NOMAD::Display & out,const NOMAD::Double & d,const NOMAD::bb_input_type & bbType) const630 void NOMAD::Evaluator_Control::display_stats_type
631 ( const NOMAD::Display        & out    ,
632   const NOMAD::Double         & d      ,
633   const NOMAD::bb_input_type  & bbType ) const
634 {
635 
636 	// Default based on bbType
637 	std::string format2;
638 	switch (bbType)
639 	{
640 		case NOMAD::CONTINUOUS:
641 			format2 = "%0." + NOMAD::itos(DISPLAY_PRECISION_STD) + "g";
642 			break;
643 		case NOMAD::INTEGER || NOMAD::BINARY || NOMAD::CATEGORICAL:
644 			format2 = "%i";
645 			break;
646 		default:
647 			break;
648 	}
649 	d.display ( out , format2 );
650 
651 }
652 
653 /*-----------------------------------------------------*/
654 /*  display a real with DISPLAY_STATS (or STATS_FILE)  */
655 /*-----------------------------------------------------*/
display_stats_real(const NOMAD::Display & out,const NOMAD::Double & d,const std::string & format) const656 void NOMAD::Evaluator_Control::display_stats_real
657 ( const NOMAD::Display & out    ,
658  const NOMAD::Double  & d      ,
659  const std::string    & format ) const
660 {
661 	if ( format.empty() )
662 	{
663 		std::string format2 = "%0." + NOMAD::itos(DISPLAY_PRECISION_STD) + "g";
664 		d.display ( out , format2 );
665 	}
666 	else
667 		d.display ( out , format );
668 }
669 
670 
671 /*---------------------------------------------------------*/
672 /*  display an integer with DISPLAY_STATS (or STATS_FILE)  */
673 /*---------------------------------------------------------*/
display_stats_int(const NOMAD::Display & out,int i,int max_i,const std::string & format) const674 void NOMAD::Evaluator_Control::display_stats_int
675 ( const NOMAD::Display & out    ,
676   int                    i      ,
677   int                    max_i  ,
678   const std::string    & format   ) const
679 {
680   if ( format.empty() )
681     out.display_int_w ( i , max_i );
682   else {
683     NOMAD::Double d = i;
684     d.display ( out , format );
685   }
686 }
687 
688 /*---------------------------------------------------------*/
689 /*    display a point with DISPLAY_STATS (or STATS_FILE)   */
690 /*---------------------------------------------------------*/
display_stats_point(const NOMAD::Display & out,const std::list<std::string> & display_stats,std::list<std::string>::const_iterator & it,const NOMAD::Point * x,const std::vector<NOMAD::bb_input_type> & bbType) const691 void NOMAD::Evaluator_Control::display_stats_point
692 ( const NOMAD::Display                      & out           ,
693   const std::list<std::string>              & display_stats ,
694   std::list<std::string>::const_iterator    & it            ,
695   const NOMAD::Point                        * x             ,
696   const std::vector<NOMAD::bb_input_type>   & bbType        ) const
697 {
698   if ( x )
699   {
700 
701     unsigned int n = x->size() , bbn = static_cast<int>(bbType.size());
702 
703 	if ( bbn!=0 && n != bbn )
704 		  throw NOMAD::Exception ( "Evaluator_Control.cpp" , __LINE__ ,
705 								  "Evaluator_Control::display_stats_point(): bbType and x have different size" );
706 
707 
708     // s1 is the string displayed befores and after
709     // one coordinate (it may include format):
710     std::string s1;
711     if ( it != display_stats.begin() )
712 	{
713       s1 = *(--it);
714       ++it;
715     }
716 
717     // extract the display format from s1:
718     std::string format;
719     if ( !s1.empty() )
720       NOMAD::Display::extract_display_format ( s1 , format );
721 
722     // s2 is the string displayed between two coordinates:
723     std::string s2;
724     ++it;
725     if ( it != display_stats.end() )
726       s2 = *it;
727     else if ( s2.empty() )
728       --it;
729 
730     for ( unsigned int i = 0 ; i < n ; ++i )
731 	{
732 		if ( !s1.empty() && i > 0 )
733 			out << s1;
734 
735 		if (bbn!=0 && format.empty())
736 			display_stats_type ( out , (*x)[i] , bbType[i]);
737 		else
738 			display_stats_real (out, (*x)[i] , format );
739 
740 		if ( !s1.empty() )
741 			out << s1;
742 		if ( !s2.empty() && i < n-1  && s2.find("(VNS)")==std::string::npos && s2.find("(PhaseOne)")==std::string::npos && s2.find("(LH)")==std::string::npos && s2.find("(ExtendedPoll)")==std::string::npos )
743 			out << " " << s2;
744 		out << " ";
745     }
746 	if ( !s2.empty() && (s2.find("(VNS)")!=std::string::npos || s2.find("(PhaseOne)")!=std::string::npos || s2.find("(LH)")!=std::string::npos || s2.find("(ExtendedPoll)")!=std::string::npos))
747 		out << s2;
748   }
749 }
750 
751 /*------------------------------------------*/
752 /*  save the solution file (SOLUTION_FILE)  */
753 /*------------------------------------------*/
write_solution_file(const NOMAD::Eval_Point & x,bool display_bimv) const754 void NOMAD::Evaluator_Control::write_solution_file ( const NOMAD::Eval_Point & x,
755 													 bool display_bimv) const
756 {
757   const std::string & sol_file = _p.get_solution_file();
758   if ( !sol_file.empty() && ( x.is_feasible ( _p.get_h_min() ) || display_bimv ) )
759     write_sol_or_his_file ( _p.get_problem_dir() + sol_file , x , true , display_bimv );
760 }
761 
762 /*----------------------------------------------*/
763 /*     save the solution file  (SOLUTION_FILE)  */
764 /*  or update the history file (HISTORY_FILE )  */
765 /*  (private)                                   */
766 /*----------------------------------------------*/
write_sol_or_his_file(const std::string & file_name,const NOMAD::Eval_Point & x,bool is_sol,bool display_bimv) const767 void NOMAD::Evaluator_Control::write_sol_or_his_file
768 ( const std::string       & file_name ,
769   const NOMAD::Eval_Point & x         ,
770   bool                      is_sol    ,
771   bool						display_bimv ) const
772 {
773 	// if is_sol == true: save the solution file
774 	//              else: update the history file
775 	bool          failed = false;
776 	std::ofstream fout;
777 
778 	if ( is_sol )
779 		fout.open ( file_name.c_str() );
780 	else
781 		fout.open ( file_name.c_str() , std::ios::app );
782 
783 	if ( !fout.fail() ) {
784 
785 		fout.setf      ( std::ios::fixed             );
786 		fout.precision ( NOMAD::DISPLAY_PRECISION_BB );
787 
788 		// solution display:
789 		if ( is_sol )
790 		{
791 			if ( _p.get_bb_input_include_seed() )
792 				fout << _p.get_seed() << std::endl;
793 			if ( _p.get_bb_input_include_tag() )
794 				fout << x.get_tag() << std::endl;
795 			x.Point::display ( fout , "\n" , -1 , -1 );
796 			if (display_bimv)
797 				fout << std::endl << "warning: best infeasible solution (min. violation)";
798 			fout << std::endl;
799 		}
800 
801 		// history display:
802 		else {
803 			x.Point::display ( fout , " " , -1 , -1 );
804 			fout << " ";
805 			x.get_bb_outputs().Point::display ( fout , " " , -1 , -1 );
806 			fout << std::endl;
807 		}
808 
809 		if ( fout.fail() )
810 			failed = true;
811 	}
812 	else
813 		failed = true;
814 
815 	fout.close();
816 
817 	if ( failed && _p.out().get_gen_dd() != NOMAD::NO_DISPLAY &&  _p.out().get_gen_dd() != NOMAD::MINIMAL_DISPLAY)
818 		_p.out() << std::endl
819 		<< "Warning (" << "Evaluator_Control.cpp" << ", " << __LINE__
820 		<< "): could not "
821 		<< ( is_sol ? "save the current solution" :
822 			"update the history" )
823 		<< " in \'"
824 		<< file_name << "\'" << std::endl << std::endl;
825 }
826 
827 
828 /*---------------------------------------------------------*/
829 /*             display evaluation result (private)         */
830 /*---------------------------------------------------------*/
display_eval_result(const NOMAD::Eval_Point & x,NOMAD::dd_type display_degree,NOMAD::search_type search,NOMAD::success_type one_eval_success,NOMAD::success_type success) const831 void NOMAD::Evaluator_Control::display_eval_result
832 ( const NOMAD::Eval_Point & x                ,
833  NOMAD::dd_type            display_degree   ,
834  NOMAD::search_type        search           ,
835  NOMAD::success_type       one_eval_success ,
836  NOMAD::success_type       success            ) const
837 {
838 	const NOMAD::Display & out = _p.out();
839 	int cur_bbe;
840 
841 	// surrogate evaluation:
842 	if ( x.get_eval_type() == NOMAD::SGTE )
843 	{
844 		if ( display_degree == NOMAD::FULL_DISPLAY )
845 		{
846 			out << std::endl << "point #" << x.get_tag() << " sgte eval: ";
847 			if ( x.is_eval_ok() )
848 			{
849 				out << "h=";
850 				if ( x.get_h().is_defined() )
851 					out << x.get_h();
852 				else
853 					out << "inf (extr. barrier)";
854 				out << " f=" << x.get_f();
855 			}
856 			else
857 				out << "failed";
858 			out << std::endl;
859 		}
860 		if ( !_p.get_opt_only_sgte() )
861 			return;
862 
863 		cur_bbe = _stats.get_sgte_eval();
864 	}
865 	else
866 		cur_bbe = _stats.get_eval();
867 
868 	const std::string & stats_file_name = _p.get_stats_file_name();
869 	bool                feas_x          = x.is_feasible ( _p.get_h_min() );
870 
871 	// update the history file:
872 	// (contains surrogate evaluations if opt_only_sgte==true)
873 	const std::string & his_file = _p.get_history_file();
874 	if ( !his_file.empty() && cur_bbe > _last_history_bbe)
875 	{
876 		write_sol_or_his_file ( _p.get_problem_dir() + his_file , x , false );
877 		_last_history_bbe = cur_bbe;
878 	}
879 
880 	// success displays:
881 	if ( one_eval_success != NOMAD::UNSUCCESSFUL &&
882 		one_eval_success >= success )
883 	{
884 
885 		// save the current solution in file:
886 		write_solution_file ( x );
887 
888 		bool ds_ok = ( cur_bbe > _last_stats_bbe)	&&
889 					( _p.get_display_all_eval()		||
890 					( one_eval_success == NOMAD::FULL_SUCCESS && feas_x ) );
891 
892 		// normal display and minimal:
893 		if ( (display_degree == NOMAD::NORMAL_DISPLAY || display_degree == NOMAD::MINIMAL_DISPLAY ) && ds_ok )
894 			display_stats ( false , out , _p.get_display_stats() , &x , feas_x , NULL );
895 		// detailed display:
896 		else if ( display_degree == NOMAD::FULL_DISPLAY )
897 			out << std::endl << search << " " << one_eval_success
898 			<< " point " << x;
899 
900 		// stats file:
901 		if ( ds_ok && !stats_file_name.empty() )
902 			stats_file ( stats_file_name , &x , feas_x , NULL );
903 
904 	}
905 	else
906 	{
907 
908 		if ( display_degree == NOMAD::FULL_DISPLAY )
909 		{
910 			out << search << " " << one_eval_success
911 			<< " point #" << x.get_tag();
912 			if ( x.is_eval_ok() )
913 				out << " [ h=" << x.get_h()
914 				<< " f=" << x.get_f() << " ]" << std::endl;
915 			else if (x.check_rejected())
916 				out << ": evaluation rejected by user (this may alter convergence properties!)" << std::endl;
917 			else
918 				out << ": evaluation failed (you may need to check the source of the problem)." << std::endl;
919 		}
920 
921 		if ( _p.get_display_all_eval() && cur_bbe > _last_stats_bbe  )
922 		{
923 
924 			if ( display_degree == NOMAD::NORMAL_DISPLAY || display_degree == NOMAD::MINIMAL_DISPLAY )
925 				display_stats ( false , out , _p.get_display_stats() , &x , feas_x , NULL );
926 
927 			if ( !stats_file_name.empty() )
928 				stats_file ( stats_file_name , &x , feas_x , NULL );
929 		}
930 	}
931 }
932 
933 
934 /*-------------------------------------------*/
935 /*        search a point in the cache        */
936 /*-------------------------------------------*/
937 /* . return true if the point is in cache    */
938 /* . private method                          */
939 /*-------------------------------------------*/
cache_check(const NOMAD::Eval_Point * & x,NOMAD::Barrier & true_barrier,NOMAD::Barrier & sgte_barrier,NOMAD::Pareto_Front * pareto_front,bool & count_eval,const NOMAD::Double & h_max,NOMAD::dd_type display_degree) const940 bool NOMAD::Evaluator_Control::cache_check
941 ( const NOMAD::Eval_Point *& x              ,
942   NOMAD::Barrier           & true_barrier   ,
943   NOMAD::Barrier           & sgte_barrier   ,
944   NOMAD::Pareto_Front      * pareto_front   ,
945   bool                     & count_eval     ,
946   const NOMAD::Double      & h_max          ,
947   NOMAD::dd_type             display_degree   ) const
948 {
949     NOMAD::eval_type          x_eval_type = x->get_eval_type();
950     const NOMAD::Eval_Point * cache_x     = NULL;
951 
952     // first cache check:
953     if ( x->is_in_cache() )
954         cache_x = x;
955     // second cache check:
956     else
957         cache_x = ( ( x->get_eval_type() == NOMAD::TRUTH ) ?
958                    _cache : _sgte_cache )->find ( *x );
959 
960     // cache hit: transfer some data from x to cache_x:
961     if ( cache_x )
962     {
963 
964         if ( x_eval_type != cache_x->get_eval_type() )
965             throw NOMAD::Exception ( "Evaluator_Control.cpp" , __LINE__ ,
966                                     "Evaluator_Control::cache_check(): eval and cache pts have different eval_type" );
967 
968         if ( cache_x->is_eval_ok() )
969         {
970 
971             NOMAD::Eval_Point * modifiable_cache_x
972             = &NOMAD::Cache::get_modifiable_point ( *cache_x );
973 
974             // if wrong number of outputs, reset cache_x._bb_outputs:
975             {
976                 int m = _p.get_bb_nb_outputs();
977                 if ( cache_x->get_bb_outputs().size() != m )
978                     modifiable_cache_x->set_bb_output ( NOMAD::Point ( m ) );
979             }
980 
981             modifiable_cache_x->set_signature          ( x->get_signature         () );
982             modifiable_cache_x->set_direction          ( x->get_direction         () );
983             modifiable_cache_x->set_poll_center        ( x->get_poll_center       () );
984             modifiable_cache_x->set_poll_center_type   ( x->get_poll_center_type  () );
985             modifiable_cache_x->set_user_eval_priority ( x->get_user_eval_priority() );
986             modifiable_cache_x->set_rand_eval_priority ( x->get_rand_eval_priority() );
987 
988 #ifdef MODEL_STATS
989             modifiable_cache_x->set_model_data ( *x );
990 #endif
991 
992             // set_f, set_h, and set_EB_ok:
993             _ev->compute_f ( *modifiable_cache_x );
994             _ev->compute_h ( *modifiable_cache_x );
995         }
996     }
997 
998     // point in cache but evaluation is to be made again:
999     if ( cache_x && cache_x->is_eval_ok() &&
1000         ( !cache_x->get_f().is_defined() ||
1001          ( cache_x->is_EB_ok()                      &&
1002           !cache_x->get_bb_outputs().is_complete() &&
1003           cache_x->get_h().is_defined()            &&
1004           cache_x->get_h() < h_max                    ) ) )
1005     {
1006              x       = cache_x;
1007              cache_x = NULL;
1008          }
1009 
1010     // point in cache:
1011     if ( cache_x )
1012     {
1013 
1014         _stats.add_cache_hit();
1015 
1016         // displays:
1017         if ( display_degree == NOMAD::FULL_DISPLAY )
1018         {
1019             const NOMAD::Display & out = _p.out();
1020             if ( cache_x->get_eval_type() == NOMAD::SGTE )
1021                 out << "surrogate ";
1022             out << "cache hit: #" << x->get_tag()
1023             << " --> #" << cache_x->get_tag() << std::endl;
1024         }
1025 
1026         // process the Eval_Point taken in cache:
1027         process_eval_point ( *cache_x ,
1028                             ( cache_x->get_eval_type() == NOMAD::TRUTH ) ?
1029                             true_barrier : sgte_barrier ,
1030                             pareto_front );
1031 
1032         // count the (simulated) bb eval ?
1033         int index_cnt_eval = _p.get_index_cnt_eval();
1034         if ( index_cnt_eval >= 0 && cache_x->get_bb_outputs()[index_cnt_eval] == 0.0 )
1035             count_eval = false;
1036 
1037         x = cache_x;
1038 
1039         return true;
1040     }
1041 
1042     return false;
1043 }
1044 
1045 /*----------------------------------------------------*/
1046 /*                 eval a point (private)             */
1047 /*----------------------------------------------------*/
eval_point(NOMAD::Eval_Point & x,NOMAD::Barrier & true_barrier,NOMAD::Barrier & sgte_barrier,NOMAD::Pareto_Front * pareto_front,bool & count_eval,bool & stop,NOMAD::stop_type & stop_reason,const NOMAD::Double & h_max)1048 void NOMAD::Evaluator_Control::eval_point ( NOMAD::Eval_Point       & x            ,
1049 					    NOMAD::Barrier          & true_barrier ,
1050 					    NOMAD::Barrier          & sgte_barrier ,
1051 					    NOMAD::Pareto_Front     * pareto_front ,
1052 					    bool                    & count_eval   ,
1053 					    bool                    & stop         ,
1054 					    NOMAD::stop_type        & stop_reason  ,
1055 					    const NOMAD::Double     & h_max          )
1056 {
1057 	int max_bb_eval   = _p.get_max_bb_eval();
1058 	int max_sgte_eval = _p.get_max_sgte_eval();
1059 
1060 	// blackbox or surrogate evaluations are allowed:
1061 	if ( ( x.get_eval_type() == NOMAD::TRUTH && max_bb_eval   != 0 ) ||
1062 		( x.get_eval_type() == NOMAD::SGTE  && max_sgte_eval != 0 )    )
1063 	{
1064 
1065 		NOMAD::Eval_Point * eval_x = &NOMAD::Cache::get_modifiable_point ( x );
1066 
1067 		// get the signature:
1068 		NOMAD::Signature * signature = x.get_signature();
1069 		if ( !signature )
1070 			throw NOMAD::Exception ( "Evaluator_Control.cpp" , __LINE__ ,
1071 									"Evaluator_Control::eval_point(): the point has no signature" );
1072 
1073 		// evaluation of the point:
1074 		// ------------------------
1075 		bool eval_ok = true;
1076 
1077         NOMAD::Evaluator_Control::_force_evaluation_failure=false;
1078 
1079 		{
1080 			// 1. scaling:
1081 			bool do_scaling = signature->get_scaling().is_defined();
1082 			if ( do_scaling )
1083 				eval_x->scale();
1084 
1085 			// 2.1. evaluation:
1086 			try
1087 			{
1088 				eval_ok = _ev->eval_x ( *eval_x , h_max , count_eval );
1089 
1090 			}
1091             catch ( exception & e )
1092             {
1093                 throw NOMAD::Exception ( "Evaluator_control.cpp" , __LINE__ , e.what() );
1094             }
1095 
1096 
1097 			// 2.2. check the nan's:
1098 			if ( eval_ok && eval_x->check_nan() )
1099 				eval_ok = false;
1100 
1101             if ( _force_evaluation_failure )
1102                 eval_ok = false;
1103 
1104 			// 3. unscaling:
1105 			if ( do_scaling )
1106 				eval_x->unscale();
1107 		}
1108 
1109 		if ( eval_ok )
1110 		{
1111 
1112 			eval_x->set_eval_status ( NOMAD::EVAL_OK );
1113 
1114 			// set_f, set_h and set_EB_ok:
1115 			_ev->compute_f ( *eval_x );
1116 			_ev->compute_h ( *eval_x );
1117 
1118 		}
1119 		else
1120 		{
1121 			eval_x->set_eval_status ( NOMAD::EVAL_FAIL );
1122 			_stats.add_failed_eval();
1123 		}
1124 
1125 		// insertion in cache even if is_eval_ok == false:
1126 		if ( !x.is_in_cache() )
1127 		{
1128 
1129 			int size_before , size_after;
1130 
1131 			if ( x.get_eval_type() == NOMAD::SGTE ) {
1132 				size_before = _sgte_cache->size();
1133 				_sgte_cache->insert(x);
1134 				size_after  = _sgte_cache->size();
1135 			}
1136 			else {
1137 				size_before = _cache->size();
1138 				_cache->insert(x);
1139 				size_after  = _cache->size();
1140 			}
1141 
1142 			if ( size_after == size_before )
1143 				x.set_in_cache ( false );
1144 		}
1145 
1146 	}
1147 
1148 }
1149 
1150 
1151 /*----------------------------------------------------*/
1152 /*                 eval points in a list (private)    */
1153 /*----------------------------------------------------*/
eval_points(std::list<NOMAD::Eval_Point * > & list_eval,NOMAD::Barrier & true_barrier,NOMAD::Barrier & sgte_barrier,NOMAD::Pareto_Front * pareto_front,std::list<bool> & count_list_eval,bool & stop,NOMAD::stop_type & stop_reason,const NOMAD::Double & h_max)1154 void NOMAD::Evaluator_Control::eval_points ( std::list<NOMAD::Eval_Point *>	& list_eval		,
1155 											NOMAD::Barrier					& true_barrier	,
1156 											NOMAD::Barrier					& sgte_barrier	,
1157 											NOMAD::Pareto_Front				* pareto_front	,
1158 											std::list<bool>					& count_list_eval,
1159 											bool							& stop			,
1160 											NOMAD::stop_type				& stop_reason	,
1161 											const NOMAD::Double				& h_max          )
1162 {
1163 	int max_bb_eval   = _p.get_max_bb_eval();
1164 	int max_sgte_eval = _p.get_max_sgte_eval();
1165 
1166 	std::list<NOMAD::Eval_Point*>::iterator it_begin=list_eval.begin();
1167 
1168 	if ( ( (*it_begin)->get_eval_type() == NOMAD::TRUTH && max_bb_eval   != 0 ) ||
1169 		( (*it_begin)->get_eval_type() == NOMAD::SGTE  && max_sgte_eval != 0 )    )
1170 	{
1171 
1172 		// 1. Pre-evaluation tests and scaling
1173 		for ( std::list<NOMAD::Eval_Point*>::iterator it=it_begin;it!=list_eval.end();++it)
1174 		{
1175 			// get the signature:
1176 			NOMAD::Signature * signature = (*it)->get_signature();
1177 			if ( !signature )
1178 				throw NOMAD::Exception ( "Evaluator_Control.cpp" , __LINE__ ,
1179 										"Evaluator_Control::eval_points(): the point has no signature" );
1180 
1181 			// Scaling before evaluation of the points:
1182 			bool do_scaling = signature->get_scaling().is_defined();
1183 			if ( do_scaling )
1184 				(*it)->scale();
1185 
1186 		}
1187 
1188 		// 2. list evaluation:
1189 		bool eval_list_ok = true;
1190         NOMAD::Evaluator_Control::_force_evaluation_failure=false;
1191 
1192 		try
1193 		{
1194 			eval_list_ok=_ev->eval_x ( list_eval , h_max,count_list_eval );
1195 		}
1196         catch ( exception & e )
1197         {
1198             throw NOMAD::Exception ( "Evaluator_control.cpp" , __LINE__ , e.what() );
1199         }
1200 
1201         if ( _force_evaluation_failure )
1202             eval_list_ok = false;
1203 
1204 
1205 		// One block of evaluations is counted
1206 		if ( eval_list_ok )
1207 			_stats.add_one_block_eval();
1208 
1209 
1210 
1211 		// 3. Post list evaluation checks and operation
1212 		std::list<bool>::iterator it_count=count_list_eval.begin();
1213 		for ( std::list<NOMAD::Eval_Point*>::iterator it=it_begin;it!=list_eval.end();++it,++it_count)
1214 		{
1215 			bool eval_ok=true;
1216 			bool eval_rejected=false;
1217 
1218 			// 3.1. check the nan's and list evaluation failure:
1219 			if ( !eval_list_ok || (*it)->check_nan() )
1220 				eval_ok = false;
1221 
1222 			if ((*it)->check_rejected())
1223 			{
1224 				eval_rejected=true;
1225 				eval_ok=false;
1226 			}
1227 
1228 			// 3.2 unscaling:
1229 			if ( (*it)->get_signature()->get_scaling().is_defined() )
1230 				(*it)->unscale();
1231 
1232 
1233 			if ( eval_ok && (*it)->get_eval_status()!=NOMAD::EVAL_FAIL )
1234 			{
1235 				(*it)->set_eval_status ( NOMAD::EVAL_OK );
1236 
1237 				// set_f, set_h and set_EB_ok:
1238 				_ev->compute_f ( *(*it) );
1239 				_ev->compute_h ( *(*it));
1240 
1241 			}
1242 			else if (!eval_rejected)
1243 			{
1244 				(*it)->set_eval_status ( NOMAD::EVAL_FAIL );
1245 				_stats.add_failed_eval();
1246 			} // Do nothing if eval has been rejected
1247 
1248 			// insertion in cache even if is_eval_ok == false. Exception: a point that has been rejected by user is not put in the cache.
1249 			if ( !(*it)->is_in_cache() && !eval_rejected )
1250 			{
1251 
1252 				int size_before , size_after;
1253 
1254 				if ( (*it)->get_eval_type() == NOMAD::SGTE )
1255 				{
1256 					size_before = _sgte_cache->size();
1257 					_sgte_cache->insert(*(*it));
1258 					size_after  = _sgte_cache->size();
1259 				}
1260 				else
1261 				{
1262 					size_before = _cache->size();
1263 					_cache->insert(*(*it));
1264 					size_after  = _cache->size();
1265 				}
1266 
1267 				if ( size_after == size_before )
1268 					(*it)->set_in_cache ( false );
1269 			}
1270 
1271 
1272 			// count the output stats (STAT_SUM and STAT_AVG):
1273 			if ( (_p.check_stat_sum() || _p.check_stat_avg()) && !eval_rejected)
1274 				count_output_stats(*(*it));
1275 
1276 		}
1277 	}
1278 }
1279 
1280 
1281 
1282 /*-------------------------------------------*/
1283 /*      check stopping criteria (private)    */
1284 /*-------------------------------------------*/
check_stopping_criteria(NOMAD::search_type search,bool count_eval,const NOMAD::Eval_Point & x,bool & stop,NOMAD::stop_type & stop_reason) const1285 void NOMAD::Evaluator_Control::check_stopping_criteria
1286 ( NOMAD::search_type        search      ,
1287   bool                      count_eval  ,
1288   const NOMAD::Eval_Point & x           ,
1289   bool                    & stop        ,
1290   NOMAD::stop_type        & stop_reason   ) const
1291 {
1292 	// check the time:
1293 	if ( !stop                 &&
1294 		_p.get_max_time() > 0 &&
1295 		_stats.get_real_time() >= _p.get_max_time() )
1296 	{
1297 		stop        = true;
1298 		stop_reason = NOMAD::MAX_TIME_REACHED;
1299 	}
1300 
1301 	// count an evaluation or a simulated blackbox evaluation:
1302 	if ( x.get_eval_type() == NOMAD::TRUTH )
1303 	{
1304 		_stats.add_eval();
1305 		if ( count_eval && !x.get_current_run() )
1306 			_stats.add_sim_bb_eval();
1307 	}
1308 
1309 
1310 	// check STAT_SUM_TARGET:
1311 	if ( !stop	&&
1312 		(_p.check_stat_sum() || _p.check_stat_avg()))
1313 	{
1314 
1315 		NOMAD::Double sum_target = _p.get_stat_sum_target();
1316 		if ( sum_target.is_defined() )
1317 		{
1318 			NOMAD::Double sum = _stats.get_stat_sum();
1319 			if ( sum.is_defined() && sum >= sum_target )
1320 			{
1321 				stop        = true;
1322 				stop_reason = NOMAD::STAT_SUM_TARGET_REACHED;
1323 			}
1324 		}
1325 	}
1326 
1327 	// check the number of blackbox evaluations:
1328 	if ( !stop )
1329 	{
1330 		int max_bb_eval   = _p.get_max_bb_eval();
1331 		int max_sgte_eval = _p.get_max_sgte_eval();
1332 		if ( max_bb_eval > 0 && _stats.get_bb_eval() >= max_bb_eval )
1333 		{
1334 			stop        = true;
1335 			stop_reason = NOMAD::MAX_BB_EVAL_REACHED;
1336 		}
1337 		if ( max_sgte_eval > 0 && _stats.get_sgte_eval() >= max_sgte_eval )
1338 		{
1339 			stop        = true;
1340 			stop_reason = NOMAD::MAX_SGTE_EVAL_REACHED;
1341 		}
1342 	}
1343 
1344 	// check the stopping condition MAX_EVAL:
1345 	if ( !stop                 &&
1346 		_p.get_max_eval() > 0 &&
1347 		_stats.get_eval() >= _p.get_max_eval() )
1348 	{
1349 		stop        = true;
1350 		stop_reason = NOMAD::MAX_EVAL_REACHED;
1351 	}
1352 
1353 	// check the stopping condition MAX_SIM_BB_EVAL:
1354 	if ( !stop                         &&
1355 		_p.get_max_sim_bb_eval() >  0 &&
1356 		_stats.get_sim_bb_eval() >= _p.get_max_sim_bb_eval() )
1357 	{
1358 		stop        = true;
1359 		stop_reason = NOMAD::MAX_SIM_BB_EVAL_REACHED;
1360 	}
1361 
1362 	// check the stopping conditions F_TARGET and FEAS_REACHED
1363 	// (for phase one: the evaluations must stop if all EB
1364 	//  constraints are satisfied, but some PB constraints can
1365 	//  be violated)
1366 	if ( !stop          &&
1367 		x.is_eval_ok() &&
1368 		( _p.get_opt_only_sgte() ||
1369 		 x.get_eval_type() == NOMAD::TRUTH ) )
1370 	{
1371 
1372 		bool feasible = x.is_feasible ( _p.get_h_min() );
1373 
1374 		// check FEAS_REACHED:
1375 		if ( feasible && _p.get_stop_if_feasible() )
1376 		{
1377 			stop        = true;
1378 			stop_reason = NOMAD::FEAS_REACHED;
1379 		}
1380 
1381 		// check F_TARGET:
1382 		{
1383 			const NOMAD::Point           & f_target       = _p.get_f_target();
1384 			const std::list<int>         & index_obj      = _p.get_index_obj();
1385 			std::list<int>::const_iterator index_obj_end  = index_obj.end();
1386 			bool                           check_f_target = f_target.is_defined();
1387 			int                            nb_to_check    = (check_f_target) ?
1388 			f_target.nb_defined() : 0;
1389 
1390 			if ( check_f_target && ( feasible || search == NOMAD::LH_SEARCH_P1 ) )
1391 			{
1392 				const NOMAD::Point & bbo = x.get_bb_outputs();
1393 				bool                 chk = true;
1394 				int                  k   = 0;
1395 				int                  cnt = 0;
1396 				for ( std::list<int>::const_iterator it = index_obj.begin();
1397 					 it != index_obj_end ; ++it , ++k )
1398 				{
1399 					if ( bbo[*it].is_defined() && f_target[k].is_defined() )
1400 					{
1401 						if ( f_target[k] < bbo[*it] )
1402 						{
1403 							chk = false;
1404 							break;
1405 						}
1406 						cnt++;
1407 					}
1408 				}
1409 
1410 				if ( chk && cnt == nb_to_check )
1411 				{
1412 					stop        = true;
1413 					stop_reason = NOMAD::F_TARGET_REACHED;
1414 				}
1415 			}
1416 		}
1417 	}
1418 }
1419 
1420 /*-------------------------------------------------------*/
1421 /*  receive an evaluation result from a slave (private)  */
1422 /*-------------------------------------------------------*/
1423 #ifdef USE_MPI
receive_eval_result(NOMAD::search_type search,NOMAD::Eval_Point * x,NOMAD::Barrier & true_barrier,NOMAD::Barrier & sgte_barrier,NOMAD::Pareto_Front * pareto_front,int slave_rank,bool & stop,NOMAD::stop_type & stop_reason)1424 void NOMAD::Evaluator_Control::receive_eval_result
1425 ( NOMAD::search_type    search       ,
1426   NOMAD::Eval_Point   * x            ,
1427   NOMAD::Barrier      & true_barrier ,
1428   NOMAD::Barrier      & sgte_barrier ,
1429   NOMAD::Pareto_Front * pareto_front ,
1430   int                   slave_rank   ,
1431   bool                & stop         ,
1432   NOMAD::stop_type    & stop_reason    )
1433 {
1434   bool eval_ok , count_eval;
1435 
1436 
1437 	// receive the evaluation result:
1438   _slave->receive_eval_result ( slave_rank , x , eval_ok , count_eval );
1439 
1440   // process the evaluation:
1441   if ( eval_ok ) {
1442 
1443     // set_f, set_h and set_EB_ok:
1444     _ev->compute_f ( *x );
1445     _ev->compute_h ( *x );
1446 
1447     // process the evaluated point:
1448     process_eval_point ( *x                                    ,
1449 			 (x->get_eval_type()==NOMAD::TRUTH) ?
1450 			 true_barrier : sgte_barrier           ,
1451 			 pareto_front                            );
1452   }
1453   else
1454     _stats.add_failed_eval();
1455 
1456   // insertion in cache even if !eval_ok:
1457   if ( !x->is_in_cache() )
1458     ( ( x->get_eval_type() == NOMAD::SGTE ) ?
1459       _sgte_cache : _cache)->insert ( *x );
1460 
1461   // count the bb evaluation:
1462   if ( count_eval ) {
1463     if ( x->get_eval_type() == NOMAD::SGTE )
1464       _stats.add_sgte_eval();
1465     else
1466       _stats.add_bb_eval();
1467   }
1468 
1469   // count the output stats (STAT_SUM and STAT_AVG):
1470   if ( _p.check_stat_sum() || _p.check_stat_avg() ) {
1471 
1472     count_output_stats ( *x );
1473 
1474     // check STAT_SUM_TARGET:
1475     NOMAD::Double sum_target = _p.get_stat_sum_target();
1476     if ( sum_target.is_defined() ) {
1477       NOMAD::Double sum = _stats.get_stat_sum();
1478       if ( !stop && sum.is_defined() && sum >= sum_target ) {
1479 	stop        = true;
1480 	stop_reason = NOMAD::STAT_SUM_TARGET_REACHED;
1481       }
1482     }
1483   }
1484 
1485   // check stopping criteria:
1486   if ( !stop ) {
1487 
1488     int max_bb_eval   = _p.get_max_bb_eval();
1489     int max_sgte_eval = _p.get_max_sgte_eval();
1490 
1491     if ( max_bb_eval > 0 && _stats.get_bb_eval() >= max_bb_eval ) {
1492       stop        = true;
1493       stop_reason = NOMAD::MAX_BB_EVAL_REACHED;
1494     }
1495     if ( max_sgte_eval > 0 && _stats.get_sgte_eval() >= max_sgte_eval ) {
1496       stop        = true;
1497       stop_reason = NOMAD::MAX_SGTE_EVAL_REACHED;
1498     }
1499   }
1500 
1501   check_stopping_criteria ( search , count_eval , *x , stop , stop_reason );
1502 }
1503 #endif
1504 
1505 /*----------------------------------------------------*/
1506 /*          wait for evaluations in progress          */
1507 /*----------------------------------------------------*/
1508 #ifdef USE_MPI
wait_for_evaluations(NOMAD::search_type search,NOMAD::Barrier & true_barrier,NOMAD::Barrier & sgte_barrier,NOMAD::Pareto_Front * pareto_front,bool & stop,NOMAD::stop_type & stop_reason,NOMAD::success_type & success,std::list<const NOMAD::Eval_Point * > & evaluated_pts)1509 void NOMAD::Evaluator_Control::wait_for_evaluations
1510 ( NOMAD::search_type                     search         ,
1511   NOMAD::Barrier                       & true_barrier   ,
1512   NOMAD::Barrier                       & sgte_barrier   ,
1513   NOMAD::Pareto_Front                  * pareto_front   ,
1514   bool                                 & stop           ,
1515   NOMAD::stop_type                     & stop_reason    ,
1516   NOMAD::success_type                  & success        ,
1517   std::list<const NOMAD::Eval_Point *> & evaluated_pts    )
1518 {
1519 	if ( _nb_in_progress == 0 )
1520 		return;
1521 
1522 	// display degree:
1523 	const NOMAD::Display    & out = _p.out();
1524 	NOMAD::dd_type display_degree = out.get_display_degree ( search );
1525 
1526 	if ( display_degree == NOMAD::FULL_DISPLAY )
1527 		out << std::endl
1528 		<< NOMAD::open_block ( "wait for evaluations" );
1529 
1530 	NOMAD::Barrier     & barrier = ( _p.get_opt_only_sgte() ) ?
1531 	sgte_barrier : true_barrier;
1532 	char                 signal;
1533 	int                  source;
1534 	NOMAD::Eval_Point  * eval_x;
1535 	NOMAD::success_type  one_eval_success;
1536 
1537 	while ( _nb_in_progress > 0 )
1538 	{
1539 
1540 		source = NOMAD::Slave::receive_signal ( signal );
1541 		eval_x = _eval_in_progress[source];
1542 
1543 		if ( eval_x )
1544 		{
1545 
1546 			if ( display_degree == NOMAD::FULL_DISPLAY )
1547 				out << std::endl << "receive eval point #" << eval_x->get_tag()
1548 				<< " from slave " << source << std::endl << std::endl;
1549 
1550 			receive_eval_result ( search       ,
1551 								 eval_x       ,
1552 								 true_barrier ,
1553 								 sgte_barrier ,
1554 								 pareto_front ,
1555 								 source       ,
1556 								 stop         ,
1557 								 stop_reason    );
1558 
1559 			// list of processed points:
1560 			if ( eval_x->is_in_cache() )
1561 				evaluated_pts.push_back ( eval_x );
1562 
1563 			// success:
1564 			one_eval_success = barrier.get_one_eval_succ();
1565 			success          = barrier.get_success();
1566 
1567 			// asynchronous success count:
1568 			if ( success == NOMAD::FULL_SUCCESS &&
1569 				_elop_tag != _slaves_elop_tags[source] )
1570 				_stats.add_asynchronous_success();
1571 
1572 			// displays:
1573 			display_eval_result ( *eval_x          ,
1574 								 display_degree   ,
1575 								 search           ,
1576 								 one_eval_success ,
1577 								 success            );
1578 
1579 			if ( !_eval_in_progress[source]->is_in_cache() )
1580 				delete _eval_in_progress[source];
1581 			_eval_in_progress[source] = NULL;
1582 			_slaves_elop_tags[source] = -1;
1583 			--_nb_in_progress;
1584 
1585 			// force quit (by pressing ctrl-c):
1586 			if ( !stop && ( NOMAD::Evaluator_Control::_force_quit || NOMAD::Evaluator::get_force_quit() ) )
1587 			{
1588 				stop        = true;
1589 				stop_reason = NOMAD::CTRL_C;
1590 				break;
1591 			}
1592 
1593 			if ( stop && ( stop_reason==NOMAD::ERROR ||
1594 						  stop_reason==NOMAD::UNKNOWN_STOP_REASON ) )
1595 				break;
1596 		}
1597 		else
1598 			NOMAD::Slave::send_signal ( NOMAD::WAIT_SIGNAL , source );
1599 	}
1600 
1601 	if ( display_degree == NOMAD::FULL_DISPLAY )
1602 		out.close_block();
1603 }
1604 #endif
1605 
1606 /*----------------------------------------------------------------*/
1607 /*  check if the evaluation at this point is already in progress  */
1608 /*  (private)                                                     */
1609 /*----------------------------------------------------------------*/
1610 #ifdef USE_MPI
already_in_progress(const NOMAD::Eval_Point & x) const1611 bool NOMAD::Evaluator_Control::already_in_progress
1612 ( const NOMAD::Eval_Point & x ) const
1613 {
1614   if ( _eval_in_progress ) {
1615 
1616     int x_tag = x.get_tag();
1617     int np    = NOMAD::Slave::get_nb_processes();
1618 
1619     for ( int i = 0 ; i < np ; ++i )
1620       if ( _eval_in_progress[i] &&
1621 	   ( _eval_in_progress[i]->get_tag() == x_tag ||
1622 	     _eval_in_progress[i]->Point::operator == ( x ) ) )
1623 	return true;
1624   }
1625   return false;
1626 }
1627 #endif
1628 
1629 /*----------------------------------------------------------------*/
1630 /*     eval_list_of_points, private version (parallel version)    */
1631 /*----------------------------------------------------------------*/
1632 #ifdef USE_MPI
private_eval_list_of_points(NOMAD::search_type search,NOMAD::Barrier & true_barrier,NOMAD::Barrier & sgte_barrier,NOMAD::Pareto_Front * pareto_front,bool & stop,NOMAD::stop_type & stop_reason,const NOMAD::Eval_Point * & new_feas_inc,const NOMAD::Eval_Point * & new_infeas_inc,NOMAD::success_type & success,std::list<const NOMAD::Eval_Point * > & evaluated_pts)1633 void NOMAD::Evaluator_Control::private_eval_list_of_points
1634 ( NOMAD::search_type              search         ,   // IN     : search type
1635   NOMAD::Barrier                & true_barrier   ,   // IN/OUT : the barrier
1636   NOMAD::Barrier                & sgte_barrier   ,   // IN/OUT : the surrogate barrier
1637   NOMAD::Pareto_Front           * pareto_front   ,   // IN/OUT : the Pareto front
1638                                                      //          (can be NULL)
1639   bool                          & stop           ,   // IN/OUT : stopping criterion
1640   NOMAD::stop_type              & stop_reason    ,   // OUT    : stopping reason
1641   const NOMAD::Eval_Point      *& new_feas_inc   ,   // OUT    : new feasible incumbent
1642   const NOMAD::Eval_Point      *& new_infeas_inc ,   // OUT    : new infeas. incumbent
1643   NOMAD::success_type           & success        ,   // OUT    : type of success
1644   std::list<const NOMAD::Eval_Point *>
1645                                 & evaluated_pts    ) // OUT    : list of processed pts
1646 {
1647 	if ( stop || _eval_lop.empty() )
1648 	{
1649 		stop_reason = NOMAD::UNKNOWN_STOP_REASON;
1650 		++_elop_tag;
1651 		return;
1652 	}
1653 
1654 	evaluated_pts.clear();
1655 
1656 
1657 	// initial display:
1658 	const NOMAD::Display    & out = _p.out();
1659 	NOMAD::dd_type display_degree = out.get_display_degree ( search );
1660 
1661 	if ( display_degree == NOMAD::FULL_DISPLAY )
1662 	{
1663 		std::ostringstream msg;
1664 		msg << "list of points evaluation (" << search << ")";
1665 		out << std::endl << NOMAD::open_block ( msg.str() );
1666 	}
1667 
1668 	// call the Evaluator (virtual) preprocessing of a list of points:
1669 	_ev->list_of_points_preprocessing ( _eval_lop );
1670 
1671 	const NOMAD::Eval_Point * old_feasible_incumbent   = NULL;
1672 	const NOMAD::Eval_Point * old_infeasible_incumbent = NULL;
1673 
1674 	// active barrier:
1675 	NOMAD::Barrier & barrier = ( _p.get_opt_only_sgte() ) ?
1676     sgte_barrier : true_barrier;
1677 
1678 	old_feasible_incumbent   = barrier.get_best_feasible();
1679 	old_infeasible_incumbent = barrier.get_best_infeasible();
1680 
1681 	NOMAD::Double f0;
1682 	if ( _p.get_opportunistic_min_f_imprvmt().is_defined() &&
1683 		old_feasible_incumbent )
1684 		f0 = old_feasible_incumbent->get_f();
1685 
1686 	new_feas_inc   = NULL;
1687 	new_infeas_inc = NULL;
1688 	stop           = false;
1689 	success        = NOMAD::UNSUCCESSFUL;
1690 	stop_reason    = NOMAD::NO_STOP;
1691 
1692 	const NOMAD::Eval_Point  * x;
1693 	NOMAD::check_failed_type   check_failed_reason;
1694 	bool                       count_eval;
1695 	std::vector<const NOMAD::Eval_Point *>
1696 	to_be_evaluated;
1697 	NOMAD::success_type        one_eval_success;
1698 	bool                       one_for_luck = false;
1699 	bool                       opp_stop     = false;
1700 	int                        init_nb_eval = _stats.get_eval();
1701 	int                        nb_success   = 0;
1702 	int                        k            = 0;
1703 	int                        nb_points    = static_cast<int> ( _eval_lop.size() );
1704 	int                        max_bb_eval  = _p.get_max_bb_eval();
1705 
1706 	// loop #1: search in cache:
1707 	// -------------------------
1708 	std::set<NOMAD::Priority_Eval_Point>::iterator
1709     it  = _eval_lop.begin() ,
1710     end = _eval_lop.end();
1711 	while ( !stop && !opp_stop && it != end )
1712 	{
1713 
1714 		x = it->get_point();
1715 
1716 		x->set_current_run ( true );
1717 
1718 		// displays:
1719 		if ( display_degree == NOMAD::FULL_DISPLAY )
1720 		{
1721 
1722 			// open the evaluation block:
1723 			{
1724 				std::ostringstream oss;
1725 				if ( x->get_eval_type() == NOMAD::SGTE )
1726 					oss << "surrogate ";
1727 				oss << "evaluation " << k+1 << "/" << nb_points;
1728 				out << std::endl << NOMAD::open_block ( oss.str() );
1729 			}
1730 
1731 			out << std::endl << "point #" << x->get_tag() << "   ( ";
1732 			x->Point::display ( out , " " , 2 , NOMAD::Point::get_display_limit() );
1733 			out << " )" << std::endl;
1734 			if ( x->get_direction() )
1735 			{
1736 				out << "direction    : " << *x->get_direction()  << std::endl;
1737 				NOMAD::Point delta;
1738 				x->get_signature()->get_mesh()->get_delta(delta);
1739 				out << "direction d : ( " << *x->get_direction()/delta  << " )"  << std::endl;
1740 			}
1741 			if ( x->get_signature() )
1742 				out << "mesh indices:  ( " << x->get_signature()->get_mesh()->get_mesh_indices() << " )" << std::endl;
1743 			out << std::endl;
1744 
1745 
1746 
1747 		}
1748 
1749 		// check if the evaluation at this point is already in progress:
1750 		if ( !already_in_progress ( *x ) )
1751 		{
1752 
1753 			// current point check (# of bb outputs, bounds, integer values, fixed-vars):
1754 			if ( x->check ( _p.get_bb_nb_outputs() , check_failed_reason ) )
1755 			{
1756 
1757 				count_eval = true;
1758 
1759 				// point in cache:
1760 				if ( cache_check ( x                   ,
1761 								  true_barrier        ,
1762 								  sgte_barrier        ,
1763 								  pareto_front        ,
1764 								  count_eval          ,
1765 								  barrier.get_h_max() ,
1766 								  display_degree        ) )
1767 
1768 				{
1769 
1770 					// list of processed points:
1771 					evaluated_pts.push_back ( x );
1772 
1773 					// check stopping criteria:
1774 					check_stopping_criteria ( search , count_eval , *x , stop , stop_reason );
1775 
1776 					// success:
1777 					one_eval_success = barrier.get_one_eval_succ();
1778 					success          = barrier.get_success();
1779 
1780 					// displays:
1781 					display_eval_result ( *x               ,
1782 										 display_degree   ,
1783 										 search           ,
1784 										 one_eval_success ,
1785 										 success            );
1786 
1787 					// stop the evaluations (opportunistic strategy) ?
1788 					if ( stop_evaluations ( *x               ,
1789 										   search           ,
1790 										   k                ,
1791 										   nb_points        ,
1792 										   stop             ,
1793 										   display_degree   ,
1794 										   one_eval_success ,
1795 										   success          ,
1796 										   init_nb_eval     ,
1797 										   f0               ,
1798 										   barrier          ,
1799 										   nb_success       ,
1800 										   one_for_luck       ) )
1801 					{
1802 						_stats.add_interrupted_eval();
1803 						opp_stop = true; // will break loop #1
1804 					}
1805 
1806 					// close the evaluation block:
1807 					if ( display_degree == NOMAD::FULL_DISPLAY )
1808 						out.close_block();
1809 				}
1810 
1811 				// point not in cache (the point is saved for loop #2):
1812 				else
1813 				{
1814 
1815 					// blackbox or surrogate evaluations are allowed:
1816 					if ( ( x->get_eval_type() == NOMAD::TRUTH && max_bb_eval != 0 ) ||
1817 						( x->get_eval_type() == NOMAD::SGTE  && _p.get_max_sgte_eval() != 0 ) )
1818 						to_be_evaluated.push_back ( x );
1819 
1820 					// close the evaluation block:
1821 					if ( display_degree == NOMAD::FULL_DISPLAY )
1822 						out.close_block();
1823 				}
1824 			}
1825 
1826 			// points[k]->check() failed (close the evaluation block):
1827 			else if ( display_degree == NOMAD::FULL_DISPLAY )
1828 			{
1829 				std::ostringstream oss;
1830 				oss << "check failed (" << check_failed_reason << ")";
1831 				out.close_block ( oss.str() );
1832 			}
1833 		}
1834 
1835 		// evaluation already in progress (close the evaluation block):
1836 		else if ( display_degree == NOMAD::FULL_DISPLAY )
1837 		{
1838 			std::ostringstream oss;
1839 			oss << "evaluation of point #" << x->get_tag()
1840 			<< " already in progress";
1841 			out.close_block ( oss.str() );
1842 		}
1843 
1844 		++it;
1845 		++k;
1846 
1847 		// force quit (by pressing ctrl-c):
1848 		if ( !stop && (NOMAD::Evaluator_Control::_force_quit || NOMAD::Evaluator::get_force_quit()) )
1849 		{
1850 			stop        = true;
1851 			stop_reason = NOMAD::CTRL_C;
1852 		}
1853 
1854 	}  // end of loop #1
1855 	// --------------
1856 
1857 	// loop #2: evaluations:
1858 	// ---------------------
1859 	int                 nb_to_evaluate = static_cast<int> ( to_be_evaluated.size() );
1860 	int                 nb_evaluated   = 0;
1861 	int                 cur            = 0;
1862 	int                 source;
1863 	char                signal;
1864 	NOMAD::Eval_Point * eval_x;
1865 
1866 	while ( !stop && !opp_stop && nb_evaluated < nb_to_evaluate )
1867 	{
1868 
1869 		source = NOMAD::Slave::receive_signal ( signal );
1870 
1871 		// 2.1: send the RESULT signal, receive and process the evaluation result:
1872 		// -----------------------------------------------------------------------
1873 		eval_x = _eval_in_progress[source];
1874 		if ( eval_x )
1875 		{
1876 
1877 			if ( display_degree == NOMAD::FULL_DISPLAY )
1878 				out << std::endl << "receive eval point #" << eval_x->get_tag()
1879 				<< " from slave " << source << std::endl << std::endl;
1880 
1881 			receive_eval_result ( search       ,
1882 								 eval_x       ,
1883 								 true_barrier ,
1884 								 sgte_barrier ,
1885 								 pareto_front ,
1886 								 source       ,
1887 								 stop         ,
1888 								 stop_reason    );
1889 
1890 
1891 			// list of processed points:
1892 			if ( eval_x->is_in_cache() )
1893 				evaluated_pts.push_back ( eval_x );
1894 
1895 			// success:
1896 			one_eval_success = barrier.get_one_eval_succ();
1897 			success          = barrier.get_success();
1898 
1899 			// asynchronous success count:
1900 			if ( success == NOMAD::FULL_SUCCESS &&
1901 				_elop_tag != _slaves_elop_tags[source] )
1902 				_stats.add_asynchronous_success();
1903 
1904 			// displays:
1905 			display_eval_result ( *eval_x          ,
1906 								 display_degree   ,
1907 								 search           ,
1908 								 one_eval_success ,
1909 								 success            );
1910 
1911 			// stop the evaluations (opportunistic strategy) ?
1912 			if ( stop_evaluations ( *eval_x          ,
1913 								   search           ,
1914 								   nb_evaluated     ,
1915 								   nb_to_evaluate   ,
1916 								   stop             ,
1917 								   display_degree   ,
1918 								   one_eval_success ,
1919 								   success          ,
1920 								   init_nb_eval     ,
1921 								   f0               ,
1922 								   barrier          ,
1923 								   nb_success       ,
1924 								   one_for_luck       ) )
1925 			{
1926 				_stats.add_interrupted_eval();
1927 				opp_stop = true; // will break loop #2
1928 			}
1929 
1930 			_eval_in_progress[source] = NULL;
1931 			_slaves_elop_tags[source] = -1;
1932 			--_nb_in_progress;
1933 			++nb_evaluated;
1934 		}
1935 
1936 		// 2.2: send the EVAL signal and launch a new evaluation:
1937 		// ------------------------------------------------------
1938 		else
1939 		{
1940 
1941 			// do not launch a new evaluation if...
1942 
1943 			// there is no more points to be evaluated:
1944 			if ( cur == nb_to_evaluate )
1945 				NOMAD::Slave::send_signal ( NOMAD::WAIT_SIGNAL , source );
1946 
1947 			// or if bbe+_nb_in_progress >= max_bb_eval:
1948 			else if ( to_be_evaluated[cur]->get_eval_type() == NOMAD::TRUTH &&
1949 					 max_bb_eval > 0 &&
1950 					 _stats.get_bb_eval() + _nb_in_progress >= max_bb_eval    )
1951 			{
1952 				stop        = true;
1953 				stop_reason = NOMAD::MAX_BB_EVAL_REACHED;
1954 				NOMAD::Slave::send_signal ( NOMAD::WAIT_SIGNAL , source );
1955 			}
1956 
1957 			else
1958 			{
1959 
1960 				// get the signature:
1961 				NOMAD::Signature * signature = to_be_evaluated[cur]->get_signature();
1962 
1963 				// there is no signature (error):
1964 				if ( !signature )
1965 				{
1966 					stop        = true;
1967 					stop_reason = NOMAD::ERROR;
1968 					if ( display_degree != NOMAD::NO_DISPLAY && display_degree != NOMAD::MINIMAL_DISPLAY)
1969 						out << std::endl
1970 						<< "Error in Evaluator_Control::private_eval_list_of_points():"
1971 						<< " the point #" << to_be_evaluated[cur]->get_tag()
1972 						<< " has no signature" << std::endl << std::endl;
1973 					NOMAD::Slave::send_signal ( NOMAD::WAIT_SIGNAL , source );
1974 				}
1975 
1976 				else
1977 				{
1978 
1979 					NOMAD::Slave::send_signal ( NOMAD::EVAL_SIGNAL , source );
1980 
1981 					eval_x = &NOMAD::Cache::get_modifiable_point ( *to_be_evaluated[cur++] );
1982 
1983 					if ( display_degree == NOMAD::FULL_DISPLAY )
1984 						out << std::endl
1985 						<< "send eval point #" << eval_x->get_tag()
1986 						<< " to slave " << source << std::endl;
1987 
1988 					// 1. scaling:
1989 					bool do_scaling = signature->get_scaling().is_defined();
1990 					if ( do_scaling )
1991 						eval_x->scale();
1992 
1993 					// 2. send the point:
1994 					_slave->send_eval_point ( eval_x , source , barrier.get_h_max() );
1995 
1996 					// 3. unscaling:
1997 					if ( do_scaling )
1998 						eval_x->unscale();
1999 
2000 					eval_x->set_eval_status ( NOMAD::EVAL_IN_PROGRESS );
2001 
2002 					_eval_in_progress[source] = eval_x;
2003 					_slaves_elop_tags[source] = _elop_tag;
2004 					++_nb_in_progress;
2005 				}
2006 			}
2007 		}
2008 
2009 		// force quit (by pressing ctrl-c):
2010 		if ( !stop && ( NOMAD::Evaluator_Control::_force_quit || NOMAD::Evaluator::get_force_quit() ))
2011 		{
2012 			stop        = true;
2013 			stop_reason = NOMAD::CTRL_C;
2014 		}
2015 
2016 	}  // end of loop #2
2017 	// --------------
2018 
2019 	if ( display_degree == NOMAD::FULL_DISPLAY )
2020 		out << std::endl
2021 		<< "number of evaluations in progress: " << _nb_in_progress
2022 		<< std::endl << std::endl;
2023 
2024 	// the algorithm is not asynchronous: we have
2025 	// to wait for all the evaluations in progress:
2026 	if ( !_p.get_asynchronous() )
2027 
2028 		wait_for_evaluations ( search        ,
2029 							  true_barrier  ,
2030 							  sgte_barrier  ,
2031 							  pareto_front  ,
2032 							  stop          ,
2033 							  stop_reason   ,
2034 							  success       ,
2035 							  evaluated_pts   );
2036 
2037 	// barriers update:
2038 	if ( !stop )
2039 	{
2040 		true_barrier.update_and_reset_success();
2041 		sgte_barrier.update_and_reset_success();
2042 	}
2043 
2044 	if ( display_degree == NOMAD::FULL_DISPLAY )
2045 		out << NOMAD::close_block ( "end of evaluations" ) << std::endl;
2046 
2047 	// incumbents update:
2048 	const NOMAD::Eval_Point * bf = barrier.get_best_feasible  ();
2049 	const NOMAD::Eval_Point * bi = barrier.get_best_infeasible();
2050 	if ( bf && bf != old_feasible_incumbent )
2051 		new_feas_inc = bf;
2052 	if ( bi && bi != old_infeasible_incumbent )
2053 		new_infeas_inc = bi;
2054 
2055 	// the list of eval. points is deleted (only points in the cache are kept):
2056 	clear_eval_lop();
2057 
2058 	// update the unique eval_lop() tag:
2059 	++_elop_tag;
2060 
2061 } // end of eval_lop() parallel version
2062 
2063 // C. Tribes may 28, 2014 --- method for points block evaluation of a given max size
2064 /*----------------------------------------------------------------*/
2065 /*       eval_list_of_points, private version (scalar version)    */
2066 /*----------------------------------------------------------------*/
2067 #else
private_eval_list_of_points(NOMAD::search_type search,NOMAD::Barrier & true_barrier,NOMAD::Barrier & sgte_barrier,NOMAD::Pareto_Front * pareto_front,bool & stop,NOMAD::stop_type & stop_reason,const NOMAD::Eval_Point * & new_feas_inc,const NOMAD::Eval_Point * & new_infeas_inc,NOMAD::success_type & success,std::list<const NOMAD::Eval_Point * > & evaluated_pts)2068 void NOMAD::Evaluator_Control::private_eval_list_of_points
2069 ( NOMAD::search_type              search         ,   // IN     : search type
2070   NOMAD::Barrier                & true_barrier   ,   // IN/OUT : the barrier
2071   NOMAD::Barrier                & sgte_barrier   ,   // IN/OUT : the surrogate barrier
2072   NOMAD::Pareto_Front           * pareto_front   ,   // IN/OUT : the Pareto front
2073                                                      //          (can be NULL)
2074   bool                          & stop           ,   // IN/OUT : stopping criterion
2075   NOMAD::stop_type              & stop_reason    ,   // OUT    : stopping reason
2076   const NOMAD::Eval_Point      *& new_feas_inc   ,   // OUT    : new feasible incumbent
2077   const NOMAD::Eval_Point      *& new_infeas_inc ,   // OUT    : new infeas. incumbent
2078   NOMAD::success_type           & success        ,   // OUT    : type of success
2079   std::list<const NOMAD::Eval_Point *>
2080                                 & evaluated_pts    ) // OUT    : list of processed pts
2081 {
2082 	if ( stop || _eval_lop.empty() )
2083 	{
2084 		stop_reason = NOMAD::UNKNOWN_STOP_REASON;
2085 		return;
2086 	}
2087 
2088 	evaluated_pts.clear();
2089 
2090 	// initial display:
2091 	const NOMAD::Display    & out = _p.out();
2092 	NOMAD::dd_type display_degree = out.get_display_degree ( search );
2093 
2094 
2095 	if ( display_degree == NOMAD::FULL_DISPLAY )
2096 	{
2097 		std::ostringstream oss;
2098 		oss << "list of points evaluation (" << search << ")";
2099 		out << std::endl << NOMAD::open_block ( oss.str() );
2100 	}
2101 
2102 	// call the Evaluator (virtual) preprocessing of a list of points:
2103 	_ev->list_of_points_preprocessing ( _eval_lop );
2104 
2105 	const NOMAD::Eval_Point * old_feasible_incumbent   = NULL;
2106 	const NOMAD::Eval_Point * old_infeasible_incumbent = NULL;
2107 
2108 	// active barrier:
2109 	NOMAD::Barrier & barrier = ( _p.get_opt_only_sgte() ) ?  sgte_barrier : true_barrier;
2110 
2111 	old_feasible_incumbent   = barrier.get_best_feasible();
2112 	old_infeasible_incumbent = barrier.get_best_infeasible();
2113 
2114 	NOMAD::Double f0;
2115 	if ( _p.get_opportunistic_min_f_imprvmt().is_defined() &&
2116 		old_feasible_incumbent )
2117 		f0 = old_feasible_incumbent->get_f();
2118 
2119 	new_feas_inc   = NULL;
2120 	new_infeas_inc = NULL;
2121 	stop           = false;
2122 	success        = NOMAD::UNSUCCESSFUL;
2123 	stop_reason    = NOMAD::NO_STOP;
2124 
2125 	const NOMAD::Eval_Point * x;
2126 	NOMAD::check_failed_type  check_failed_reason;
2127 	bool                      one_for_luck = false;
2128 	bool                      stop_evals   = false;
2129 	int                       init_nb_eval = _stats.get_eval();
2130 	int                       nb_success   = 0;
2131 	int                       k            = 0;
2132 	int                       k_block      = 0;
2133 	int                       nb_points    = get_nb_eval_points();
2134 	int						  block_size   = _p.get_bb_max_block_size();
2135 	int						  block_nb		= 1;
2136 
2137 	// main loop (on the list of points):
2138 	// ----------------------------------
2139 	std::set<NOMAD::Priority_Eval_Point>::iterator it  = _eval_lop.begin() , end = _eval_lop.end();
2140 	std::list<NOMAD::Eval_Point *> list_x,list_eval;
2141 	std::list<bool> count_list_eval;
2142 
2143 	while ( !stop_evals && !stop && it != end )
2144 	{
2145 
2146 
2147 		if ( block_size > 1 && display_degree == NOMAD::FULL_DISPLAY )
2148 		{
2149 			std::ostringstream oss;
2150 			oss << "Block of evaluations (" << block_nb <<")";
2151 			out << std::endl << NOMAD::open_block ( oss.str() );
2152 		}
2153 
2154 		// Creation of a block of evaluations from the list
2155 		//----------------------
2156 		k_block=k;
2157         bool opportunistic_success_from_cache_point=false;
2158 		while (list_eval.size()!=static_cast<size_t>(block_size) && it != end && ! stop_evals)
2159 		{
2160 
2161 			x = it->get_point();
2162 			x->set_current_run ( true );
2163 
2164 			// displays:
2165 			if ( display_degree == NOMAD::FULL_DISPLAY )
2166 			{
2167 				{
2168 					// open the evaluation block:
2169 					std::ostringstream oss;
2170 						oss << "submitted ";
2171 					if ( x->get_eval_type() == NOMAD::SGTE )
2172 						oss << "surrogate ";
2173 					oss << "evaluation " << k+1 << "/" << nb_points;
2174 					out << std::endl << NOMAD::open_block ( oss.str() );
2175 				}
2176 
2177 				out << std::endl << "point #" << x->get_tag() << "   ( ";
2178 				x->Point::display ( out , " " , 2 , NOMAD::Point::get_display_limit() );
2179 				out << " )" << std::endl;
2180 				if ( x->get_direction() )
2181 				{
2182 					out << "direction   : " << *x->get_direction()  << std::endl;
2183 					NOMAD::Point delta;
2184 					x->get_signature()->get_mesh()->get_delta(delta);
2185 					out << "direction d : ( " << *x->get_direction()/delta  << " )"  << std::endl;
2186 				}
2187 				if ( x->get_signature() )
2188 					out << "mesh indices: ( " << x->get_signature()->get_mesh()->get_mesh_indices() << " )" << std::endl;
2189 				out << std::endl;
2190 
2191 			}
2192 
2193 			// current point check (# of bb outputs, bounds, integer values, fixed-vars):
2194 			if ( x->check ( _p.get_bb_nb_outputs() , check_failed_reason ) )
2195 			{
2196 				bool count_eval = true;
2197 				bool has_been_in_cache=cache_check ( x                  ,
2198 													true_barrier        ,
2199 													sgte_barrier        ,
2200 													pareto_front        ,
2201 													count_eval			,
2202 													barrier.get_h_max() ,
2203 													display_degree        );
2204 
2205 
2206 				// put the point in a block list for evaluation:
2207 				if ( !has_been_in_cache )
2208 					list_eval.push_back(&NOMAD::Cache::get_modifiable_point ( *x ));
2209 				else
2210 				{
2211 					// check stopping criteria for points in cache
2212 					check_stopping_criteria ( search , count_eval , *x , stop , stop_reason );
2213 
2214                     // process the evaluated point:
2215                     process_eval_point ( *x                                       ,
2216                                         ( x->get_eval_type() == NOMAD::TRUTH ) ? true_barrier : sgte_barrier ,
2217                                         pareto_front                                    );
2218 
2219 
2220                     // success:
2221                     NOMAD::success_type one_eval_success = barrier.get_one_eval_succ();
2222                     success                              = barrier.get_success();
2223 
2224 
2225                     opportunistic_success_from_cache_point = stop_evaluations ( *x               ,
2226                                                                            search           ,
2227                                                                            k                ,
2228                                                                            nb_points        ,
2229                                                                            stop             ,
2230                                                                            display_degree   ,
2231                                                                            one_eval_success ,
2232                                                                            success          ,
2233                                                                            init_nb_eval     ,
2234                                                                            f0               ,
2235                                                                            barrier          ,
2236                                                                            nb_success       ,
2237                                                                            one_for_luck       );
2238 
2239 
2240 				}
2241 
2242 				if (!stop)
2243 					list_x.push_back(&NOMAD::Cache::get_modifiable_point ( *x ));
2244 
2245                 if ( opportunistic_success_from_cache_point )
2246                 {
2247                     if ( display_degree == NOMAD::FULL_DISPLAY )
2248                         out << NOMAD::close_block();
2249 
2250                     if ( block_size > 1 && display_degree == NOMAD::FULL_DISPLAY )
2251                         out << NOMAD::close_block ();
2252 
2253                     stop_evals = true;
2254                     break;
2255                 }
2256 
2257 			}
2258 			// points[k]->check() failed:
2259 			else if ( display_degree == NOMAD::FULL_DISPLAY )
2260 				out << "check failed (" << check_failed_reason << ")" << std::endl;
2261 
2262 			if ( display_degree == NOMAD::FULL_DISPLAY )
2263 				 out << NOMAD::close_block();
2264 
2265 
2266 			++it;
2267 			++k;
2268 		}
2269 		if (list_eval.size()!=0)
2270 		{
2271 
2272 			count_list_eval.assign(list_eval.size(), false);
2273 
2274 			if (_p.eval_points_as_block())
2275 			{
2276 				eval_points ( list_eval			,
2277 							 true_barrier		,
2278 							 sgte_barrier		,
2279 							 pareto_front		,
2280 							 count_list_eval	,
2281 							 stop				,
2282 							 stop_reason		,
2283 							 barrier.get_h_max() );
2284 
2285 				// check stopping criteria for points NOT in cache
2286 				std::list<NOMAD::Eval_Point *>::iterator it_eval;
2287 			}
2288 			else
2289 			{
2290 				// bool count_eval=false;
2291 				x=*(list_eval.begin());
2292 				eval_point ( NOMAD::Cache::get_modifiable_point ( *x )	,
2293 							 true_barrier								,
2294 							 sgte_barrier								,
2295 							 pareto_front								,
2296 							 count_list_eval.front()					,
2297 							 stop										,
2298 							 stop_reason								,
2299 							 barrier.get_h_max()						);
2300 
2301 			}
2302 
2303 		}
2304 
2305         // Stop evals and exit the loop
2306         if ( stop_evals )
2307             break;
2308 
2309 		// Check all the points in the evaluation block
2310 		std::list<NOMAD::Eval_Point *>::iterator it_x,it_eval;
2311 		k=k_block;
2312 		it_eval=list_eval.begin();
2313 		for(it_x=list_x.begin();it_x!=list_x.end();++it_x)
2314 		{
2315 
2316 			x=(*it_x);
2317 
2318 			// process the evaluated point:
2319 			if ( x->is_eval_ok() && x->is_in_cache() )
2320 				process_eval_point ( *x                                       ,
2321 									( x->get_eval_type() == NOMAD::TRUTH ) ?
2322 									true_barrier : sgte_barrier                   ,
2323 									pareto_front                                    );
2324 
2325 
2326 
2327 
2328 			// success:
2329 			NOMAD::success_type one_eval_success = barrier.get_one_eval_succ();
2330 			success                              = barrier.get_success();
2331 
2332 			// list of processed points:
2333 			if ( x->is_in_cache() )
2334 				evaluated_pts.push_back ( x );
2335 			else
2336 			{
2337 				// this situation may occur on very thin meshes:
2338 				// the point has not been found in the cache
2339 				// and it failed to be inserted.
2340 				one_eval_success = NOMAD::UNSUCCESSFUL;
2341 			}
2342 
2343 			// displays:
2344 			if ( block_size > 0 && display_degree == NOMAD::FULL_DISPLAY )
2345 			{
2346 					// open the evaluation block:
2347 					std::ostringstream oss;
2348 					if ( x->get_eval_type() == NOMAD::SGTE )
2349 						oss << "surrogate ";
2350 					oss << "evaluation " << k+1 << "/" << nb_points;
2351 					out << std::endl << NOMAD::open_block ( oss.str() );
2352                     out << std::endl << "point #" << x->get_tag() << std::endl;
2353 			}
2354 
2355 			std::list<bool>::iterator it_count=count_list_eval.begin();
2356 			for(it_eval=list_eval.begin();it_eval!=list_eval.end();++it_eval,++it_count)
2357 			{
2358 				if ((*it_eval)==x)
2359 				{
2360 
2361 					// count the bb evaluation:
2362 					if ( *it_count )
2363 					{
2364 						if ( (*it_eval)->get_eval_type() == NOMAD::SGTE )
2365 							_stats.add_sgte_eval();
2366 						else
2367 						{
2368 							// current mads bbe evaluation
2369 							_stats.add_bb_eval();
2370 						}
2371 
2372 						// count the output stats (STAT_SUM and STAT_AVG):
2373 						if ( _p.check_stat_sum() || _p.check_stat_avg() )
2374 							count_output_stats(*(*it_eval));
2375 					}
2376 
2377 					check_stopping_criteria ( search , *it_count ,*(*it_eval) , stop , stop_reason );
2378 
2379 					if ( *it_count )
2380 						display_eval_result ( *x, display_degree, search, one_eval_success, success );
2381 
2382 					break;
2383 				}
2384 			}
2385 
2386 
2387 
2388 			// close the evaluation block:
2389 			if ( display_degree == NOMAD::FULL_DISPLAY )
2390 				out << NOMAD::close_block ();
2391 
2392 			// stop the evaluations (opportunistic strategy) ?
2393 			if ( !stop_evals && stop_evaluations ( *x               ,
2394 												  search           ,
2395 												  k                ,
2396 												  nb_points        ,
2397 												  stop             ,
2398 												  display_degree   ,
2399 												  one_eval_success ,
2400 												  success          ,
2401 												  init_nb_eval     ,
2402 												  f0               ,
2403 												  barrier          ,
2404 												  nb_success       ,
2405 												  one_for_luck       ) )
2406 			{
2407 				_stats.add_interrupted_eval();
2408 				stop_evals = true;
2409 			}
2410 
2411 
2412 			++k;
2413 
2414 		}
2415 
2416 		if ( block_size > 1 && display_degree == NOMAD::FULL_DISPLAY )
2417 			out << NOMAD::close_block ();
2418 
2419 
2420 		// force quit (by pressing ctrl-c):
2421 		if ( !stop && ( NOMAD::Evaluator_Control::_force_quit || NOMAD::Evaluator::get_force_quit()) )
2422 		{
2423 			stop        = true;
2424 			stop_reason = NOMAD::CTRL_C;
2425 		}
2426 
2427 		list_x.clear();
2428 		list_eval.clear();
2429 
2430 		++block_nb;
2431 
2432 	}// end of test for list evaluation
2433 
2434 	// barriers update:
2435 	if ( !stop )
2436 	{
2437 		true_barrier.update_and_reset_success();
2438 		sgte_barrier.update_and_reset_success();
2439 	}
2440 
2441 	if ( display_degree == NOMAD::FULL_DISPLAY )
2442 		out << std::endl << NOMAD::close_block ( "end of evaluations" )
2443 		<< std::endl;
2444 
2445 	// incumbents update:
2446 	const NOMAD::Eval_Point * bf = barrier.get_best_feasible  ();
2447 	const NOMAD::Eval_Point * bi = barrier.get_best_infeasible();
2448 	if ( bf && bf != old_feasible_incumbent )
2449 		new_feas_inc = bf;
2450 	if ( bi && bi != old_infeasible_incumbent )
2451 		new_infeas_inc = bi;
2452 
2453 	// the list of eval. points is deleted (only points in the cache are kept):
2454 	clear_eval_lop();
2455 
2456 } // end of eval_lop() scalar version
2457 
2458 
2459 #endif
2460 
2461 /*-------------------------------------------------*/
2462 /*       reduce the list of evaluation points      */
2463 /*-------------------------------------------------*/
reduce_eval_lop(int n)2464 void NOMAD::Evaluator_Control::reduce_eval_lop ( int n )
2465 {
2466     int nb_eval_pts = get_nb_eval_points();
2467 
2468     if ( n < 0 || n >= nb_eval_pts )
2469         return;
2470 
2471     const NOMAD::Eval_Point * x;
2472     std::set<NOMAD::Priority_Eval_Point>::iterator it = _eval_lop.end();
2473     for( int i=0;i<nb_eval_pts-n;i++)
2474     {
2475         --it;
2476         x = it->get_point();
2477         if ( x && !x->is_in_cache() && x->get_eval_status() != NOMAD::EVAL_IN_PROGRESS )
2478             delete x;
2479     }
2480     _eval_lop.erase( it,_eval_lop.end());
2481 }
2482 
2483 /*-------------------------------------------------*/
2484 /*            TGP model ordering (private)         */
2485 /*-------------------------------------------------*/
TGP_model_ordering(NOMAD::dd_type display_degree,bool & modified_list)2486 void NOMAD::Evaluator_Control::TGP_model_ordering ( NOMAD::dd_type   display_degree ,
2487 						    bool           & modified_list    )
2488 {
2489   modified_list = false;
2490 
2491   if ( _p.get_opt_only_sgte() )
2492     return;
2493 
2494 #ifdef USE_TGP
2495 
2496   // display:
2497   const NOMAD::Display & out = _p.out();
2498 
2499   // model stats:
2500   NOMAD::Model_Stats model_stats;
2501   NOMAD::Clock       clock;
2502 
2503 #ifdef TGP_DEBUG
2504   out << std::endl << NOMAD::open_block ( "TGP model ordering") << std::endl;
2505 #endif
2506 
2507   const std::vector<NOMAD::bb_output_type> & bbot = _p.get_bb_output_type();
2508   int i , j , n_XX = 0 , m = bbot.size();
2509 
2510   // construct prediction set (XX):
2511   // ------------------------------
2512   std::vector<NOMAD::Eval_Point *> XX;
2513   NOMAD::Point                     lb_XX , ub_XX;
2514 
2515   // save _eval_lop in XX and other_pts:
2516   const NOMAD::Eval_Point            * x;
2517   std::list<const NOMAD::Eval_Point *> other_pts;
2518   const NOMAD::Signature             * signature = NULL;
2519   int                                  n         = -1;
2520 
2521   std::set<NOMAD::Priority_Eval_Point>::const_iterator it , end = _eval_lop.end();
2522   for ( it = _eval_lop.begin() ; it != end ; ++it ) {
2523     x = it->get_point();
2524     if ( n < 0 ) {
2525       signature = x->get_signature();
2526       if ( !signature ) {
2527 #ifdef TGP_DEBUG
2528 	out << NOMAD::close_block ( "failure (no signature)" ) << std::endl;
2529 #endif
2530 	return;
2531       }
2532       n = signature->get_n();
2533 
2534       lb_XX = ub_XX = NOMAD::Point(n);
2535     }
2536 
2537     if ( x->size           () == n            &&
2538 	 x->get_m          () == m            &&
2539 	 x->get_eval_type  () == NOMAD::TRUTH &&
2540 	 !x->get_bb_outputs().is_defined()       ) {
2541 
2542       XX.push_back ( &NOMAD::Cache::get_modifiable_point ( *x ) );
2543 
2544       for ( i = 0 ; i < n ; ++i ) {
2545 	if ( !lb_XX[i].is_defined() || (*x)[i] < lb_XX[i] )
2546 	  lb_XX[i] = (*x)[i];
2547 	if ( !ub_XX[i].is_defined() || (*x)[i] > ub_XX[i] )
2548 	  ub_XX[i] = (*x)[i];
2549       }
2550     }
2551     else
2552       other_pts.push_back ( x );
2553   }
2554 
2555   n_XX = XX.size();
2556 
2557   if ( n_XX <= 1 ) {
2558 #ifdef TGP_DEBUG
2559     out << NOMAD::close_block ( "failure (size(XX) <= 1)" ) << std::endl;
2560 #endif
2561     return;
2562   }
2563 
2564   // the TGP model:
2565   NOMAD::TGP_Model * model;
2566 
2567   // Reuse the last TGP model from the TGP model search:
2568   if ( _last_TGP_model && _p.get_model_tgp_reuse_model() ) {
2569 
2570     model = _last_TGP_model;
2571 
2572     // individual predictions for XX points:
2573     for ( i = 0 ; i < n_XX ; ++i )
2574       if ( !model->predict ( *XX[i] , false ) ) // pred_outside_bnds = false
2575 	for ( j = 0 ; j < m ; ++j )
2576 	  XX[i]->set_bb_output ( j , NOMAD::Double() );
2577   }
2578 
2579   // creation of a new TGP model:
2580   else {
2581 
2582     model = new NOMAD::TGP_Model ( n , bbot , out , _p.get_model_tgp_mode() );
2583 
2584     NOMAD::Point center(n);
2585     for ( i = 0 ; i < n ; ++i )
2586       center[i] = ( lb_XX[i] + ub_XX[i] ) / 2.0;
2587 
2588     // construct interpolation set (X):
2589     // --------------------------------
2590     if ( !model->set_X ( *_cache       ,
2591 			 &center       ,
2592 			 _p.get_seed() ,
2593 			 true            ) ) { // remove_fv = true
2594 
2595       if ( model->get_p() <= model->get_n() )
2596 	model_stats.add_not_enough_pts();
2597 #ifdef TGP_DEBUG
2598       out << NOMAD::close_block ( "failure: " + model->get_error_str() )
2599 	  << std::endl;
2600 #endif
2601 
2602       delete model;
2603 
2604       return;
2605     }
2606 
2607     int p = model->get_p();
2608 
2609     // display sets X and XX:
2610     // ----------------------
2611 #ifdef TGP_DEBUG
2612     {
2613       // max number of points displayed:
2614       const int set_display_limit = 15; // set to -1 for no limit
2615 
2616       // X:
2617       model->display_X ( out ,  set_display_limit );
2618 
2619       // XX:
2620       out << NOMAD::open_block ( "prediction points (XX)");
2621       for ( i = 0 ; i < n_XX ; ++i ) {
2622 	out << "#";
2623 	out.display_int_w ( i , n_XX );
2624 	out << " x=(";
2625 	XX[i]->NOMAD::Point::display ( out , " " , 15 , -1 );
2626 	out << " )" << std::endl;
2627       }
2628       std::ostringstream oss;
2629       oss << "(size=" << n_XX << ")";
2630       out << NOMAD::close_block ( oss.str() ) << std::endl;
2631     }
2632 #endif
2633 
2634     // TGP model construction:
2635     // -----------------------
2636 #ifdef TGP_DEBUG
2637     out << "TGP model construction ...";
2638     out.flush();
2639 #endif
2640 
2641     if ( !model->compute ( XX    ,
2642 			   false ,       // compute_Ds2x      = false
2643 			   false ,       // compute_improv    = false
2644 			   false   ) ) { // pred_outside_bnds = false
2645 
2646       model_stats.add_construction_error();
2647 
2648 #ifdef TGP_DEBUG
2649       out << "... error: " << model->get_error_str() << std::endl
2650 	  << NOMAD::close_block() << std::endl;
2651 #endif
2652 
2653       // reset XX outputs:
2654       for ( i = 0 ; i < n_XX ; ++i )
2655 	for ( j = 0 ; j < m ; ++j )
2656 	  XX[i]->set_bb_output ( j , NOMAD::Double() );
2657 
2658       delete model;
2659 
2660       // check if ctrl-c has been pressed:
2661       if ( NOMAD::TGP_Output_Model::get_force_quit() )
2662 	NOMAD::Evaluator_Control::_force_quit = true;
2663 
2664       return;
2665     }
2666 #ifdef TGP_DEBUG
2667     out << "... OK" << std::endl << std::endl;
2668 #endif
2669 
2670     // update model stats:
2671     model_stats.add_construction_time ( clock.get_CPU_time() );
2672     model_stats.update_nY             ( p                    );
2673     model_stats.update_ES_stats       ( n_XX , n_XX          );
2674     model_stats.add_nb_truth();
2675     model_stats.add_nb_TGP();
2676   }
2677 
2678   // open display block for model predictions:
2679 #ifdef TGP_DEBUG
2680   out << NOMAD::open_block ( "TGP predictions (XX+ZZ)");
2681 #endif
2682 
2683   // clear then fill _eval_lop again:
2684   // --------------------------------
2685   NOMAD::Double         f_model , h_model;
2686   const NOMAD::Double & h_min          = _p.get_h_min();
2687   NOMAD::hnorm_type     h_norm         = _p.get_h_norm();
2688   bool                  snap_to_bounds = _p.get_snap_to_bounds();
2689 
2690   modified_list = true;
2691   _eval_lop.clear();
2692 
2693   for ( i = 0 ; i < n_XX ; ++i ) {
2694 
2695     // compute model h and f values:
2696     model->eval_hf ( XX[i]->get_bb_outputs() ,
2697 		     h_min                   ,
2698 		     h_norm                  ,
2699 		     h_model                 ,
2700 		     f_model                   );
2701 
2702     // display model predictions:
2703 #ifdef TGP_DEBUG
2704     out << "#";
2705     out.display_int_w ( i , n_XX );
2706     out << " x=(";
2707     XX[i]->NOMAD::Point::display ( out , " " , 15 , -1 );
2708     out << " ) m(x)=[";
2709     XX[i]->get_bb_outputs().display ( out , " " , 15 , -1 );
2710     out << " ]";
2711 
2712     if ( h_model.is_defined() && f_model.is_defined() )
2713       out << " hm=" << std::setw(15) << h_model
2714 	  << " fm=" << std::setw(15) << f_model;
2715     else
2716       out << " no model value";
2717     out << std::endl;
2718 #endif
2719 
2720     // add the evaluation point:
2721     add_eval_point ( XX[i]           ,
2722 		     display_degree  ,
2723 		     snap_to_bounds  ,
2724 		     NOMAD::Double() ,
2725 		     NOMAD::Double() ,
2726 		     f_model         ,
2727 		     h_model           );
2728 
2729 #ifdef MODEL_STATS
2730     if ( XX[i] && f_model.is_defined() && h_model.is_defined() ) {
2731       XX[i]->set_mod_use  ( 2                ); // 2 for model ordering
2732       XX[i]->set_Yw       ( model->get_Yw () );
2733       XX[i]->set_nY       ( p                );
2734       XX[i]->set_mh       ( h_model          );
2735       XX[i]->set_mf       ( f_model          );
2736     }
2737 #endif
2738   }
2739 
2740 #ifdef TGP_DEBUG
2741   {
2742     // close display block for model predictions:
2743     std::ostringstream oss;
2744     oss << "(size=" << n_XX << ")";
2745     out << NOMAD::close_block ( oss.str() ) << std::endl;
2746 
2747     // compute and display prediction errors:
2748     out << NOMAD::open_block ( "prediction relative errors on X(%)" );
2749     model->display_X_errors ( out );
2750     out << NOMAD::close_block() << std::endl;
2751   }
2752 #endif
2753 
2754   // other points that have been previously discarded and have no model values:
2755   NOMAD::Eval_Point * y;
2756   std::list<const NOMAD::Eval_Point *>::const_iterator it2 , end2 = other_pts.end();
2757   for ( it2 = other_pts.begin() ; it2 != end2 ; ++it2 ) {
2758     y = &NOMAD::Cache::get_modifiable_point (**it2);
2759     add_eval_point ( y               ,
2760 		     display_degree  ,
2761 		     snap_to_bounds  ,
2762 		     NOMAD::Double() ,
2763 		     NOMAD::Double() ,
2764 		     NOMAD::Double() ,
2765 		     NOMAD::Double()   );
2766   }
2767 
2768   _stats.update_model_stats    ( model_stats );
2769   _model_ordering_stats.update ( model_stats );
2770 
2771   if ( model != _last_TGP_model )
2772     delete model;
2773 
2774 #ifdef TGP_DEBUG
2775   out << NOMAD::close_block() << std::endl;
2776 #else
2777   if ( display_degree == NOMAD::FULL_DISPLAY ) {
2778     out << std::endl << "model ordering";
2779     if ( !modified_list )
2780       out << " (no modification)";
2781     out << std::endl;
2782   }
2783 #endif
2784 #endif
2785 }
2786 
2787 /*-------------------------------------------------*/
2788 /*         model_np1_quad_epsilon (private)      */
2789 /*-------------------------------------------------*/
quad_model_ordering(NOMAD::dd_type display_degree,bool & modified_list)2790 void NOMAD::Evaluator_Control::quad_model_ordering ( NOMAD::dd_type display_degree ,
2791 						     bool         & modified_list    )
2792 {
2793 	const NOMAD::Display & out = _p.out();
2794 
2795 #ifdef DEBUG
2796 	out << std::endl << NOMAD::open_block ( "model_np1_quad_epsilon") << std::endl;
2797 #endif
2798 
2799 	// save _eval_lop in pts and other_pts:
2800 	// ------------------------------------
2801 	NOMAD::Point                         min , max , center , interpolation_radius;
2802 	const NOMAD::Eval_Point *            y;
2803 	std::list<const NOMAD::Eval_Point *> pts , other_pts;
2804 	const NOMAD::Signature  *            signature     = NULL;
2805 	const NOMAD::Double &                radius_factor = _p.get_model_quad_radius_factor();
2806 	NOMAD::eval_type                     ev_type       = NOMAD::TRUTH;
2807 	int                                  i , n = -1;
2808 
2809 	std::set<NOMAD::Priority_Eval_Point>::const_iterator it , end = _eval_lop.end();
2810 	for ( it = _eval_lop.begin() ; it != end ; ++it )
2811 	{
2812 		y = it->get_point();
2813 		if ( n < 0 )
2814 		{
2815 			signature = y->get_signature();
2816 			if ( !signature )
2817 			{
2818 #ifdef DEBUG
2819 				out << NOMAD::close_block ( "failure (no signature)" ) << std::endl;
2820 #endif
2821 				modified_list = false;
2822 				return;
2823 			}
2824 			n       = signature->get_n();
2825 			ev_type = y->get_eval_type();
2826 			min.resize                  ( n );
2827 			max.resize                  ( n );
2828 			center.resize               ( n );
2829 			interpolation_radius.resize ( n );
2830 		}
2831 
2832 		if ( y->size() == n && y->get_eval_type() == ev_type ) {
2833 			pts.push_back(y);
2834 			for ( i = 0 ; i < n ; ++i ) {
2835 				if ( !min[i].is_defined() || (*y)[i] < min[i] )
2836 					min[i] = (*y)[i];
2837 				if ( !max[i].is_defined() || (*y)[i] > max[i] )
2838 					max[i] = (*y)[i];
2839 			}
2840 		}
2841 		else
2842 			other_pts.push_back ( y );
2843 	}
2844 
2845 	for ( i = 0 ; i < n ; ++i )
2846 	{
2847 		center              [i] = ( min[i] + max[i] ) / 2.0;
2848 		interpolation_radius[i] = ( max[i] - min[i] ) * radius_factor / 2.0;
2849 	}
2850 
2851 #ifdef DEBUG
2852 	out << NOMAD::open_block ( "points used to define interpolation radius")
2853 	<< "type of eval.   : " << ev_type    << std::endl
2854 	<< "number of points: " << pts.size() << std::endl
2855 	<< "min. coordinates: ( ";
2856 	min.display ( out , " " , 2 );
2857 	out << " )" << std::endl
2858 	<< "max. coordinates: ( ";
2859 	max.display ( out , " " , 2 );
2860 	out << " )" << std::endl
2861 	<< "center          : ( ";
2862 	center.display ( out , " " , 2 );
2863 	out << " )" << std::endl
2864 	<< "interp. radius  : ( ";
2865 	interpolation_radius.display ( out , " " , 2 );
2866 	out << " )" << std::endl
2867 	<< NOMAD::close_block() << std::endl;
2868  #endif
2869 
2870 	// create model:
2871 	// -------------
2872 	NOMAD::Clock       clock;
2873 	NOMAD::Model_Stats model_stats;
2874 	NOMAD::Quad_Model  model ( out                                              ,
2875 							  _p.get_bb_output_type()                          ,
2876 							  (ev_type==NOMAD::TRUTH) ? *_cache : *_sgte_cache ,
2877 							  *signature                                         );
2878 
2879 	int  max_Y_size = _p.get_model_quad_max_Y_size();
2880 	int  min_Y_size = _p.get_model_quad_min_Y_size();
2881 	bool use_WP     = _p.get_model_quad_use_WP    ();
2882 
2883 	// construct interpolation set Y:
2884 	model.construct_Y ( center               ,
2885 					   interpolation_radius ,
2886 					   max_Y_size             );
2887 
2888 	int nY = model.get_nY();
2889 
2890 #ifdef DEBUG
2891 	out << "number of points in Y: " << nY
2892 	<< " (p=" << nY-1;
2893 	if ( nY < 2 ) out << ", not enough";
2894 	out << ")" << std::endl;
2895  #endif
2896 
2897 	// not enough points:
2898 	if ( nY < 2 )
2899 	{
2900 		modified_list = false;
2901 		model_stats.add_not_enough_pts();
2902 	}
2903 	else
2904 	{
2905 
2906 #ifdef DEBUG
2907 		out << std::endl;
2908 		model.display_Y ( out , "unscaled interpolation set Y" );
2909 #endif
2910 
2911 		// define scaling:
2912 		model.define_scaling ( radius_factor );
2913 
2914 #ifdef DEBUG
2915 		out << std::endl;
2916 		model.display_Y ( out , "scaled interpolation set Ys" );
2917 #endif
2918 
2919 		// model error flag:
2920 		if ( model.get_error_flag() )
2921 		{
2922 			model_stats.add_construction_error();
2923 			modified_list = false;
2924 		}
2925 		else
2926 		{
2927 			// not enough points:
2928 			if ( nY < 2 || ( min_Y_size < 0 && nY <= model.get_nfree() ) )
2929 			{
2930 				model_stats.add_not_enough_pts();
2931 				modified_list = false;
2932 			}
2933 			// enough points and no error:
2934 			else
2935 			{
2936 
2937 				bool cautious         = _p.get_model_eval_sort_cautious();
2938 				int  nb_inside_radius = 0;
2939 
2940 				// check that there is at least two trial points inside the trust radius
2941 				// (cautious strategy):
2942 				nb_inside_radius = 0;
2943 				std::list<const NOMAD::Eval_Point *>::const_iterator it2 , end2 = pts.end();
2944 				if ( cautious )
2945 				{
2946 					for ( it2 = pts.begin() ; it2 != end2 ; ++it2 )
2947 					{
2948 						NOMAD::Point scaled_pt ( **it2 );
2949 						model.scale ( scaled_pt );
2950 						if ( model.is_within_trust_radius ( scaled_pt ) )
2951 						{
2952 							if ( ++nb_inside_radius == 2 )
2953 								break;
2954 						}
2955 					}
2956 				}
2957 
2958 				// not enough points inside trust radius:
2959 				if ( cautious && nb_inside_radius < 2 )
2960 					modified_list = false;
2961 
2962 				// at least two trial points are inside trust radius:
2963 				else
2964 				{
2965 					// construct model:
2966 					// ----------------
2967 					model.construct ( use_WP , NOMAD::SVD_EPS , NOMAD::SVD_MAX_MPN , max_Y_size );
2968 					model_stats.add_construction_time ( clock.get_CPU_time() );
2969 					model_stats.update_nY ( model.get_nY() );
2970 
2971 					// display model characteristics:
2972 #ifdef DEBUG
2973 					out << std::endl;
2974 					model.display_model_coeffs ( out );
2975 					out << std::endl;
2976 					model.display_Y_error ( out );
2977 #endif
2978 
2979 					// count model:
2980 					if ( ev_type == NOMAD::TRUTH )
2981 						model_stats.add_nb_truth();
2982 					else
2983 						model_stats.add_nb_sgte();
2984 
2985 					switch ( model.get_interpolation_type() )
2986 					{
2987 						case NOMAD::MFN:
2988 							model_stats.add_nb_MFN();
2989 							break;
2990 						case NOMAD::WP_REGRESSION:
2991 							model_stats.add_nb_WP_regression();
2992 							break;
2993 						case NOMAD::REGRESSION:
2994 							model_stats.add_nb_regression();
2995 							break;
2996 						default:
2997 							break;
2998 					}
2999 
3000 					// check model error flag:
3001 					const NOMAD::Double & cond = model.get_cond();
3002 					if ( model.get_error_flag()     ||
3003 						!cond.is_defined()         ||
3004 						cond > NOMAD::SVD_MAX_COND    )
3005 					{
3006 						modified_list = false;
3007 						if ( model.get_error_flag() )
3008 							model_stats.add_construction_error();
3009 						else
3010 							model_stats.add_bad_cond();
3011 					}
3012 					else
3013 					{
3014 						// clear then fill _eval_lop again:
3015 						// --------------------------------
3016 						NOMAD::Double         f_model , h_model;
3017 						NOMAD::Eval_Point   * x;
3018 						bool                  snap_to_bounds = _p.get_snap_to_bounds();
3019 
3020 						modified_list = true;
3021 						_eval_lop.clear();
3022 
3023 						nb_inside_radius = 0;
3024 
3025 #ifdef DEBUG
3026 						out << std::endl << NOMAD::open_block ( "original trial points" );
3027 #endif
3028 
3029 						NOMAD::Quad_Model_Evaluator *quad_model_ev=new NOMAD::Quad_Model_Evaluator(_p , model);
3030 
3031 						for ( it2 = pts.begin() ; it2 != end2 ; ++it2 )
3032 						{
3033 							NOMAD::Point scaled_pt ( **it2 );
3034 							model.scale ( scaled_pt );
3035 
3036 
3037 
3038 							f_model.clear();
3039 							h_model.clear();
3040 
3041 
3042 							if ( !cautious || model.is_within_trust_radius ( scaled_pt ) )
3043 							{
3044 
3045 								int m  = static_cast<int>(_p.get_bb_output_type().size());
3046 								NOMAD::Eval_Point x_eval(scaled_pt,m);
3047 								for (int i = 0 ; i < x_eval.size() ; ++i )
3048 									x_eval[i] = scaled_pt[i].value() * 1000.0;
3049 
3050 								bool count_eval;
3051 
3052 								bool success=quad_model_ev->eval_x(x_eval,0.0,count_eval);
3053 								if (success)
3054 								{
3055 									_ev->compute_f(x_eval);
3056 									_ev->compute_h(x_eval);
3057 
3058 									f_model=x_eval.get_f();
3059 									h_model=x_eval.get_h();
3060 								}
3061 
3062 								++nb_inside_radius;
3063 							}
3064 
3065 							x = &NOMAD::Cache::get_modifiable_point (**it2);
3066 
3067 #ifdef DEBUG
3068 							x->display_tag ( out );
3069 							out << ": ( ";
3070 							x->NOMAD::Point::display ( out , " " , 2 );
3071 							out << " ) scaled: (";
3072 							scaled_pt.NOMAD::Point::display ( out , " " , 2 );
3073 							out << ") ";
3074 							if ( h_model.is_defined() && f_model.is_defined() )
3075 								out << "hm=" << h_model << " fm=" << f_model;
3076 							else
3077 								out << "no model value";
3078 							out << std::endl;
3079 #endif
3080 
3081 							// add the evaluation point:
3082 							add_eval_point ( x               ,
3083 											display_degree  ,
3084 											snap_to_bounds  ,
3085 											NOMAD::Double() ,
3086 											NOMAD::Double() ,
3087 											f_model         ,
3088 											h_model           );
3089 
3090 #ifdef MODEL_STATS
3091 							if ( x && f_model.is_defined() && h_model.is_defined() )
3092 							{
3093 								x->set_mod_use  ( 2                ); // 2 for model ordering
3094 								x->set_cond     ( model.get_cond() );
3095 								x->set_Yw       ( model.get_Yw  () );
3096 								x->set_nY       ( model.get_nY  () );
3097 								x->set_mh       ( h_model          );
3098 								x->set_mf       ( f_model          );
3099 							}
3100 #endif
3101 						}
3102 
3103 						delete quad_model_ev;
3104 
3105 						// other points that have been previously discarded
3106 						// and have no model values:
3107 						end2 = other_pts.end();
3108 						for ( it2 = other_pts.begin() ; it2 != end2 ; ++it2 )
3109 						{
3110 
3111 							x = &NOMAD::Cache::get_modifiable_point (**it2);
3112 #ifdef DEBUG
3113 							x->display_tag ( out );
3114 							out << ": ( ";
3115 							x->NOMAD::Point::display ( out , " " , 2 );
3116 							out << " ) no model value" << std::endl;
3117 #endif
3118 							add_eval_point ( x               ,
3119 											display_degree  ,
3120 											snap_to_bounds  ,
3121 											NOMAD::Double() ,
3122 											NOMAD::Double() ,
3123 											NOMAD::Double() ,
3124 											NOMAD::Double()   );
3125 						}
3126 #ifdef DEBUG
3127 						out.close_block();
3128 #endif
3129 					}
3130 				}
3131 				model_stats.update_ES_stats ( nb_inside_radius , static_cast<int>(pts.size()) );
3132 			}
3133 		}
3134 	}
3135 
3136 	_stats.update_model_stats    ( model_stats );
3137 	_model_ordering_stats.update ( model_stats );
3138 
3139 #ifdef DEBUG
3140 	out << NOMAD::close_block() << std::endl;
3141 #else
3142 	if ( display_degree == NOMAD::FULL_DISPLAY )
3143 	{
3144 		out << std::endl << "model ordering";
3145 		if ( !modified_list )
3146 			out << " (no modification)";
3147 		out << std::endl;
3148 	}
3149 #endif
3150 }
3151 
3152 /*----------------------------------------------------------------------------------*/
3153 /*  evaluation of a list of points (public version that calls the private version)  */
3154 /*----------------------------------------------------------------------------------*/
eval_list_of_points(NOMAD::search_type search,NOMAD::Barrier & true_barrier,NOMAD::Barrier & sgte_barrier,NOMAD::Pareto_Front * pareto_front,bool & stop,NOMAD::stop_type & stop_reason,const NOMAD::Eval_Point * & new_feas_inc,const NOMAD::Eval_Point * & new_infeas_inc,NOMAD::success_type & success,std::list<const NOMAD::Eval_Point * > * evaluated_pts)3155 void NOMAD::Evaluator_Control::eval_list_of_points
3156 ( NOMAD::search_type              search             , // IN    : search type
3157   NOMAD::Barrier                & true_barrier       , // IN/OUT: truth barrier
3158   NOMAD::Barrier                & sgte_barrier       , // IN/OUT: surrogate barrier
3159   NOMAD::Pareto_Front           * pareto_front       , // IN/OUT: Pareto front
3160                                                        //         (can be NULL)
3161   bool                          & stop               , // IN/OUT: stopping criterion
3162   NOMAD::stop_type              & stop_reason        , // OUT   : stopping reason
3163   const NOMAD::Eval_Point      *& new_feas_inc       , // OUT   : new feas. incumbent
3164   const NOMAD::Eval_Point      *& new_infeas_inc     , // OUT   : new infeas. incumb.
3165   NOMAD::success_type           & success            , // OUT   : type of success
3166   std::list<const NOMAD::Eval_Point *>
3167                                 * evaluated_pts   )    // OUT   : list of processed
3168                                                        //         pts (can be NULL)
3169 {
3170 
3171   bool del_evaluated_pts = false;
3172   if ( !evaluated_pts )
3173   {
3174     evaluated_pts     = new std::list<const NOMAD::Eval_Point *>;
3175     del_evaluated_pts = true;
3176   }
3177 
3178   bool sgte_eval_sort = _p.get_sgte_eval_sort() && _eval_lop.size() > 1;
3179   bool opt_only_sgte  = _p.get_opt_only_sgte ();
3180   bool snap_to_bounds = _p.get_snap_to_bounds();
3181   bool modified_list  = false;
3182 
3183   const NOMAD::Display    & out = _p.out();
3184   NOMAD::dd_type display_degree = out.get_display_degree ( search );
3185 
3186   // reset the success type:
3187   true_barrier.reset_success();
3188   sgte_barrier.reset_success();
3189 
3190   // define all points as surrogates:
3191   if ( opt_only_sgte || sgte_eval_sort )
3192   {
3193     for ( std::set<NOMAD::Priority_Eval_Point>::iterator it = _eval_lop.begin() ;
3194 	  it != _eval_lop.end() ; ++it )
3195       NOMAD::Cache::get_modifiable_point(*it->get_point()).set_eval_type(NOMAD::SGTE);
3196   }
3197 
3198   // use the surrogates to sort the eval. points:
3199 	if ( !opt_only_sgte && sgte_eval_sort )
3200 	{
3201 
3202 		// evaluate the surrogate:
3203 		private_eval_list_of_points ( search         ,
3204 									 true_barrier   ,
3205 									 sgte_barrier   ,
3206 									 NULL           , // Pareto front = NULL
3207 									 stop           ,
3208 									 stop_reason    ,
3209 									 new_feas_inc   ,
3210 									 new_infeas_inc ,
3211 									 success        ,
3212 									 *evaluated_pts   );
3213 		if ( stop )
3214 		{
3215 			if ( del_evaluated_pts )
3216 				delete evaluated_pts;
3217 			return;
3218 		}
3219 
3220 		NOMAD::Eval_Point * x;
3221 
3222 		// construct a new list of trial points that will be
3223 		// ordered using surrogate values:
3224 		std::list<const NOMAD::Eval_Point *>::const_iterator
3225 		end = evaluated_pts->end() , it2;
3226 		for ( it2 = evaluated_pts->begin() ; it2 != end ; ++it2 ) {
3227 
3228 			// Eval_Point construction:
3229 			x = new NOMAD::Eval_Point;
3230 			x->set ( (*it2)->size() , _p.get_bb_nb_outputs() );
3231 			x->set_signature  ( (*it2)->get_signature () );
3232 			x->set_direction  ( (*it2)->get_direction () );
3233 			x->Point::operator = ( **it2 );
3234 
3235 			modified_list = true;
3236 
3237 			// add the new point to the ordered list of trial points:
3238 			add_eval_point ( x               ,
3239 							display_degree  ,
3240 							snap_to_bounds  ,
3241 							(*it2)->get_f() ,
3242 							(*it2)->get_h() ,
3243 							NOMAD::Double() ,
3244 							NOMAD::Double()   );
3245 		}
3246 	}
3247 
3248 	if ( stop ) {
3249 		if ( del_evaluated_pts )
3250 			delete evaluated_pts;
3251 		return;
3252 	}
3253 
3254 	// model ordering:
3255 	// ---------------
3256 	if ( !modified_list && _model_eval_sort && _eval_lop.size() > 1 )
3257     {
3258 		switch ( _p.get_model_eval_sort() ) {
3259 			case NOMAD::TGP_MODEL:
3260 				TGP_model_ordering ( display_degree , modified_list );
3261 				if ( NOMAD::Evaluator_Control::_force_quit || NOMAD::Evaluator::get_force_quit() )
3262                 {
3263 					stop        = true;
3264 					stop_reason = NOMAD::CTRL_C;
3265 				}
3266 				break;
3267 			case NOMAD::QUADRATIC_MODEL:
3268 				quad_model_ordering ( display_degree , modified_list );
3269 				break;
3270 			case NOMAD::NO_MODEL:;
3271 		}
3272 	}
3273 
3274   // this test is true if ctrl-c has been pressed:
3275   if ( stop ) {
3276     if ( del_evaluated_pts )
3277       delete evaluated_pts;
3278     return;
3279   }
3280 
3281   // display the re-ordered list of trial points:
3282   if ( modified_list && display_degree == NOMAD::FULL_DISPLAY ) {
3283 
3284     const NOMAD::Eval_Point * y;
3285 
3286     std::ostringstream oss;
3287     oss << "re-ordered list of " << _eval_lop.size()
3288 	<< " " << search << " trial points";
3289 
3290     out << NOMAD::open_block ( oss.str() ) << std::endl;
3291 
3292     std::set<NOMAD::Priority_Eval_Point>::const_iterator
3293       end = _eval_lop.end() , it;
3294     for ( it = _eval_lop.begin() ; it != end ; ++it ) {
3295       y =  it->get_point();
3296       y->display_tag ( out );
3297       out << ": ( ";
3298       y->Point::display ( out , " " , 2 , NOMAD::Point::get_display_limit() );
3299       out << " )";
3300       if ( y->get_direction() )
3301 	out << " (dir " << y->get_direction()->get_index() << ")";
3302       out << std::endl;
3303     }
3304     out.close_block();
3305   }
3306 
3307   // evaluate the list of points on the 'true' function:
3308   private_eval_list_of_points ( search         ,
3309 				true_barrier   ,
3310 				sgte_barrier   ,
3311 				pareto_front   ,
3312 				stop           ,
3313 				stop_reason    ,
3314 				new_feas_inc   ,
3315 				new_infeas_inc ,
3316 				success        ,
3317 				*evaluated_pts   );
3318 
3319 #ifdef MODEL_STATS
3320   display_model_stats ( *evaluated_pts );
3321 #endif
3322 
3323   if ( del_evaluated_pts )
3324     delete evaluated_pts;
3325 }
3326 
3327 /*------------------------------------------------------------------------------------*/
3328 /*  ordering of a list of points based on surrogate (1st) or model (2nd) evaluations  */
3329 /*------------------------------------------------------------------------------------*/
3330 
ordering_lop(NOMAD::search_type search,bool & stop,NOMAD::stop_type & stop_reason,NOMAD::Barrier & true_barrier,NOMAD::Barrier & sgte_barrier)3331 void NOMAD::Evaluator_Control::ordering_lop ( NOMAD::search_type             search             , // IN    : search type
3332 											 bool                          & stop               , // IN/OUT: stopping criterion
3333 											 NOMAD::stop_type              & stop_reason        , // OUT   : stopping reason
3334 											 NOMAD::Barrier                & true_barrier       , // IN/OUT: truth barrier
3335 											 NOMAD::Barrier                & sgte_barrier        // IN/OUT: surrogate barrier
3336 											 )
3337 
3338 {
3339 	std::list<const NOMAD::Eval_Point *> * evaluated_pts     = new std::list<const NOMAD::Eval_Point *>;
3340 
3341 	bool sgte_eval_sort = _p.get_sgte_eval_sort() && _eval_lop.size() > 1;
3342 	bool opt_only_sgte  = _p.get_opt_only_sgte ();
3343 	bool snap_to_bounds = _p.get_snap_to_bounds();
3344 	bool modified_list  = false;
3345 
3346 	const NOMAD::Display    & out = _p.out();
3347 	NOMAD::dd_type display_degree = out.get_display_degree ( search );
3348 
3349 	NOMAD::success_type success ;
3350 	const NOMAD::Eval_Point *new_feas_inc ;
3351 	const NOMAD::Eval_Point *new_infeas_inc;
3352 
3353 
3354 	// reset the success type:
3355 	true_barrier.reset_success();
3356 	sgte_barrier.reset_success();
3357 
3358 
3359 	// use the surrogates to sort the eval. points:
3360 	if ( !opt_only_sgte && sgte_eval_sort )
3361 	{
3362 
3363 		for ( std::set<NOMAD::Priority_Eval_Point>::iterator it = _eval_lop.begin() ; it != _eval_lop.end() ; ++it )
3364 			NOMAD::Cache::get_modifiable_point(*it->get_point()).set_eval_type(NOMAD::SGTE);
3365 
3366 
3367 		// evaluate the surrogate:
3368 		private_eval_list_of_points ( search         ,
3369 									 true_barrier   ,
3370 									 sgte_barrier   ,
3371 									 NULL           , // Pareto front = NULL
3372 									 stop           ,
3373 									 stop_reason    ,
3374 									 new_feas_inc   ,
3375 									 new_infeas_inc ,
3376 									 success        ,
3377 									 *evaluated_pts   );
3378 		if ( stop )
3379 		{
3380 			delete evaluated_pts;
3381 			return;
3382 		}
3383 
3384 		NOMAD::Eval_Point * x;
3385 
3386 		// construct a new list of trial points that will be
3387 		// ordered using surrogate values:
3388 		std::list<const NOMAD::Eval_Point *>::const_iterator
3389 		end = evaluated_pts->end() , it2;
3390 		for ( it2 = evaluated_pts->begin() ; it2 != end ; ++it2 )
3391 		{
3392 
3393 			// Eval_Point construction:
3394 			x = new NOMAD::Eval_Point;
3395 			x->set ( (*it2)->size() , _p.get_bb_nb_outputs() );
3396 			x->set_signature  ( (*it2)->get_signature () );
3397 			x->set_direction  ( (*it2)->get_direction () );
3398 			x->set_poll_center( (*it2)->get_poll_center () );  // Poll center is needed for further testing (not needed when evaluating points)
3399 			x->set_poll_center_type ( (*it2)->get_poll_center_type ()   );
3400 			x->Point::operator = ( **it2 );
3401 
3402 			modified_list = true;
3403 
3404 			// add the new point to the ordered list of trial points:
3405 			add_eval_point ( x               ,
3406 							display_degree  ,
3407 							snap_to_bounds  ,
3408 							(*it2)->get_f() ,
3409 							(*it2)->get_h() ,
3410 							NOMAD::Double() ,
3411 							NOMAD::Double()   );
3412 		}
3413 	}
3414 
3415 	// model ordering:
3416 	// ---------------
3417 	if ( !modified_list && _model_eval_sort && _eval_lop.size() > 1 ) {
3418 		switch ( _p.get_model_eval_sort() ) {
3419 			case NOMAD::TGP_MODEL:
3420 				TGP_model_ordering ( display_degree , modified_list );
3421 				break;
3422 			case NOMAD::QUADRATIC_MODEL:
3423 				quad_model_ordering ( display_degree , modified_list );
3424 				break;
3425 			case NOMAD::NO_MODEL:;
3426 		}
3427 	}
3428 
3429 	if ( NOMAD::Evaluator_Control::_force_quit || NOMAD::Evaluator::get_force_quit() )
3430 	{
3431 		stop        = true;
3432 		stop_reason = NOMAD::CTRL_C;
3433 	}
3434 
3435 	delete evaluated_pts;
3436 }
3437 
3438 
3439 
3440 /*--------------------------------------------------------------*/
3441 /*  return if a series of evaluations is opportunistic or not,  */
3442 /*  depending on the search type (private)                      */
3443 /*--------------------------------------------------------------*/
is_opportunistic(NOMAD::search_type t) const3444 bool NOMAD::Evaluator_Control::is_opportunistic ( NOMAD::search_type t ) const
3445 {
3446   switch ( t ) {
3447   case NOMAD::X0_EVAL:
3448     return false;
3449   case NOMAD::LH_SEARCH:
3450     return _p.get_opportunistic_LH();
3451   case NOMAD::CACHE_SEARCH:
3452     return _p.get_opportunistic_cache_search();
3453   default:
3454     return _p.get_opportunistic_eval();
3455   }
3456   return false;
3457 }
3458 
3459 /*----------------------------------------------------------------*/
3460 /*                     stop the evaluations ?                     */
3461 /*----------------------------------------------------------------*/
3462 /* . check the opportunistic strategy stopping criterion          */
3463 /* . private method                                               */
3464 /*----------------------------------------------------------------*/
stop_evaluations(const NOMAD::Eval_Point & x,NOMAD::search_type search,int k,int nb_points,bool stop,NOMAD::dd_type display_degree,NOMAD::success_type one_eval_success,NOMAD::success_type success,int init_nb_eval,const NOMAD::Double & f0,const NOMAD::Barrier & barrier,int & nb_success,bool & one_for_luck) const3465 bool NOMAD::Evaluator_Control::stop_evaluations
3466 ( const NOMAD::Eval_Point & x                ,
3467   NOMAD::search_type        search           ,
3468   int                       k                ,
3469   int                       nb_points        ,
3470   bool                      stop             ,
3471   NOMAD::dd_type            display_degree   ,
3472   NOMAD::success_type       one_eval_success ,
3473   NOMAD::success_type       success          ,
3474   int                       init_nb_eval     ,
3475   const NOMAD::Double     & f0               ,
3476   const NOMAD::Barrier    & barrier          ,
3477   int                     & nb_success       ,
3478   bool                    & one_for_luck       ) const
3479 {
3480 	// opportunistic evaluation ?
3481 	bool opportunistic = is_opportunistic ( search );
3482 
3483 	if ( k < nb_points - 1 ) {
3484 
3485 		if ( stop )
3486 			return true;
3487 
3488 		if ( opportunistic &&
3489 			( x.get_eval_type() == NOMAD::TRUTH || _p.get_opt_only_sgte() ) )
3490 		{
3491 
3492 			if ( one_for_luck && one_eval_success != NOMAD::FULL_SUCCESS )
3493 			{
3494 				if ( display_degree == NOMAD::FULL_DISPLAY )
3495 					_p.out() << std::endl
3496 					<< "opportunistic termination of evaluations (lucky eval)"
3497 					<< std::endl;
3498 				return true;
3499 			}
3500 
3501 			if ( success == NOMAD::FULL_SUCCESS &&
3502 				check_opportunistic_criterion ( display_degree   ,
3503 											   one_eval_success ,
3504 											   init_nb_eval     ,
3505 											   f0               ,
3506 											   barrier          ,
3507 											   nb_success       ,
3508 											   one_for_luck       ) )
3509 				return true;
3510 		}
3511 	}
3512 	return false;
3513 }
3514 
3515 /*-----------------------------------------------------------------*/
3516 /*  check the opportunistic strategy stopping criterion (private)  */
3517 /*            return true to stop the evaluations                  */
3518 /*            return false to continue the evaluations             */
3519 /*-----------------------------------------------------------------*/
check_opportunistic_criterion(NOMAD::dd_type display_degree,NOMAD::success_type one_eval_success,int init_nb_eval,const NOMAD::Double & f0,const NOMAD::Barrier & barrier,int & nb_success,bool & one_for_luck) const3520 bool NOMAD::Evaluator_Control::check_opportunistic_criterion
3521 ( NOMAD::dd_type         display_degree   ,
3522   NOMAD::success_type    one_eval_success ,
3523   int                    init_nb_eval     ,
3524   const NOMAD::Double  & f0               ,
3525   const NOMAD::Barrier & barrier          ,
3526   int                  & nb_success       ,
3527   bool                 & one_for_luck       ) const
3528 {
3529 
3530 	int                    min_nb_success = _p.get_opportunistic_min_nb_success();
3531 	int                    min_eval       = _p.get_opportunistic_min_eval();
3532 	NOMAD::Double          min_f_imprvmt  = _p.get_opportunistic_min_f_imprvmt();
3533 	bool                   lucky_eval     = _p.get_opportunistic_lucky_eval();
3534 	const NOMAD::Display & out            = _p.out();
3535 
3536 	// min_nb_success:
3537 	if ( min_nb_success > 0 )
3538 	{
3539 
3540 		if ( one_eval_success == NOMAD::FULL_SUCCESS )
3541 			++nb_success;
3542 
3543 		if ( nb_success < min_nb_success )
3544 		{
3545 
3546 			if ( display_degree == NOMAD::FULL_DISPLAY )
3547 				out << std::endl
3548 				<< "opport. strategy (nb_success=" << nb_success
3549 				<< " < min_nb_success=" << min_nb_success
3550 				<< "): continue evaluations"
3551 				<< std::endl;
3552 
3553 			return false;
3554 		}
3555 	}
3556 
3557 	// min_eval:
3558 	if ( min_eval > 0 )
3559 	{
3560 
3561 		int eval = _stats.get_eval() - init_nb_eval;
3562 
3563 		if ( eval < min_eval )
3564 		{
3565 
3566 			if ( display_degree == NOMAD::FULL_DISPLAY )
3567 				out << std::endl
3568 				<< "opport. strategy (eval=" << eval
3569 				<< " < min_eval=" << min_eval
3570 				<< "): continue evaluations" << std::endl;
3571 			return false;
3572 		}
3573 	}
3574 
3575 	// min_f_imprvmt:
3576 	if ( min_f_imprvmt.is_defined() )
3577 	{
3578 
3579 		const NOMAD::Eval_Point * bf = barrier.get_best_feasible();
3580 
3581 		if ( f0.is_defined() && bf )
3582 		{
3583 
3584 			NOMAD::Double f = bf->get_f();
3585 
3586 			if ( f.is_defined() )
3587 			{
3588 
3589 				NOMAD::Double f_imprvmt = f0.rel_err(f) * 100.0;
3590 
3591 				if ( f_imprvmt < min_f_imprvmt )
3592 				{
3593 
3594 					if ( display_degree == NOMAD::FULL_DISPLAY )
3595 						out << std::endl
3596 						<< "opport. strategy (f_improvement="
3597 						<< f_imprvmt << " < min_f_imprvmt=" << min_f_imprvmt
3598 						<< "): continue evaluations" << std::endl;
3599 
3600 					return false;
3601 				}
3602 			}
3603 		}
3604 	}
3605 
3606 	// lucky_eval:
3607 	if ( lucky_eval && one_eval_success == NOMAD::FULL_SUCCESS )
3608 	{
3609 		one_for_luck = true;
3610 
3611 		if ( display_degree == NOMAD::FULL_DISPLAY )
3612 			out << std::endl
3613 			<< "opport. strategy: one more evaluation for luck"
3614 			<< std::endl;
3615 
3616 		return false;
3617 	}
3618 
3619 	if ( display_degree == NOMAD::FULL_DISPLAY )
3620 	{
3621 		out << std::endl << "opport. strategy: stop evaluations" ;
3622 		if (_p.get_bb_max_block_size() > 1)
3623 			out << " at the end of the block evaluation";
3624 		out << std::endl;
3625 	}
3626 
3627 	return true;
3628 }
3629 
3630 /*---------------------------------------------------------------*/
3631 /*        display the list of evaluation points (_eval_lop)      */
3632 /*---------------------------------------------------------------*/
display_eval_lop(NOMAD::search_type t) const3633 void NOMAD::Evaluator_Control::display_eval_lop ( NOMAD::search_type t ) const
3634 {
3635   const NOMAD::Display & out = _p.out();
3636   int cnt = 0 , nb = static_cast<int>(_eval_lop.size());
3637 
3638   if ( nb == 0 ) {
3639     out << std::endl << "no evaluation point" << std::endl;
3640     return;
3641   }
3642 
3643   // open indented block:
3644   std::ostringstream oss;
3645   if ( t != NOMAD::UNDEFINED_SEARCH )
3646     oss << t << " ";
3647   oss << "evaluation point";
3648   if ( nb > 1 )
3649     oss << "s";
3650   out << std::endl << NOMAD::open_block ( oss.str() ) << std::endl;
3651 
3652   // display the points:
3653   std::set<NOMAD::Priority_Eval_Point>::const_iterator it , end = _eval_lop.end();
3654   for ( it = _eval_lop.begin() ; it != end ; ++it ) {
3655     out << "point ";
3656     out.display_int_w ( ++cnt , nb );
3657     out << "/" << nb << ": ( ";
3658     it->get_point()->Point::display ( out                               ,
3659 				      " "                               ,
3660 				      2                                 ,
3661 				      NOMAD::Point::get_display_limit()   );
3662     out << " )" << std::endl;
3663   }
3664 
3665   // close indented block:
3666   out.close_block();
3667 }
3668 
3669 /*--------------------------------------------------------------*/
3670 /*    add an Eval_Point to the list of points to be evaluated   */
3671 /*--------------------------------------------------------------*/
3672 /*  . x has to be a dynamic object                              */
3673 /*  . it may be deleted into the method and be NULL after that  */
3674 /*  . the point is also snapped to bounds                       */
3675 /*  . periodic variables are checked                            */
3676 /*--------------------------------------------------------------*/
add_eval_point(NOMAD::Eval_Point * & x,NOMAD::dd_type display_degree,bool snap_to_bounds,const NOMAD::Double & f_sgte,const NOMAD::Double & h_sgte,const NOMAD::Double & f_model,const NOMAD::Double & h_model)3677 void NOMAD::Evaluator_Control::add_eval_point( NOMAD::Eval_Point  *& x              ,
3678 											  NOMAD::dd_type        display_degree ,
3679 											  bool                  snap_to_bounds ,
3680 											  const NOMAD::Double & f_sgte         ,
3681 											  const NOMAD::Double & h_sgte         ,
3682 											  const NOMAD::Double & f_model        ,
3683 											  const NOMAD::Double & h_model         )
3684 {
3685 	if ( !x )
3686 		return;
3687 
3688 	const NOMAD::Display & out = _p.out();
3689 
3690 	// treat the periodic variables:
3691 	NOMAD::Direction * new_dir = NULL;
3692 
3693 	if ( _p.has_periodic_variables() &&
3694 		x->treat_periodic_variables ( new_dir ) )
3695 	{
3696 
3697 		if ( new_dir && new_dir->norm() == 0.0 )
3698 		{
3699 
3700 			if ( display_degree == NOMAD::FULL_DISPLAY )
3701 				out << "point #" << x->get_tag()
3702 				<< " is flushed (||dir||==0)"
3703 				<< std::endl;
3704 
3705 			delete x;
3706 			x = NULL;
3707 
3708 			delete new_dir;
3709 
3710 			return;
3711 		}
3712 	}
3713 	delete new_dir;
3714 
3715 	if ( snap_to_bounds && x->snap_to_bounds() )
3716 	{
3717 
3718 		if ( display_degree == NOMAD::FULL_DISPLAY )
3719 		{
3720 			out << std::endl << "point #" << x->get_tag() << " ";
3721 			if ( x->get_direction() && x->get_direction()->get_index() >= 0 )
3722 				out << "(dir " << x->get_direction()->get_index() << ") ";
3723 			out << "has been snapped to bounds" << std::endl;
3724 		}
3725 
3726 		if ( x->get_direction() && x->get_direction()->norm() == 0.0 )
3727 		{
3728 
3729 			if ( display_degree == NOMAD::FULL_DISPLAY )
3730 				out << "point #" << x->get_tag()
3731 				<< " is flushed (||dir||==0)"
3732 				<< std::endl;
3733 			delete x;
3734 			x = NULL;
3735 
3736 			return;
3737 		}
3738 	}
3739 
3740 	// creation of the Priority_Eval_Point:
3741 	NOMAD::Priority_Eval_Point pep ( x , _p.get_h_min() );
3742 
3743 	// ordering elements of Priority_Eval_Point's:
3744 	// -------------------------------------------
3745 
3746 	// 1. surrogate values for f and h:
3747 	pep.set_f_sgte ( f_sgte );
3748 	pep.set_h_sgte ( h_sgte );
3749 
3750 	// 2. model values for f and h:
3751 	pep.set_f_model ( f_model );
3752 	pep.set_h_model ( h_model );
3753 
3754 	if ( x->get_direction() )
3755 	{
3756 
3757 		// get the signature:
3758 		NOMAD::Signature * signature = x->get_signature();
3759 		if ( !signature )
3760 			throw NOMAD::Exception ( "Evaluator_Control.cpp" , __LINE__ ,
3761 									"Evaluator_Control::add_eval_point(): the point has no signature" );
3762 
3763 		// angle with last successful directions (feasible)
3764 		const NOMAD::Direction & feas_success_dir = signature->get_feas_success_dir();
3765 		if ( feas_success_dir.is_defined() &&
3766 			x->get_poll_center_type() == NOMAD::FEASIBLE  )
3767 			pep.set_angle_success_dir ( feas_success_dir.get_angle ( *x->get_direction() ) );
3768 
3769 		// angle with last infeasible success direction:
3770 		const NOMAD::Direction & infeas_success_dir = signature->get_infeas_success_dir();
3771 		if ( infeas_success_dir.is_defined() &&
3772 			x->get_poll_center_type() == NOMAD::INFEASIBLE  )
3773 			pep.set_angle_success_dir ( infeas_success_dir.get_angle ( *x->get_direction() ) );
3774 
3775 	}
3776 
3777 
3778 
3779 	// insertion of the point in _eval_lop:
3780 	// ------------------------------------
3781 	size_t size_before = _eval_lop.size();
3782 
3783 	_eval_lop.insert ( pep );
3784 
3785 	if ( _eval_lop.size() == size_before )
3786 	{
3787 		delete x;
3788 		x = NULL;
3789 	}
3790 }
3791 
3792 #ifdef MODEL_STATS
3793 /*------------------------------------------------------------------*/
3794 /*  display stats on an evaluation for which a model has been used  */
3795 /*------------------------------------------------------------------*/
3796 /*  The displayed stats are:                                        */
3797 /*                                                                  */
3798 /*     use (1:model_search, 2:model_ordering)                       */
3799 /*     mesh_index                                                   */
3800 /*     cardinality of Y                                             */
3801 /*     width of Y                                                   */
3802 /*     Y condition number                                           */
3803 /*     h value, model for h, relative error (if constraints)        */
3804 /*     f value, model for f, relative error                         */
3805 /*                                                                  */
3806 /*------------------------------------------------------------------*/
display_model_stats(const std::list<const NOMAD::Eval_Point * > & evaluated_pts) const3807 void NOMAD::Evaluator_Control::display_model_stats
3808 ( const std::list<const NOMAD::Eval_Point *> & evaluated_pts ) const
3809 {
3810   const NOMAD::Display & out = _p.out();
3811 
3812   NOMAD::Double h , mh , eh , f , mf , ef;
3813 
3814   std::list<const NOMAD::Eval_Point *>::const_iterator it , end = evaluated_pts.end();
3815   for ( it = evaluated_pts.begin() ; it != end ; ++it ) {
3816     if ( *it && (*it)->get_mod_use() >= 0 ) {
3817 
3818       if ( _p.has_constraints() ) {
3819 	h  = (*it)->get_h ();
3820 	mh = (*it)->get_mh();
3821       }
3822       else
3823 	h = mh = 0.0;
3824 
3825       f  = (*it)->get_f ();
3826       mf = (*it)->get_mf();
3827 
3828       if ( h.is_defined() && mh.is_defined() && f.is_defined() && mf.is_defined() ) {
3829 
3830 	ef = f.rel_err ( mf ) * 100.0;
3831 
3832 	out << (*it)->get_mod_use()
3833 	    << " " << std::setw(3) << NOMAD::Mesh::get_mesh_index()
3834 	    << " " << std::setw(4) << (*it)->get_nY()
3835 	    << " ";
3836 
3837 	(*it)->get_Yw  ().display ( out , "%12.3g" ); out << " ";
3838 	(*it)->get_cond().display ( out , "%12.3g" ); out << " ";
3839 	if ( _p.has_constraints() ) {
3840 	  eh = h.rel_err ( mh ) * 100.0;
3841 	  h.display  ( out , "%14.3g" ); out << " ";
3842 	  mh.display ( out , "%14.3g" ); out << " ";
3843 	  eh.display ( out , "%14.3g" ); out << " ";
3844 	}
3845 	f.display  ( out , "%14.3g" ); out << " ";
3846 	mf.display ( out , "%14.3g" ); out << " ";
3847 	ef.display ( out , "%14.3g" );
3848 
3849 	out << std::endl;
3850       }
3851 
3852       (*it)->clear_model_data();
3853     }
3854   }
3855 }
3856 #endif
3857