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 Mads.hpp 38 \brief MADS algorithm (headers) 39 \author Sebastien Le Digabel 40 \date 2010-04-20 41 \see Mads.cpp 42 */ 43 #ifndef __MADS__ 44 #define __MADS__ 45 46 #include "Quad_Model_Search.hpp" 47 #include "Speculative_Search.hpp" 48 #include "LH_Search.hpp" 49 #include "VNS_Search.hpp" 50 #include "Cache_Search.hpp" 51 #include "Phase_One_Search.hpp" 52 #include "L_Curve.hpp" 53 #include "Extended_Poll.hpp" 54 55 #include "XMesh.hpp" 56 #include "SMesh.hpp" 57 58 #ifdef USE_TGP 59 #include "TGP_Model_Search.hpp" 60 #endif 61 62 namespace NOMAD { 63 64 // forward declaration of Extended_Poll: 65 class Extended_Poll; 66 67 /// The MADS algorithm. 68 class Mads : private NOMAD::Uncopyable { 69 70 private: 71 72 static bool _force_quit; ///< Forces NOMAD to terminate if Ctrl-C is pressed. 73 74 NOMAD::Parameters & _p; ///< Parameters. 75 NOMAD::Stats _stats; ///< Statistics. 76 NOMAD::Evaluator_Control _ev_control; ///< Evaluator control. 77 NOMAD::Evaluator_Control _ev_control_for_sorting; ///< Evaluator control. 78 NOMAD::Barrier _true_barrier; ///< Barrier for true function evaluations. 79 NOMAD::Barrier _sgte_barrier; ///< Barrier for surrogate evaluations. 80 81 NOMAD::OrthogonalMesh * _mesh; ///< Access to the OrthogonalMesh 82 83 /// Pareto front for multi-objective optimization. 84 NOMAD::Pareto_Front * _pareto_front; 85 86 /// User search defined with NOMAD::Mads::set_user_search(). 87 NOMAD::Search * _user_search; 88 89 NOMAD::Search * _model_search1; ///< Model search #1. 90 NOMAD::Search * _model_search2; ///< Model search #2. 91 92 NOMAD::Search * _VNS_search; ///< VNS search. 93 NOMAD::Search * _cache_search; ///< Cache search. 94 NOMAD::L_Curve * _L_curve; ///< L-curve target. 95 NOMAD::Extended_Poll * _extended_poll; ///< Extended poll for categorical variables. 96 bool _user_ext_poll; ///< Flag for user-defined extended poll. 97 98 // MADS flags (these are not parameters as users do not modify them): 99 100 static bool _flag_check_bimads; ///< Flag for the multi-objective test in \c run(). 101 static bool _flag_reset_mesh; ///< Reset or not the mesh before a MADS run. 102 static bool _flag_reset_barriers; ///< Reset or not the barriers before a MADS run. 103 static bool _flag_p1_active; ///< Flag equal to \c true if phase one is active. 104 105 /*-----------------------------------------------------------------------------*/ 106 107 /// Initializations. 108 void init ( void ); 109 110 /// Starting point evaluation. 111 /** 112 \param stop Stop flag -- \b IN/OUT. 113 \param stop_reason Stop reason -- \b OUT. 114 */ 115 void eval_x0 ( bool & stop , NOMAD::stop_type & stop_reason ); 116 117 /// One MADS iteration. 118 /** 119 \param stop Stop flag -- \b IN/OUT. 120 \param stop_reason Stop reason -- \b OUT. 121 \param success Success for this iteration -- \b OUT. 122 \param new_feas_inc Pointer to the new feasible incumbent -- \b OUT. 123 \param new_infeas_inc Pointer to the new infeasible incumbent -- \b OUT. 124 */ 125 void iteration ( bool & stop , 126 NOMAD::stop_type & stop_reason , 127 NOMAD::success_type & success , 128 const NOMAD::Eval_Point *& new_feas_inc , 129 const NOMAD::Eval_Point *& new_infeas_inc ); 130 131 /// The search step. 132 /** 133 \param stop Stop flag -- \b IN/OUT. 134 \param stop_reason Stop reason -- \b OUT. 135 \param success Success for this step -- \b OUT. 136 \param new_feas_inc Pointer to the new feasible incumbent -- \b OUT. 137 \param new_infeas_inc Pointer to the new infeasible incumbent -- \b OUT. 138 */ 139 void search ( bool & stop , 140 NOMAD::stop_type & stop_reason , 141 NOMAD::success_type & success , 142 const NOMAD::Eval_Point *& new_feas_inc , 143 const NOMAD::Eval_Point *& new_infeas_inc ); 144 145 /// The poll step. 146 /** 147 \param stop Stop flag -- \b IN/OUT. 148 \param stop_reason Stop reason -- \b OUT. 149 \param success Success for this step -- \b OUT. 150 \param new_feas_inc Pointer to the new feasible incumbent -- \b OUT. 151 \param new_infeas_inc Pointer to the new infeasible incumbent -- \b OUT. 152 \param forbid_poll_size_stop Boolean used to check if the min poll 153 size stopping criterion has to be 154 disabled for integer variables -- \b OUT. 155 */ 156 void poll ( bool & stop, 157 NOMAD::stop_type & stop_reason, 158 NOMAD::success_type & success, 159 const NOMAD::Eval_Point *& new_feas_inc, 160 const NOMAD::Eval_Point *& new_infeas_inc, 161 bool & forbid_poll_size_stop ); 162 163 /// Sets the poll trial points from poll direction, poll center and mesh size 164 /** 165 \param stop Stop flag -- \b IN/OUT. 166 \param stop_reason Stop reason -- \b OUT. 167 \param dirs List of directions for the poll -- \b IN. 168 \param poll_center the poll center (can be null) -- \b IN. 169 \param offset Dir index offset for primary and sec. poll center -- \b IN. 170 \param sorting If true than the points are for sorting -- \b IN. 171 */ 172 void set_poll_trial_points ( std::list<NOMAD::Direction> & dirs, 173 size_t offset, 174 const NOMAD::Eval_Point & poll_center, 175 bool & stop, 176 NOMAD::stop_type &stop_reason, 177 bool sorting); 178 179 180 /// Compute a prospect point by optimization on quadratic models. 181 /** 182 \param poll_center The poll center -- \b IN. 183 \param dirs The directions that delimit the hypercube for optimization -- \b IN. 184 \param prospect_point The prospect point -- \b OUT. 185 \return A flag equal to \c true if the prospect direction has been computed. 186 */ 187 bool optimize_quad_model ( const NOMAD::Eval_Point & poll_center , 188 const std::list<NOMAD::Direction> & dirs , 189 NOMAD::Point & prospect_point ) ; 190 191 192 /// Sets the poll directions from signature, poll center and mesh size 193 /** 194 \param dirs List of directions for the poll -- \b OUT. 195 \param i_pc Poll type -- \b IN. 196 \param offset Dir index offset for primary and sec. poll center -- \b IN. 197 \param poll_center The poll center -- \b IN. 198 \param stop Stop flag, true if cannot get direction -- \b IN/OUT. 199 \param stop_reason Stop type -- \b OUT. 200 */ 201 void set_poll_directions ( std::list<NOMAD::Direction> & dirs , 202 NOMAD::poll_type i_pc , 203 size_t offset , 204 const NOMAD::Eval_Point & poll_center , 205 bool & stop , 206 NOMAD::stop_type & stop_reason ); 207 208 /// Reduce the number of poll directions -> n 209 /** 210 \param dirs List of directions for the poll -- \b IN/OUT. 211 \param poll_center the poll center -- \b IN. 212 \return success for this step. 213 */ 214 bool set_reduced_poll_to_n_directions(std::list<NOMAD::Direction> & dirs, 215 const NOMAD::Eval_Point & poll_center); 216 217 /// Compute the rank of a list of directions 218 /** 219 \param dirs List of directions for the poll -- \b IN/OUT. 220 \return rank>0 of the dirs if successfull or 0 if rank cannot be evaluated 221 */ 222 int get_rank_from_dirs(const std::list<NOMAD::Direction> & dirs); 223 224 225 /// Check the directions after the poll step. 226 /** 227 \param forbid_poll_size_stop Boolean equal to \c true if 228 the \c MIN_POLL_SIZE parameter is valid for 229 the last set of poll directions -- \b OUT. 230 */ 231 void check_directions ( bool & forbid_poll_size_stop ); 232 233 /// Update of the success directions. 234 /** 235 - Occurs after the poll. 236 \param new_inc Pointer to the new incumbent -- \b IN (may be \c NULL). 237 \param feasible Flag equal to \c true if the incumbent is feasible -- \b IN. 238 */ 239 void update_success_directions ( const NOMAD::Eval_Point * new_inc , 240 bool feasible ) const; 241 242 /// Launch a single-objective MADS run for multi-objective optimization. 243 /** 244 \param display_degree Display degree -- \b IN. 245 \param mads_runs Total number of MADS runs to execute -- \b IN. 246 \param overall_bbe Global maximum number of blackbox evaluations -- \b IN. 247 \param ev Evaluator for multi-objective -- \b IN/OUT. 248 \param stagnation_cnt Counter to detect a stagnation -- \b IN/OUT. 249 \param multi_stats Stats for multi-objective -- \b IN/OUT. 250 \param stop Stop flag -- \b IN/OUT. 251 \param stop_reason Stop reason -- \b OUT. 252 */ 253 void multi_launch_single_opt ( NOMAD::dd_type display_degree , 254 int mads_runs , 255 int overall_bbe , 256 NOMAD::Multi_Obj_Evaluator & ev , 257 int & stagnation_cnt , 258 NOMAD::Stats & multi_stats , 259 bool & stop , 260 NOMAD::stop_type & stop_reason ); 261 262 /// Compute and set the minimal poll size for multi-objective optimization. 263 /** 264 \param lb Lower bounds -- \b IN. 265 \param ub Upper bounds -- \b IN. 266 \param delta_p_0 Initial poll size -- \b IN. 267 \param delta_j Delta criterion for multi-objective -- \b IN/OUT. 268 */ 269 void multi_set_min_poll_size ( const NOMAD::Point & lb , 270 const NOMAD::Point & ub , 271 const NOMAD::Point & delta_p_0 , 272 NOMAD::Double delta_j ); 273 274 // Display mesh and poll sizes for a given signature. 275 /** 276 \param s The signature -- \b IN. 277 */ 278 void display_deltas ( const NOMAD::Signature & s ) const; 279 280 /// Displays at the beginning of an iteration. 281 void display_iteration_begin ( void ) const; 282 283 /// Displays at the end of an iteration. 284 /** 285 \param stop Stop flag -- \b IN. 286 \param stop_reason Stop reason -- \b IN. 287 \param success Iteration success -- \b IN. 288 \param new_feas_inc Pointer to the new feasible incumbent -- \b IN. 289 \param new_infeas_inc Pointer to the new infeasible incumbent -- \b IN. 290 */ 291 void display_iteration_end ( bool stop , 292 NOMAD::stop_type stop_reason , 293 NOMAD::success_type success , 294 const NOMAD::Eval_Point * new_feas_inc , 295 const NOMAD::Eval_Point * new_infeas_inc ) const; 296 297 298 /// Determine dynamic directions from a set of directions. 299 /** 300 - The computed opposite directions already include Delta^k_m. 301 \param dirs List of existing directions (no snap to bounds) -- \b IN. 302 \param newDirs New dynamic directions -- \b OUT. 303 \param poll_center Poll center -- \b IN. 304 \return true if new dynamic direction generated false otherwise 305 */ 306 bool get_dynamic_directions (const std::list<NOMAD::Direction> & dirs, 307 std::list<NOMAD::Direction> & newDirs, 308 const NOMAD::Eval_Point & poll_center) ; 309 310 311 312 /// Check if a set of directions include Ortho-MADS N+1 direction. 313 /** 314 \param dirs List of directions -- \b IN. 315 \return A boolean equal to \c true if at 316 least one direction in the set is 317 of type Ortho-MADS N+1. 318 */ 319 bool dirs_have_orthomads_np1 ( const std::list<NOMAD::Direction> & dirs ); 320 321 322 /// Check if a dir needs to be obtained from model optimization 323 /** 324 \param dirs List of directions -- \b IN. 325 \return A boolean equal to \c true if all directions are of type Ortho-MADS N+1 QUAD. 326 */ 327 bool dir_from_model_opt( const std::list<NOMAD::Direction> & dirs); 328 329 330 /// get a single direction using quad model optimization or sum of negatives 331 /** 332 \param dirs Reduced poll directions (no snap to bounds) -- \b IN. 333 \param poll_center Poll center -- \b IN. 334 \return new direction 335 */ 336 NOMAD::Direction get_single_dynamic_direction (const std::list<NOMAD::Direction> & dirs, 337 const NOMAD::Eval_Point & poll_center) ; 338 339 340 /*-----------------------------------------------------------------------------*/ 341 342 public: 343 344 /// Constructor #1. 345 /** 346 - Basic version. 347 \param p Parameters -- \b IN. 348 \param ev A pointer to the evaluator -- \b IN 349 -- \b optional (default = \c NULL). 350 */ Mads(NOMAD::Parameters & p,NOMAD::Evaluator * ev=NULL)351 Mads ( NOMAD::Parameters & p , NOMAD::Evaluator * ev = NULL ) 352 : _p ( p ) , 353 _stats ( p.get_sgte_cost() ) , 354 _ev_control ( p , _stats , ev , NULL , NULL ) , 355 _ev_control_for_sorting( p , _stats , _ev_control.get_evaluator() , &(_ev_control.get_cache()) , &(_ev_control.get_sgte_cache()) ) , 356 _true_barrier ( p , NOMAD::TRUTH ) , 357 _sgte_barrier ( p , NOMAD::SGTE ) , 358 _mesh ( p.get_signature()->get_mesh() ) , 359 _pareto_front ( NULL ) , 360 _user_search ( NULL ) , 361 _model_search1 ( NULL ) , 362 _model_search2 ( NULL ) , 363 _VNS_search ( NULL ) , 364 _cache_search ( NULL ) , 365 _L_curve ( NULL ) , 366 _extended_poll ( NULL ) , 367 _user_ext_poll ( false ) { init(); } 368 369 /// Constructor #2. 370 /** 371 - Advanced version. 372 \param p Parameters -- \b IN. 373 \param ev A pointer to the evaluator -- \b IN (may be \c NULL). 374 \param extended_poll A pointer to a NOMAD::Extended_Poll object 375 -- \b IN (may be \c NULL). 376 \param cache A pointer to a cache -- \b IN (may be \c NULL). 377 \param sgte_cache A pointer to a cache for surrogates 378 -- \b IN (may be \c NULL). 379 */ Mads(NOMAD::Parameters & p,NOMAD::Evaluator * ev,NOMAD::Extended_Poll * extended_poll,NOMAD::Cache * cache,NOMAD::Cache * sgte_cache)380 Mads ( NOMAD::Parameters & p , 381 NOMAD::Evaluator * ev , // may be NULL 382 NOMAD::Extended_Poll * extended_poll , // may be NULL 383 NOMAD::Cache * cache , // may be NULL 384 NOMAD::Cache * sgte_cache ) // may be NULL 385 : _p ( p ) , 386 _stats ( p.get_sgte_cost() ) , 387 _ev_control ( p , _stats , ev , cache , sgte_cache ) , 388 _ev_control_for_sorting( p , _stats , _ev_control.get_evaluator() , cache , sgte_cache ) , 389 _true_barrier ( p , NOMAD::TRUTH ) , 390 _sgte_barrier ( p , NOMAD::SGTE ) , 391 _mesh ( p.get_signature()->get_mesh() ) , 392 _pareto_front ( NULL ) , 393 _user_search ( NULL ) , 394 _model_search1 ( NULL ) , 395 _model_search2 ( NULL ) , 396 _VNS_search ( NULL ) , 397 _cache_search ( NULL ) , 398 _L_curve ( NULL ) , 399 _extended_poll ( extended_poll ) , 400 _user_ext_poll ( (extended_poll!=NULL) ) { init(); } 401 402 /// Destructor. 403 virtual ~Mads ( void ); 404 405 /// Algorithm execution for single-objective. 406 /** 407 \return Stop reason. 408 */ 409 NOMAD::stop_type run ( void ); 410 411 /// Algorithm execution for multi-objective. 412 /** 413 \return Stop reason. 414 */ 415 NOMAD::stop_type multi_run ( void ); 416 417 /// Force quit. 418 /** 419 Called by pressing Ctrl-C. 420 \param signalValue Signal value -- \b IN. 421 */ 422 static void force_quit ( int signalValue ); 423 424 /// Reset. 425 /** 426 - Also resets the user search. 427 \param keep_barriers A boolean equal to \c true if NOMAD::Barrier objects 428 have to be reseted 429 -- \b IN -- \b optional (default = \c false). 430 \param keep_stats A boolean equal to \c true if the stats object 431 has to be reseted 432 -- \b IN -- \b optional (default = \c false). 433 */ 434 void reset ( bool keep_barriers = false , bool keep_stats = false ); 435 436 /// Set user search. 437 /** 438 \param us A pointer to the user search -- \b IN. 439 */ set_user_search(NOMAD::Search * us)440 void set_user_search ( NOMAD::Search * us ) { _user_search = us; } 441 442 /// Set an extern Pareto front. 443 /** 444 \param pf A pointer to a Pareto front -- \b IN. 445 */ set_pareto_front(NOMAD::Pareto_Front * pf)446 void set_pareto_front ( NOMAD::Pareto_Front * pf ) { _pareto_front = pf; } 447 448 /// Set the flag for the multi-objective test. 449 /** 450 \param fcb The flag for the multi-objective test -- \b IN. 451 */ set_flag_check_bimads(bool fcb)452 static void set_flag_check_bimads ( bool fcb ) { _flag_check_bimads = fcb; } 453 454 /// Set the flag \c _flag_reset_mesh. 455 /** 456 \param frm The flag -- \b IN. 457 */ set_flag_reset_mesh(bool frm)458 static void set_flag_reset_mesh ( bool frm ) { _flag_reset_mesh = frm; } 459 460 /// Set the flag \c _flag_reset_barriers. 461 /** 462 \param frb The flag -- \b IN. 463 */ set_flag_reset_barriers(bool frb)464 static void set_flag_reset_barriers ( bool frb ) { _flag_reset_barriers = frb; } 465 466 /// Set the flag \c _flag_p1_active -- \b IN. 467 /** 468 \param fpa The flag. 469 */ set_flag_p1_active(bool fpa)470 static void set_flag_p1_active ( bool fpa ) { _flag_p1_active = fpa; } 471 472 /// Access to the flags. 473 /** 474 \param flag_check_bimads Multi-objective flag -- \b OUT. 475 \param flag_reset_mesh Mesh reset flag -- \b OUT. 476 \param flag_reset_barriers Reset barriers flag -- \b OUT. 477 \param flag_p1_active Phase one flag -- \b OUT. 478 */ 479 static void get_flags ( bool & flag_check_bimads , 480 bool & flag_reset_mesh , 481 bool & flag_reset_barriers , 482 bool & flag_p1_active ); 483 484 /// Access to the stats. 485 /** 486 \return The stats. 487 */ get_stats(void)488 NOMAD::Stats & get_stats ( void ) { return _stats; } 489 490 /// Access to the evaluator control. 491 /** 492 \return The evaluator control. 493 */ get_evaluator_control(void)494 NOMAD::Evaluator_Control & get_evaluator_control ( void ) { return _ev_control; } 495 496 /// Access to the barrier for true function evaluations. 497 /** 498 \return The barrier for the true function evaluations. 499 */ get_true_barrier(void)500 NOMAD::Barrier & get_true_barrier ( void ) { return _true_barrier; } 501 502 /// Access to the barrier for surrogate evaluations. 503 /** 504 \return The barrier for the surrogates. 505 */ get_sgte_barrier(void)506 NOMAD::Barrier & get_sgte_barrier ( void ) { return _sgte_barrier; } 507 508 /// Access to the NOMAD::Extended_Poll object. 509 /** 510 \return A pointer to \c _extended_poll. 511 */ get_extended_poll(void) const512 NOMAD::Extended_Poll * get_extended_poll ( void ) const { return _extended_poll; } 513 514 515 516 /// Access to the Pareto front. 517 /** 518 \return A pointer to the Pareto front. 519 */ get_pareto_front(void) const520 NOMAD::Pareto_Front * get_pareto_front ( void ) const { return _pareto_front; } 521 522 /// Access to the active cache (truth or surrogate). 523 /** 524 \return The active cache. 525 */ get_cache(void) const526 const NOMAD::Cache & get_cache ( void ) const 527 { 528 return ( _p.get_opt_only_sgte() ) ? 529 _ev_control.get_sgte_cache() : _ev_control.get_cache(); 530 } 531 532 /// Access to the active barrier (truth or surrogate). 533 /** 534 \return The active barrier. 535 */ get_active_barrier(void) const536 const NOMAD::Barrier & get_active_barrier ( void ) const 537 { 538 return ( _p.get_opt_only_sgte() ) ? _sgte_barrier : _true_barrier; 539 } 540 541 /// Access to the best feasible point. 542 /** 543 \return A pointer to the best feasible point; 544 \return \c NULL if there is no feasible point. 545 */ get_best_feasible(void) const546 const NOMAD::Eval_Point * get_best_feasible ( void ) const 547 { 548 return get_active_barrier().get_best_feasible(); 549 } 550 551 /// Access to the best infeasible point. 552 /** 553 \return A pointer to the best infeasible point; 554 \return \c NULL if there is no infeasible point. 555 */ get_best_infeasible(void) const556 const NOMAD::Eval_Point * get_best_infeasible( void ) const 557 { 558 return get_active_barrier().get_best_infeasible(); 559 } 560 561 /// Access to the best infeasible point with minimun constraint violation. 562 /** 563 \return A pointer to the best infeasible point with min. viol.; 564 \return \c NULL if there is no infeasible point. 565 */ get_best_infeasible_min_viol(void) const566 const NOMAD::Eval_Point * get_best_infeasible_min_viol ( void ) const 567 { 568 return get_active_barrier().get_best_infeasible_min_viol(); 569 } 570 571 /// Display model stats. 572 /** 573 \param out The NOMAD::Display object -- \b IN. 574 */ 575 void display_model_stats ( const NOMAD::Display & out ) const; 576 577 /// Display the Pareto front. 578 /** 579 Displays the front at the standard output or in a stats file. 580 */ 581 void display_pareto_front ( void ) const; 582 583 /// Display. 584 /** 585 \param out The NOMAD::Display object -- \b IN. 586 */ 587 void display ( const NOMAD::Display & out ) const; 588 589 /// Display. 590 /** 591 Uses the NOMAD::Display object of the NOMAD::Parameters class. 592 */ display(void) const593 void display ( void ) const { display ( _p.out() ); } 594 }; 595 596 /// Display a NOMAD::Mads object. 597 /** 598 \param out The NOMAD::Display object -- \b IN. 599 \param m The NOMAD::Mads object to be displayed -- \b IN. 600 \return The NOMAD::Display object. 601 */ operator <<(const NOMAD::Display & out,const NOMAD::Mads & m)602 inline const NOMAD::Display & operator << ( const NOMAD::Display & out , 603 const NOMAD::Mads & m ) 604 { 605 m.display ( out ); 606 return out; 607 } 608 } 609 610 #endif 611