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   Directions.hpp
38  \brief  Set of polling directions (headers)
39  \author Sebastien Le Digabel
40  \date   2010-04-14
41  \see    Directions.cpp
42  */
43 #ifndef __DIRECTIONS__
44 #define __DIRECTIONS__
45 
46 #include "Random_Pickup.hpp"
47 #include "Direction.hpp"
48 #include "OrthogonalMesh.hpp"
49 #include "RNG.hpp"
50 
51 namespace NOMAD {
52 
53     /// Set of polling directions.
54     class Directions {
55 
56         /*--------------------------------------------------------------*/
57     private:
58 
59         int _nc;  ///< Number of non-fixed variables.
60 
61         /// Types of the poll directions.
62         std::set<NOMAD::direction_type> _direction_types;
63 
64         /// Types of the secondary poll directions.
65         std::set<NOMAD::direction_type> _sec_poll_dir_types;
66 
67         bool _is_binary;      ///< Flag equal to \c true if all variables are binary.
68         bool _is_categorical; ///< Flag equal to \c true if all variables are categorical.
69 
70         bool _is_orthomads;  //< Flag equal to \c true if Ortho-MADS directions are used.
71 
72         // LT-MADS attributes:
73         NOMAD::Direction * _bl [1+2*NOMAD::L_LIMITS];  ///< Directions b(ell) (LT-MADS).
74         int             _hat_i [1+2*NOMAD::L_LIMITS];  ///< b(ell) indexes (LT-MADS).
75         bool   _lt_initialized;  ///< Flag equal to \c true if LT-MADS has been initialized.
76 
77         const NOMAD::Display & _out;  ///< Display.
78 
79         /*--------------------------------------------------------------*/
80 
81         /// Affectation operator.
82         /**
83          \param d The right-hand side object -- \b IN.
84          */
85         Directions & operator = ( const Directions & d );
86 
87         /// LT-MADS initializations.
88         void lt_mads_init ( void );
89 
90         /// Compute the squared norm of \c normalized(2u_t-e) for Ortho-MADS.
91         /**
92          \param x     \b IN.
93          \param norm  \b IN.
94          \param b     \b IN.
95          \param new_b \b OUT.
96          \return The squared norm.
97          */
98         NOMAD::Double eval_ortho_norm ( const NOMAD::Double & x      ,
99                                        const NOMAD::Double & norm   ,
100                                        const NOMAD::Point  & b      ,
101                                        NOMAD::Point        & new_b    ) const;
102 
103         /// Householder transformation.
104         /**
105          - Generate \c _nc directions.
106          - Computes also \c H[i+nc] \c = \c -H[i] (completion to 2n directions).
107          \param dir     The given direction                -- \b IN.
108          \param complete_to_2n Complete or not to \c 2n directions -- \b IN.
109          \param H              The \c _nc directions               -- \b OUT.
110          */
111         void householder ( const NOMAD::Direction & dir     ,
112                           bool                     complete_to_2n ,
113                           NOMAD::Direction      ** H                ) const;
114 
115         /// Get the expression of an integer \c t in inverse base \c p.
116         /**
117          \param t \b IN.
118          \param p \b IN.
119          \return The expression of \c t in inverse base \c p.
120          */
121         static NOMAD::Double get_phi ( int t , int p );
122 
123 
124         /// Access to the LT-MADS \c b(ell) direction.
125         /**
126          \param mesh the currenet OrthogonalMesh  \c ell  -- \b IN.
127          \param dtype Direction type          -- \b IN.
128          \param hat_i LT-MADS \c hat{i} index -- \b IN/OUT.
129          \return The LT-MADS \c b(ell) direction.
130          */
131         const NOMAD::Direction * get_bl ( const NOMAD::OrthogonalMesh & mesh ,
132                                          NOMAD::direction_type   dtype      ,
133                                          int                   & hat_i        );
134 
135         /// Create a new LT-MADS direction.
136         /**
137          If \c hat_i \c == \c -1, a new \c b(ell) direction is created
138          and \c hat_i is set.
139          \param mesh the current OrthogonalMesh index \c ell           -- \b IN.
140          \param dtype      Direction type              -- \b IN.
141          \param diag_i     Diagonal index              -- \b IN.
142          \param hat_i      LT-MADS \c hat{i} index     -- \b IN/OUT.
143          \param dir        LT-MADS \c b(ell) direction -- \b OUT.
144          */
145         void create_lt_direction ( const NOMAD::OrthogonalMesh & mesh ,
146                                   NOMAD::direction_type   dtype      ,
147                                   int                     diag_i     ,
148                                   int                   & hat_i      ,
149                                   NOMAD::Direction     *& dir          );
150 
151         /// Permute the coordinates of a direction.
152         /**
153          \param dir                The direction      -- \b IN/OUT.
154          \param permutation_vector Permutation vector -- \b IN.
155          */
156         void permute_coords ( NOMAD::Direction & dir                ,
157                              const int        * permutation_vector   ) const;
158 
159         /// Compute binary directions.
160         /**
161          Only if all groups of variables are binary.
162          \param dirs Set of directions -- \b OUT.
163          */
164         void compute_binary_directions ( std::list<NOMAD::Direction> & dirs ) const;
165 
166         /*--------------------------------------------------------------*/
167 
168     public:
169 
170         /// Constructor.
171         /**
172          \param nc                 Number of non-fixed variables          -- \b IN.
173          \param direction_types    Types of the poll directions           -- \b IN.
174          \param sec_poll_dir_types Types of the secondary poll directions -- \b IN.
175          \param out                The display                            -- \b IN.
176          */
177         Directions ( int                                     nc                 ,
178                     const std::set<NOMAD::direction_type> & direction_types    ,
179                     const std::set<NOMAD::direction_type> & sec_poll_dir_types ,
180                     const NOMAD::Display                  & out                  );
181 
182         /// Copy constructor.
183         /**
184          \param d The copied object -- \b IN.
185          */
Directions(const Directions & d)186         Directions ( const Directions & d )
187         : _nc                 ( d._nc                 ) ,
188         _direction_types    ( d._direction_types    ) ,
189         _sec_poll_dir_types ( d._sec_poll_dir_types ) ,
190         _is_binary          ( d._is_binary          ) ,
191         _is_categorical     ( d._is_categorical     ) ,
192         _is_orthomads       ( d._is_orthomads       ) ,
193         _lt_initialized     ( false                 ) ,
194         _out                ( d._out                )   {}
195 
196         /// Destructor.
197         virtual ~Directions ( void );
198 
199         /// Compute the directions for a given mesh.
200         /**
201          \param mesh               The given mesh                                             -- \b IN.
202          \param dirs               Set of directions                                          -- \b OUT.
203          \param poll               Type of poll (primary or secondary)                        -- \b IN.
204          */
205         void compute ( std::list<NOMAD::Direction> & dirs           ,
206                       NOMAD::poll_type               poll           ,
207                       const NOMAD::OrthogonalMesh  & mesh			);
208 
209         /// Compute a random direction on a N-Sphere.
210         /**
211          \param random_dir								-- \b OUT.
212          \return A boolean equal to \c true if the computation went well.
213          */
214         bool compute_dir_on_unit_sphere (	NOMAD::Direction	& random_dir ) const;
215 
216 
217         /// Check if Ortho-MADS directions are used.
218         /**
219          \return A boolean equal to \c true if Ortho-MADS directions are used.
220          */
is_orthomads(void) const221         bool is_orthomads ( void ) const
222         {
223             return _is_orthomads;
224         }
225 
226         /// Check if all variables are categorical.
227         /**
228          \return A boolean equal to \c true if all variables are categorical.
229          */
is_categorical(void) const230         bool is_categorical ( void ) const
231         {
232             return _is_categorical;
233         }
234 
235         /// Access to the poll direction types.
236         /**
237          \return Poll direction types.
238          */
get_direction_types(void) const239         const std::set<NOMAD::direction_type> & get_direction_types ( void ) const
240         {
241             return _direction_types;
242         }
243 
244         /// Access to the secondary poll direction types.
245         /**
246          \return Secondary poll direction types.
247          */
get_sec_poll_dir_types(void) const248         const std::set<NOMAD::direction_type> & get_sec_poll_dir_types ( void ) const
249         {
250             return _sec_poll_dir_types;
251         }
252 
253         /// Reset directions for binary variables.
254         void set_binary ( void );
255 
256         /// Reset directions for categorical variables.
257         void set_categorical ( void );
258 
259         /// Comparison operator.
260         /**
261          \param  d The right-hand side object -- \b IN.
262          \return A boolean equal to \c true if \c *this \c < \c d .
263          */
264         bool operator < ( const Directions & d ) const;
265 
266         /// Access to the NOMAD::Display member \c _out.
267         /**
268          \return The NOMAD::Display member \c _out.
269          */
out(void) const270         const NOMAD::Display & out ( void ) const { return _out; }
271 
272         /// Display.
273         /**
274          \param out The NOMAD::Display object -- \b IN.
275          */
276         void display ( const NOMAD::Display & out ) const;
277 
278         /// Display.
279         /**
280          Uses the \c this->_out member as NOMAD::Display object.
281          */
display(void) const282         void display ( void ) const
283         {
284             display ( _out );
285         }
286     };
287 
288     /// Display a NOMAD::Directions object.
289     /**
290      \param out The NOMAD::Display object -- \b IN.
291      \param d   The NOMAD::Directions object to be displayed -- \b IN.
292      \return    The NOMAD::Display object.
293      */
operator <<(const NOMAD::Display & out,const NOMAD::Directions & d)294     inline const NOMAD::Display & operator << ( const NOMAD::Display    & out ,
295                                                const NOMAD::Directions & d     )
296     {
297         d.display ( out );
298         return out;
299     }
300 }
301 
302 #endif
303