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 ¢er ,
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