NOMAD Source  Version 4.0.0 Beta
Direction.cpp
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------------*/
2 /* NOMAD - Nonlinear Optimization by Mesh Adaptive Direct Search - */
3 /* */
4 /* NOMAD - Version 4.0.0 has been created by */
5 /* Viviane Rochon Montplaisir - Polytechnique Montreal */
6 /* Christophe Tribes - Polytechnique Montreal */
7 /* */
8 /* The copyright of NOMAD - version 4.0.0 is owned by */
9 /* Charles Audet - Polytechnique Montreal */
10 /* Sebastien Le Digabel - Polytechnique Montreal */
11 /* Viviane Rochon Montplaisir - Polytechnique Montreal */
12 /* Christophe Tribes - Polytechnique Montreal */
13 /* */
14 /* NOMAD v4 has been funded by Rio Tinto, Hydro-Québec, NSERC (Natural */
15 /* Sciences and Engineering Research Council of Canada), InnovÉÉ (Innovation */
16 /* en Énergie Électrique) and IVADO (The Institute for Data Valorization) */
17 /* */
18 /* NOMAD v3 was created and developed by Charles Audet, Sebastien Le Digabel, */
19 /* Christophe Tribes and Viviane Rochon Montplaisir and was funded by AFOSR */
20 /* and Exxon Mobil. */
21 /* */
22 /* NOMAD v1 and v2 were created and developed by Mark Abramson, Charles Audet, */
23 /* Gilles Couture, and John E. Dennis Jr., and were funded by AFOSR and */
24 /* Exxon Mobil. */
25 /* */
26 /* Contact information: */
27 /* Polytechnique Montreal - GERAD */
28 /* C.P. 6079, Succ. Centre-ville, Montreal (Quebec) H3C 3A7 Canada */
29 /* e-mail: nomad@gerad.ca */
30 /* */
31 /* This program is free software: you can redistribute it and/or modify it */
32 /* under the terms of the GNU Lesser General Public License as published by */
33 /* the Free Software Foundation, either version 3 of the License, or (at your */
34 /* option) any later version. */
35 /* */
36 /* This program is distributed in the hope that it will be useful, but WITHOUT */
37 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
38 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License */
39 /* for more details. */
40 /* */
41 /* You should have received a copy of the GNU Lesser General Public License */
42 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
43 /* */
44 /* You can find information on the NOMAD software at www.gerad.ca/nomad */
45 /*---------------------------------------------------------------------------------*/
46 /**
47  \file Direction.cpp
48  \brief Custom class for directions (implementation)
49  \author Sebastien Le Digabel and Viviane Rochon Montplaisir
50  \date March 2017
51  \see Direction.hpp
52  */
53 #include "../Math/Direction.hpp"
54 #include "../Math/RNG.hpp"
55 
56 // Assignment operator
57 NOMAD::Direction& NOMAD::Direction::operator=(const NOMAD::Direction& dir)
58 {
59  NOMAD::ArrayOfDouble::operator=(dir);
60  return *this;
61 }
62 
63 /*------------------------------------------------------*/
64 /* Squared Norm of this direction, viewed as a vector. */
65 /*------------------------------------------------------*/
66 const NOMAD::Double NOMAD::Direction::squaredL2Norm() const
67 {
68  NOMAD::Double sqL2 = 0;
69 
70  for (size_t i = 0; i < size(); i++)
71  {
72  sqL2 += _array[i] * _array[i];
73  }
74 
75  return sqL2;
76 }
77 
78 
79 /*------------------------------------------------*/
80 /* Norm of this direction X, viewed as a vector. */
81 /* Norm type may be L1, L2, or LINF. */
82 /*------------------------------------------------*/
83 const NOMAD::Double NOMAD::Direction::norm(NOMAD::NormType normType) const
84 {
85  NOMAD::Double retNorm = 0;
86 
87  switch (normType)
88  {
89  case NOMAD::NormType::L1:
90  for (size_t i = 0; i < size(); i++)
91  {
92  retNorm += _array[i].abs();
93  }
94  break;
95  case NOMAD::NormType::L2:
96  default:
97  retNorm = this->squaredL2Norm();
98  retNorm = sqrt(retNorm.todouble());
99  break;
100  case NOMAD::NormType::LINF:
101  for (size_t i = 0; i < size(); i++)
102  {
103  retNorm = NOMAD::max(retNorm, _array[i].abs());
104  }
105  break;
106  }
107 
108  return retNorm;
109 }
110 
111 
112 /// Infinite norm
113 const NOMAD::Double NOMAD::Direction::infiniteNorm() const
114 {
115  return norm(NormType::LINF);
116 }
117 
118 
119 const NOMAD::Double NOMAD::Direction::dotProduct(const NOMAD::Direction& dir1,
120  const NOMAD::Direction& dir2)
121 {
122  NOMAD::Double dot = 0.0;
123 
124  size_t size = dir1.size();
125  if (size != dir2.size())
126  {
127  std::string err = "Dot product: vectors are not of the same size: \n";
128  err += dir1.display() + "\n";
129  err += dir2.display();
130  throw NOMAD::Exception(__FILE__, __LINE__, err);
131  }
132 
133  for (size_t i = 0; i < size; i++)
134  {
135  dot += dir1[i] * dir2[i];
136  }
137 
138  return dot;
139 }
140 
141 
142 const NOMAD::Double NOMAD::Direction::cos(const NOMAD::Direction& dir1,
143  const NOMAD::Direction& dir2)
144 {
145  NOMAD::Double cos = 0.0;
146 
147  double norm1 = dir1.norm().todouble();
148  double norm2 = dir2.norm().todouble();
149  if (0.0 == norm1 || 0.0 == norm2)
150  {
151  std::string err = "Cosine: a vector is of size 0";
152  throw NOMAD::Exception(__FILE__, __LINE__, err);
153  }
154 
155  cos = dotProduct(dir1, dir2) / (norm1 * norm2);
156 
157  return cos;
158 }
159 
160 /*--------------------------------------------------*/
161 /* Compute a random direction on a unit N-Sphere */
162 /* See http://en.wikipedia.org/wiki/N-sphere */
163 /*--------------------------------------------------*/
164 void NOMAD::Direction::computeDirOnUnitSphere(NOMAD::Direction &randomDir)
165 {
166  size_t i;
167  NOMAD::Double norm, d;
168  size_t n = randomDir.size();
169 
170  for (i = 0; i < n; ++i)
171  {
172  randomDir[i] = NOMAD::RNG::normalRand(0,1);
173  }
174 
175  norm = randomDir.norm();
176 
177  if (0 == norm)
178  {
179  std::string err("Cannot compute a random direction on unit sphere");
180  throw NOMAD::Exception(__FILE__, __LINE__, err);
181  }
182 
183  for (i = 0; i < n; ++i)
184  {
185  randomDir[i] /= norm;
186  }
187 
188 }
189 
190 
191 /*----------------------------------------------------------------*/
192 /* - Householder transformation to generate _nc directions from */
193 /* a given direction. */
194 /* - Compute also H[i+nc] = -H[i] (completion to 2n directions). */
195 /* - Private method. */
196 /*----------------------------------------------------------------*/
197 void NOMAD::Direction::householder(const NOMAD::Direction &dir,
198  bool completeTo2n,
199  NOMAD::Direction ** H)
200 {
201  size_t n = dir.size();
202 
203  const NOMAD::Double norm2 = dir.squaredL2Norm();
204  NOMAD::Double v, h2i;
205 
206  for (size_t i = 0 ; i < n ; ++i)
207  {
208  h2i = 2 * dir[i];
209  for (size_t j = 0 ; j < n ; ++j)
210  {
211  // H[i]:
212  (*H[i])[j] = v = (i == j) ? norm2 - h2i * dir[j] : - h2i * dir[j];
213 
214  // -H[i]:
215  if ( completeTo2n )
216  {
217  (*H[i+n])[j] = -v;
218  }
219  }
220  }
221 }
222 
223 
224 std::ostream& NOMAD::operator<< (std::ostream& out, const NOMAD::Direction& dir)
225 {
226  out << dir.display();
227  return out;
228 }
SgtelibModelFeasibilityType::H
@ H
one model for each constraint
max
Double max(const Double d1, const Double d2)
Largest of two values >=.
Definition: Double.hpp:600
NormType::LINF
@ LINF
Norm LInf.
NormType
NormType
Type of norm.
Definition: Direction.hpp:63
operator<<
std::ostream & operator<<(std::ostream &os, const Algorithm &algo)
Operator to write parameters used for hot restart.