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   OrthogonalMesh.hpp
38  \brief  implementation
39  \author Christophe Tribes
40  \date   2014-06-19
41  \see    SMesh.cpp XMesh.cpp
42  */
43 
44 #include "OrthogonalMesh.hpp"
45 
46 /// Constructor (called only by derived objects).
OrthogonalMesh(const NOMAD::Point & Delta_0,const NOMAD::Point & Delta_min,const NOMAD::Point & delta_min,const NOMAD::Point & fixed_variables,NOMAD::Double update_basis,int coarsening_step,int refining_step,int limit_mesh_index)47 NOMAD::OrthogonalMesh::OrthogonalMesh (const NOMAD::Point	& Delta_0   ,
48                                        const NOMAD::Point	& Delta_min ,
49                                        const NOMAD::Point	& delta_min ,
50                                        const NOMAD::Point  & fixed_variables ,
51                                        NOMAD::Double		update_basis,
52                                        int					coarsening_step,
53                                        int					refining_step,
54                                        int                  limit_mesh_index ) :
55 _delta_0			( Delta_0 ),
56 _Delta_0			( Delta_0 ),
57 _Delta_min			( Delta_min ),
58 _delta_min			( delta_min ),
59 _update_basis		( update_basis ),
60 _coarsening_step	( coarsening_step ),
61 _refining_step		( refining_step ),
62 _limit_mesh_index   ( limit_mesh_index )
63 {
64 
65     _Delta_min_is_defined=_Delta_min.is_defined();
66     _Delta_min_is_complete=_Delta_min.is_complete();
67 
68     bool chkMesh  = delta_min.is_defined();
69     bool chkPoll  = _Delta_min_is_defined;
70     _n = Delta_0.size();
71 
72 
73     _n_free_variables = _n - fixed_variables.nb_defined();
74 
75     // The delta_0 are decreased
76     _delta_0*=pow(_n_free_variables,-0.5);
77 
78     if ( !_Delta_0.is_complete() )
79         throw NOMAD::Exception (  "OrthogonalMesh.hpp" , __LINE__ ,
80                                 "NOMAD::OrthogonalMesh::OrthogonalMesh(): delta_0 has undefined values" );
81 
82     if ( chkMesh && delta_min.size() != _n )
83         throw NOMAD::Exception ( "OrthogonalMesh.hpp" , __LINE__ ,
84                                 "NOMAD::OrthogonalMesh::OrthogonalMesh(): delta_0 and delta_min have different sizes" );
85 
86     if ( chkPoll && Delta_min.size() != _n )
87         throw NOMAD::Exception ( "OrthogonalMesh.hpp" , __LINE__ ,
88                                 "NOMAD::OrthogonalMesh::OrthogonalMesh(): Delta_0 and Delta_min have different sizes" );
89 
90 
91     std::string error;
92     for ( int k = 0 ; k < _n ; ++k )
93     {
94         // we check that Delta_min <= Delta_0 and that delta_min <= delta_0:
95         if ( chkMesh &&
96             _delta_min[k].is_defined()						&&
97             _delta_0[k] < _delta_min[k]		)
98         {
99             error = "NOMAD::OrthogonalMesh::OrthogonalMesh(): delta_0 < delta_min";
100             break;
101         }
102         if ( chkPoll &&
103             _Delta_min[k].is_defined()						&&
104             _Delta_0[k] < _Delta_min[k]     )
105         {
106             error = "NOMAD::OrthogonalMesh::OrthogonalMesh(): Delta_0 < Delta_min";
107             break;
108         }
109 
110     }
111 
112     if ( !error.empty() )
113         throw NOMAD::Exception ( "OrthogonalMesh.hpp" , __LINE__ , error );
114 }
115 
116 
117 
is_finer_than_initial(void) const118 bool NOMAD::OrthogonalMesh::is_finer_than_initial (void) const
119 {
120     NOMAD::Point delta;
121     get_delta(delta);
122 
123     for (int i =0; i < _n ; ++i )
124         if ( delta[i] >= _delta_0[i] )
125             return false;
126 
127     return true;
128 }
129 
130 
131 
132 /// Manually set the min mesh size per coordinate.
set_min_mesh_sizes(const NOMAD::Point & delta_min)133 void NOMAD::OrthogonalMesh::set_min_mesh_sizes ( const NOMAD::Point & delta_min )
134 {
135 
136     // If delta_min undefined than _delta_min->undefined
137     if ( ! delta_min.is_defined() )
138     {
139         _delta_min.clear();
140         return;
141     }
142 
143     // If delta_min defined test that everything is consistent
144     if ( delta_min.size() != _n )
145         throw NOMAD::Exception ( "XMesh.cpp" , __LINE__ ,
146                                 "NOMAD::OrthogonalMesh::set_min_mesh_sizes() delta_min has dimension different than mesh dimension" );
147 
148     if ( !delta_min.is_complete() )
149         throw NOMAD::Exception (  "OrthogonalMesh.hpp" , __LINE__ ,
150                                 "NOMAD::OrthogonalMesh::set_min_mesh_sizes(): delta_min has some defined and undefined values" );
151 
152     std::string error;
153     for ( int k = 0 ; k < _n ; ++k )
154     {
155 
156         // we check that Delta_min <= Delta_0 and that delta_min <= delta_0:
157         if ( delta_min[k].is_defined()						&&
158             _delta_0[k] < delta_min[k]		)
159         {
160             error = "NOMAD::OrthogonalMesh::set_delta_min(): delta_0 < delta_min";
161             break;
162         }
163         if ( delta_min[k].is_defined()						&&
164             _Delta_0[k] < delta_min[k]     )
165         {
166             error = "NOMAD::OrthogonalMesh::set_delta_min(): Delta_0 < delta_min";
167             break;
168         }
169 
170     }
171 
172     if ( !error.empty() )
173         throw NOMAD::Exception ( "OrthogonalMesh.hpp" , __LINE__ , error );
174 
175     _delta_min=delta_min;
176 
177 }
178 
179 
180 
181 /*-----------------------------------------------------------*/
182 /*             set delta_0                                   */
183 /*-----------------------------------------------------------*/
set_delta_0(const NOMAD::Point & d)184 void NOMAD::OrthogonalMesh::set_delta_0 ( const NOMAD::Point & d )
185 {
186 
187     if ( d.size() != _delta_0.size() )
188         throw NOMAD::Exception ( "OrthogonalMesh.hpp" , __LINE__ ,
189                                 "NOMAD::OrthogonalMesh::set_delta_0(): dimension of provided delta_0 must be consistent with their previous dimension" );
190 
191     _delta_0=d;
192 }
193 
194 /*-----------------------------------------------------------*/
195 /*             set Delta_0                                   */
196 /*-----------------------------------------------------------*/
set_Delta_0(const NOMAD::Point & d)197 void NOMAD::OrthogonalMesh::set_Delta_0 ( const NOMAD::Point & d )
198 {
199 
200     if ( d.size() != _Delta_0.size() )
201         throw NOMAD::Exception ( "XMesh.cpp" , __LINE__ ,
202                                 "NOMAD::XMesh::set_Delta_0(): dimension of provided Delta_0 must be consistent with their previous dimension" );
203 
204     _Delta_0=d;
205 }
206