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   Signature.hpp
38  \brief  Evaluation point signature (headers)
39  \author Sebastien Le Digabel
40  \date   2010-04-22
41  \see    Signature.cpp
42  */
43 #ifndef __SIGNATURE__
44 #define __SIGNATURE__
45 
46 #include "Variable_Group.hpp"
47 
48 namespace NOMAD {
49 
50     /// Evaluation point signature.
51     class Signature {
52 
53     private:
54 
55 #ifdef MEMORY_DEBUG
56         static int _cardinality;     ///< Number of NOMAD::Signature objects in memory.
57         static int _max_cardinality; ///< Max number of NOMAD::Signature objects in memory.
58 #endif
59 
60         NOMAD::Point _lb;              ///< Lower bounds.
61         NOMAD::Point _ub;              ///< Upper bounds.
62         NOMAD::Point _scaling;         ///< Scaling.
63         NOMAD::Point _fixed_variables; ///< Fixed variables.
64 
65         std::vector<NOMAD::bb_input_type> _input_types; ///< Input types.
66 
67         bool _all_continuous;  ///< Flag equal to \c true if all variables are continuous.
68         bool _has_categorical; ///< Flag equal to \c true if there are categorical variables.
69 
70         static bool _warning_has_been_displayed;  ///< Flag equal to \c true if the warning has already been displayed
71 
72         std::vector<bool> _periodic_variables; ///< Periodic variables.
73 
74         /// Groups of variables.
75         /**
76          Include the directions/
77          */
78         std::list<NOMAD::Variable_Group*> _var_groups;
79 
80         /// Mesh associated to this signature.
81         NOMAD::OrthogonalMesh *_mesh; ///< Orthogonal mesh
82 
83         /**
84          Flag equal to \c true if the signature is standard
85          (i.e created in Parameters class).
86          */
87         bool _std;
88 
89         // Feasible successful direction.
90         /**
91          Mutable since it is not used in
92          \c operator \c < and have to be often changed.
93          */
94         mutable NOMAD::Direction _feas_success_dir;
95 
96         // Infeasible successful direction.
97         /**
98          Mutable since it is not used in
99          \c operator \c < and have to be often changed.
100          */
101         mutable NOMAD::Direction _infeas_success_dir;
102 
103 
104         // Direction group index
105         int _dir_group_index;
106 
107         // Display
108         NOMAD::Display _out;
109 
110         /*---------------------------------------------------------------------------*/
111 
112         /// Initializations.
113         /**
114          \param n                  Number of variables    -- \b IN.
115          \param input_types        Types of the variables -- \b IN.
116          \param lb                 Lower bounds           -- \b IN.
117          \param ub                 Upper bounds           -- \b IN.
118          \param scaling            Scaling                -- \b IN.
119          \param fixed_variables    Fixed variables        -- \b IN.
120          \param periodic_variables Periodic variables     -- \b IN.
121          \param var_groups         Groups of variables    -- \b IN.
122          */
123         void init
124         ( int                                                     n                  ,
125          const std::vector<NOMAD::bb_input_type>               & input_types        ,
126          const NOMAD::Point                                    & lb                 ,
127          const NOMAD::Point                                    & ub                 ,
128          const NOMAD::Point                                    & scaling            ,
129          const NOMAD::Point                                    & fixed_variables    ,
130          const std::vector<bool>                               & periodic_variables ,
131          std::set<NOMAD::Variable_Group*,NOMAD::VG_Comp> & var_groups           );
132 
133         /// Reset groups of variables.
134         void reset_var_groups ( void );
135 
136         /// Clear.
137         /**
138          Private method called by the destructor and after an exception is thrown.
139          */
140         void clear ( void );
141 
142         /// Affectation operator.
143         /**
144          \param s The right-hand side object.
145          */
146         const Signature & operator = ( const Signature & s );
147 
148     public:
149 
150         /*---------------------------------------------------------------------------*/
151 
152         /// Exception class for an invalid signature.
153         class Signature_Error : public NOMAD::Exception {
154         public:
155             /// Constructor.
Signature_Error(const std::string & file,int line,Signature & s,const std::string & msg)156             Signature_Error ( const std::string & file ,
157                              int                 line ,
158                              Signature         & s    ,
159                              const std::string & msg    )
160             : NOMAD::Exception ( file , line , msg ) { s.clear(); }
161         };
162 
163         /*---------------------------------------------------------------------------*/
164 
165         /// Constructor #1.
166         /**
167          Advanced version.
168          \param n							Number of variables			-- \b IN.
169          \param input_types					Types of the variables		-- \b IN.
170          \param use_smesh                   Type of mesh (SMesh, XMesh)	-- \b IN.
171          \param anisotropic_mesh			Anisotropy of mesh (XMesh)	-- \b IN.
172          \param initial_poll_size			Initial poll size			-- \b IN.
173          \param min_poll_size				Minimum poll size			-- \b IN.
174          \param min_mesh_size				Minimim mesh size			-- \b IN.
175          \param mesh_update_basis			Mesh update basis			-- \b IN.
176          \param poll_update_basis			Poll update basis			-- \b IN.
177          \param mesh_coarsening_exponent	Mesh coarsening exponent	-- \b IN.
178          \param mesh_refining_exponent		Mesh refining exponent		-- \b IN.
179          \param initial_mesh_index			Initial mesh index			-- \b IN.
180          \param lb							Lower bounds				-- \b IN.
181          \param ub							Upper bounds				-- \b IN.
182          \param scaling						Scaling						-- \b IN.
183          \param fixed_variables				Fixed variables				-- \b IN.
184          \param periodic_variables			Periodic variables			-- \b IN.
185          \param var_groups					Groups of variables			-- \b IN.
186          \param out							Display                     -- \b IN.
187          */
188         Signature
189         ( int													n                  ,
190          const std::vector<NOMAD::bb_input_type>				& input_types        ,
191          const NOMAD::Point										& lb                 ,
192          const NOMAD::Point										& ub                 ,
193          bool													use_smesh	,
194          bool													anisotropic_mesh	,
195          const NOMAD::Point									    & initial_poll_size	,
196          const NOMAD::Point										& min_poll_size		,
197          const NOMAD::Point										& min_mesh_size		,
198          NOMAD::Double											& mesh_update_basis	,
199          NOMAD::Double											& poll_update_basis	,
200          int													& mesh_coarsening_exponent,
201          int													& mesh_refining_exponent,
202          int													initial_mesh_index	,
203          const NOMAD::Point										& scaling           ,
204          const NOMAD::Point										& fixed_variables   ,
205          const std::vector<bool>								& periodic_variables,
206          std::set<NOMAD::Variable_Group*,NOMAD::VG_Comp>		& var_groups         ,
207          const NOMAD::Display									& out=NOMAD::Display()
208          );
209 
210         /// Constructor #2.
211         /**
212          Basic version that will automatically construct groups of variables.
213          \param n                  Number of variables                    -- \b IN.
214          \param input_types        Types of the variables                 -- \b IN.
215          \param initial_poll_size  Initial poll size                      -- \b IN.
216          \param lb                 Lower bounds                           -- \b IN.
217          \param ub                 Upper bounds                           -- \b IN.
218          \param direction_types    Types of directions                    -- \b IN.
219          \param sec_poll_dir_types Types of directions for secondary poll -- \b IN.
220          \param out                Display                                -- \b IN.
221          */
222         Signature ( int                                       n                  ,
223                    const std::vector<NOMAD::bb_input_type> & input_types        ,
224                    const NOMAD::Point					   & initial_poll_size	,
225                    const NOMAD::Point                      & lb                 ,
226                    const NOMAD::Point                      & ub                 ,
227                    const std::set<NOMAD::direction_type>   & direction_types    ,
228                    const std::set<NOMAD::direction_type>   & sec_poll_dir_types ,
229                    const NOMAD::Display                    & out = NOMAD::Display()
230                    );
231 
232         /// Copy constructor.
233         /**
234          \param s The copied object.
235          */
236         Signature ( const Signature & s );
237 
238         /// Destructor.
239         virtual ~Signature ( void );
240 
241         /// Reset.
242         /**
243          \param n                  Number of variables    -- \b IN.
244          \param input_types        Types of the variables -- \b IN.
245          \param lb                 Lower bounds           -- \b IN.
246          \param ub                 Upper bounds           -- \b IN.
247          \param scaling            Scaling                -- \b IN.
248          \param fixed_variables    Fixed variables        -- \b IN.
249          \param periodic_variables Periodic variables     -- \b IN.
250          \param var_groups         Groups of variables    -- \b IN.
251          */
252         void reset
253         ( int                                                     n                  ,
254          const std::vector<NOMAD::bb_input_type>               & input_types        ,
255          const NOMAD::Point                                    & lb                 ,
256          const NOMAD::Point                                    & ub                 ,
257          const NOMAD::Point                                    & scaling            ,
258          const NOMAD::Point                                    & fixed_variables    ,
259          const std::vector<bool>                               & periodic_variables ,
260          std::set<NOMAD::Variable_Group*,NOMAD::VG_Comp>	   & var_groups );
261 
262         /// Define a signature to be standard.
set_std(void)263         void set_std ( void ) { _std = true; }
264 
265         /// Set a feasible successful direction.
266         /**
267          \param dir The direction -- \b IN.
268          */
269         void set_feas_success_dir ( const NOMAD::Direction & dir );
270 
271         /// Set an infeasible successful direction.
272         /**
273          \param dir The direction -- \b IN.
274          */
275         void set_infeas_success_dir ( const NOMAD::Direction & dir );
276 
277         /// Reset the feasible successful direction.
reset_feas_success_dir(void) const278         void reset_feas_success_dir ( void ) const { _feas_success_dir.clear(); }
279 
280         /// Reset the infeasible successful direction.
reset_infeas_success_dir(void) const281         void reset_infeas_success_dir ( void ) const { _infeas_success_dir.clear(); }
282 
283         /// Scaling.
284         /**
285          Performed before an evaluation.
286          \param x The scaled point -- \b IN/OUT.
287          */
288         void scale ( NOMAD::Point & x );
289 
290         /// Unscaling.
291         /**
292          Performed after an evaluation.
293          \param x The unscaled point -- \b IN/OUT.
294          */
295         void unscale ( NOMAD::Point & x );
296 
297         /// Snap to bounds.
298         /**
299          - Supposes that \c this->treat_periodic_variables() has already been invoked.
300          - If periodic variables have been treated, then bounds are
301          satisfied and there is no need to snap anymore.
302          \param x         The point to snap -- \b IN/OUT.
303          \param direction A pointer to the direction associated to this point
304          (may be \c NULL)  -- \b IN/OUT.
305          \return A Boolean equal to \c true if \c x has been modified.
306          */
307         bool snap_to_bounds ( NOMAD::Point & x , NOMAD::Direction * direction );
308 
309         /// Treat the periodic variables.
310         /**
311          \param x The point to treat -- \b IN/OUT.
312          \param old_dir A pointer to the direction associated to this point
313          (before the treatment; may be \c NULL) -- \b IN.
314          \param new_dir A pointer to the direction associated to this point
315          (after the treatment; may be \c NULL) -- \b OUT.
316          \return A boolean equal to \c true if \c x has been modified.
317          */
318         bool treat_periodic_variables ( NOMAD::Point            & x       ,
319                                        const NOMAD::Direction *  old_dir ,
320                                        NOMAD::Direction       *& new_dir   );
321 
322         /// Access to the lower bounds.
323         /**
324          \return The lower bounds.
325          */
get_lb(void) const326         const NOMAD::Point & get_lb ( void ) const { return _lb; }
327 
328         /// Access to the upper bounds.
329         /**
330          \return The upper bounds.
331          */
get_ub(void) const332         const NOMAD::Point & get_ub ( void ) const { return _ub; }
333 
334         /// Access to the mesh.
335         /**
336          \return The orthogonal mesh.
337          */
get_mesh(void) const338         NOMAD::OrthogonalMesh * get_mesh ( void ) const { return _mesh; }
339 
340 
341         /// Update the Mesh (poll and mesh sizes).
342         /**
343          \param success    Type of success of the iteration			-- \b IN.
344          \param dir        Direction of the iteration (optional)	-- \b IN.
345          */
update_mesh(NOMAD::success_type success,const NOMAD::Direction * dir=NULL)346         void update_mesh ( NOMAD::success_type success, const NOMAD::Direction * dir=NULL )
347         {
348             _mesh->update ( success, dir );
349         }
350 
351         /// Complete reset of the mesh.
352         /**
353          */
reset_mesh(void)354         void reset_mesh ( void ) { _mesh->reset(); }
355 
356         /// Reset of the mesh indices.
357         /**
358          /param mesh_indices
359          */
reset_mesh(NOMAD::Point & mesh_indices)360         void reset_mesh ( NOMAD::Point & mesh_indices  ) { _mesh->set_mesh_indices( mesh_indices); }
361 
362 
363         /// Access to the scaling.
364         /**
365          \return The scaling.
366          */
get_scaling(void) const367         const NOMAD::Point & get_scaling ( void ) const { return _scaling; }
368 
369         /// Access to the fixed variables.
370         /**
371          \return The fixed variables.
372          */
get_fixed_variables(void) const373         const NOMAD::Point & get_fixed_variables ( void ) const { return _fixed_variables; }
374 
375 
376         /// Access to the number of fixed variables.
377         /**
378          \return The number of fixed variables.
379          */
380         int get_nb_fixed_variables ( void ) const;
381 
382 
383 
384         /// Access to the feasible successful direction.
385         /**
386          \return The feasible successful direction
387          (may be undefined).
388          */
get_feas_success_dir(void) const389         const NOMAD::Direction & get_feas_success_dir ( void ) const
390         {
391             return _feas_success_dir;
392         }
393 
394         /// Access to the infeasible successful direction.
395         /**
396          \return The infeasible successful direction
397          (may be undefined).
398          */
get_infeas_success_dir(void) const399         const NOMAD::Direction & get_infeas_success_dir ( void ) const
400         {
401             return _infeas_success_dir;
402         }
403 
404         /// Access to the periodic variables.
405         /**
406          \return The periodic variables.
407          */
get_periodic_variables(void) const408         const std::vector<bool> & get_periodic_variables ( void ) const
409         {
410             return _periodic_variables;
411         }
412 
413         /// Check if all variables are continuous.
414         /**
415          \return A boolean equal to \c true if all variables are continuous.
416          */
all_continuous(void) const417         bool all_continuous ( void ) const { return _all_continuous; }
418 
419         /// Check if there are categorical variables.
420         /**
421          \return A boolean equal to \c true if there are categorical variables.
422          */
has_categorical(void) const423         bool has_categorical ( void ) const { return _has_categorical; }
424 
425         /// Access to the number of categorical variables.
426         /**
427          \return Integer equal to the number of categorical variables.
428          */
429         int get_n_categorical ( void ) const ;
430 
431         /// Access to the number of variables.
432         /**
433          \return The number of variables.
434          */
get_n(void) const435         int get_n ( void ) const { return static_cast<int> ( _input_types.size() ); }
436 
437         /// Access to the input types.
438         /**
439          \return The input types.
440          */
get_input_types(void) const441         const std::vector<NOMAD::bb_input_type> & get_input_types ( void ) const
442         {
443             return _input_types;
444         }
445 
446         /// Access to the input types.
447         /**
448          \return The input types.
449          */
get_input_type(void) const450         const std::vector<NOMAD::bb_input_type> & get_input_type  ( void ) const
451         {
452             return _input_types;
453         }
454 
455         /// Access to the groups of variables.
456         /**
457          \return The groups of variables.
458          */
get_var_groups(void) const459         const std::list<NOMAD::Variable_Group*> & get_var_groups ( void ) const
460         {
461             return _var_groups;
462         }
463 
464 
465         /// Check the compatibility of a point.
466         /**
467          - Only the number of variables is checked.
468          - Other criteria (fixed variables, binary variables,...)
469          are checked by NOMAD::Eval_Point::check().
470          \param x The point to check -- \b IN.
471          \return A boolean equal to \c true if the point is compatible
472          with the signature.
473          */
474         bool is_compatible ( const NOMAD::Point & x ) const;
475 
476         /// Access to the directions.
477         /**
478          - The computed directions already include Delta^k_m.
479          \param dirs              List of directions                      -- \b OUT.
480          \param poll              Type of poll (primary or secondary)     -- \b IN.
481          \param poll_center       Poll center                             -- \b IN.
482          */
483         void get_directions ( std::list<NOMAD::Direction>	& dirs			,
484                              NOMAD::poll_type				poll			,
485                              const NOMAD::Point				& poll_center	);
486 
487 
488         /// Access to one direction for a given mesh.
489         /**
490          Used for example in the VNS search.
491          \param dir          The direction  -- \b OUT.
492          \param mesh_index   Mesh index ell -- \b IN.
493          */
494         void get_one_direction ( NOMAD::Direction & dir				,
495                                 int                mesh_index		) const;
496 
497 
498         /// Comparison operator \c < .
499         /**
500          Successful directions are not considered.
501          \param s The right-hand side object -- \b IN.
502          \return A boolean equal to \c true if \c *this \c < \c s.
503          */
504         bool operator <  ( const Signature & s ) const;
505 
506         /// Comparison operator \c != .
507         /**
508          \param s The right-hand side object -- \b IN.
509          \return A boolean equal to \c true if \c *this \c != \c s.
510          */
operator !=(const Signature & s) const511         bool operator != ( const Signature & s ) const
512         {
513             return ( (*this < s) || (s < *this) );
514         }
515 
516 #ifdef MEMORY_DEBUG
517 
518         /// Access to the number of NOMAD::Signature objects in memory.
519         /**
520          \return Number of NOMAD::Signature objects in memory.
521          */
get_cardinality(void)522         static int get_cardinality ( void ) { return Signature::_cardinality; }
523 
524         /// Access to the max number of NOMAD::Signature objects in memory.
525         /**
526          \return Max number of NOMAD::Signature objects in memory.
527          */
get_max_cardinality(void)528         static int get_max_cardinality ( void ) { return Signature::_max_cardinality; }
529 #endif
530 
531         /// Display.
532         /**
533          \param out The NOMAD::Display object -- \b IN.
534          */
535         void display ( const NOMAD::Display & out ) const;
536 
537     };
538 
539     /// Display a NOMAD::Signature object.
540     /**
541      \param out The NOMAD::Display object                   -- \b IN.
542      \param s   The NOMAD::Signature object to be displayed -- \b IN.
543      \return    The NOMAD::Display object.
544      */
operator <<(const NOMAD::Display & out,const NOMAD::Signature & s)545     inline const NOMAD::Display & operator << ( const NOMAD::Display   & out ,
546                                                const NOMAD::Signature & s     ) {
547         s.display ( out );
548         return out;
549     }
550 }
551 
552 #endif
553