SOT
utils.h
1 
9 #ifndef SOT_UTILS_H
10 #define SOT_UTILS_H
11 
12 #include <thread> // std::this_thread::sleep_for
13 #include <chrono> // std::chrono::seconds
14 #include "common.h"
15 
17 namespace sot {
18 
20 
31  template <class MatType = mat, class VecType = vec>
32  inline VecType squaredPointSetDistance(const VecType& x, const MatType& Y) {
33  return arma::abs(arma::repmat(arma::sum(x % x,0), Y.n_cols,1) + arma::sum(Y % Y,0).t() - 2*Y.t()*x);
34  };
35 
37 
47  template <class MatType = mat>
48  inline MatType squaredPairwiseDistance(const MatType& X, const MatType& Y) {
49  MatType dists = - 2*(X.t()*Y);
50  dists.each_row() += arma::sum(Y % Y, 0);
51  dists.each_col() += arma::sum(X % X, 0).t();
52  dists = arma::abs(dists);
53  return dists;
54  };
55 
57 
66  inline vec toUnitBox(const vec& x, const vec& xLow, const vec& xUp) {
67  return (x - xLow)/(xUp - xLow);
68  };
69 
71 
80  inline mat toUnitBox(const mat& X, const vec& xLow, const vec& xUp) {
81  return (X - arma::repmat(xLow, 1, X.n_cols))/arma::repmat(xUp - xLow, 1, X.n_cols);
82  };
83 
85 
94  inline vec fromUnitBox(const vec& x, const vec& xLow, const vec& xUp) {
95  return xLow + (xUp - xLow) % x;
96  };
97 
99 
108  inline mat fromUnitBox(const mat& X, const vec& xLow, const vec& xUp) {
109  return arma::repmat(xLow, 1, X.n_cols) + arma::repmat(xUp - xLow, 1, X.n_cols) % X;
110  };
111 
113 
119  inline vec unitRescale(const vec& x) {
120  double xMin = arma::min(x);
121  double xMax = arma::max(x);
122  if( xMin == xMax ) {
123  return arma::ones(x.n_elem);
124  }
125  return (x - xMin)/(xMax - xMin);
126  };
127 
129 
138  class Result {
139  protected:
140  int mNumEvals = 0;
141  int mDim;
142  int mMaxEvals;
144  mat mX;
145  double mfBest;
147  public:
149 
153  Result(int maxEvals, int dim) {
154  mMaxEvals = maxEvals;
155  mNumEvals = 0;
156  mDim = dim;
157  mfX = std::numeric_limits<double>::max() * arma::ones<vec>(mMaxEvals);
158  mfBest = std::numeric_limits<double>::max();
159  mX = std::numeric_limits<double>::max() * arma::ones<mat>(dim, maxEvals);
160  mxBest = std::numeric_limits<double>::max() * arma::ones<mat>(dim);
161  }
163 
166  int dim() const {
167  return mDim;
168  }
169 
171 
174  int numEvals() const {
175  return mNumEvals;
176  }
177 
179 
182  vec fX() const {
183  if(mNumEvals == 0) {
184  throw std::logic_error("No evaluations have been added!");
185  }
186  return mfX.rows(0, mNumEvals-1);
187  }
188 
190 
193  mat X() const {
194  if(mNumEvals == 0) {
195  throw std::logic_error("No evaluations have been added!");
196  }
197  return mX.cols(0, mNumEvals-1);
198  }
199 
201 
204  vec xBest() const {
205  if(mNumEvals == 0) {
206  throw std::logic_error("No evaluations have been added!");
207  }
208  return mxBest;
209  }
210 
212 
215  double fBest() const {
216  if(mNumEvals == 0) {
217  throw std::logic_error("No evaluations have been added!");
218  }
219  return mfBest;
220  }
221 
223 
227  void addEval(const vec &x, double funVal) {
228  if(mNumEvals >= mMaxEvals) {
229  throw std::logic_error("Capacity exceeded");
230  }
231 
232  mX.col(mNumEvals) = x;
233  mfX(mNumEvals) = funVal;
234  if (funVal < mfBest) {
235  mfBest = funVal;
236  mxBest = x;
237  }
238  mNumEvals++;
239  }
241 
245  void addEvals(const mat &X, const vec &funVals) {
246  for(int i=0; i < X.n_cols; i++) {
247  vec x = X.col(i);
248  addEval(x, funVals(i));
249  }
250  }
251 
253  void reset() {
254  mNumEvals = 0;
255  mX = std::numeric_limits<double>::max() * arma::ones<mat>(mDim, mMaxEvals);
256  mxBest = std::numeric_limits<double>::max() * arma::ones<mat>(mDim);
257  mfX = std::numeric_limits<double>::max() * arma::ones<vec>(mMaxEvals);
258  mfBest = std::numeric_limits<double>::max();
259  }
260  };
261 
263 
272  inline uvec paretoFront(const vec &x, const vec &y) {
273  if(x.n_rows != y.n_rows) {
274  throw std::logic_error("paretoFront: x and y need to have the same length");
275  }
276  uvec isort = sort_index(x);
277  vec x2 = x(isort);
278  vec y2 = y(isort);
279  uvec indvec = arma::ones<uvec>(x.n_rows);
280  indvec(0) = isort(0);
281  int indcur = 1;
282  double ycur = y2(0);
283 
284  for(int i=1; i < x.n_rows; i++) {
285  if (y2(i) <= ycur) {
286  indvec(indcur) = isort(i);
287  ycur = y2(i);
288  indcur++;
289  }
290  }
291  indvec = indvec.head(indcur);
292  return indvec;
293  };
294 
296 
302  inline vec cumMin(const vec& x) {
303  vec out(x.n_elem);
304  out(0) = x(0);
305  for(int i=1; i < x.n_elem; i++) {
306  out(i) = std::min(x(i), out(i-1));
307  }
308  return out;
309  };
310 
312 
320  class StopWatch {
321  private:
322  std::chrono::time_point<std::chrono::system_clock> mStartTime;
323  std::chrono::time_point<std::chrono::system_clock> mEndTime;
324  bool mStarted;
325  public:
327 
331  mStarted = false;
332  }
334 
337  void start() {
338  if(mStarted) { throw std::logic_error("StopWatch: The StopWatch is already running, so can't start!"); }
339  mStartTime = std::chrono::system_clock::now();
340  mStarted = true;
341  }
343 
347  double stop() {
348  if(not mStarted) { throw std::logic_error("StopWatch: The StopWatch is not running, so can't stop!"); }
349  mEndTime = std::chrono::system_clock::now();
350  mStarted = false;
351  std::chrono::duration<double> elapsedSeconds = mEndTime - mStartTime;
352  return elapsedSeconds.count();
353  }
354  };
355 
356 
358 
364  inline double randi(int i) {
365  std::uniform_int_distribution<int> randi(0, i);
366  return randi(rng::mt);
367  }
368 
370 
375  inline double randn() {
376  std::normal_distribution<double> randn(0.0, 1.0);
377  return randn(rng::mt);
378  }
379 
381 
386  inline double rand() {
387  std::uniform_real_distribution<double> rand(0, 1);
388  return rand(rng::mt);
389  }
390 
392 
398  inline void setSeedRandom() {
399  // Set the armadillo seed randomly
400  arma::arma_rng::set_seed_random();
401 
402  // Set the SOT seed using chrono
403  typedef std::chrono::high_resolution_clock myClock;
404  myClock::time_point beginning = myClock::now();
405  myClock::duration d = myClock::now() - beginning;
406  unsigned newSeed = d.count();
407 
408  rng::mt.seed(newSeed);
409  }
410 
412 
417  inline void setSeed(unsigned seed) {
418  arma::arma_rng::set_seed(seed);
419  rng::mt.seed(seed);
420  }
421 }
422 
423 #endif
Optimization result class.
Definition: utils.h:138
vec fX() const
Method for getting the values of the finished evaluations.
Definition: utils.h:182
Stop watch class.
Definition: utils.h:320
double fBest() const
Method for getting the value of the best solution found so far.
Definition: utils.h:215
arma::vec vec
Default (column) vector class.
Definition: common.h:17
void setSeedRandom()
Set the seed to a random seed.
Definition: utils.h:398
vec xBest() const
Method for getting the best solution found so far.
Definition: utils.h:204
void addEvals(const mat &X, const vec &funVals)
Method for adding a finished evaluations.
Definition: utils.h:245
double stop()
Stops the watch and returns the time elapsed.
Definition: utils.h:347
arma::uvec uvec
Default unsigned (column) vector class.
Definition: common.h:22
int mMaxEvals
Definition: utils.h:142
int mNumEvals
Definition: utils.h:140
vec cumMin(const vec &x)
Computes the cumulative minimum.
Definition: utils.h:302
double rand()
Generate a U[0,1] realization.
Definition: utils.h:386
double randi(int i)
Generate a random integer.
Definition: utils.h:364
vec mxBest
Definition: utils.h:146
int mDim
Definition: utils.h:141
int dim() const
Method for getting the number of dimensions.
Definition: utils.h:166
MatType squaredPairwiseDistance(const MatType &X, const MatType &Y)
Fast level-3 distance computation between two sets of points.
Definition: utils.h:48
vec toUnitBox(const vec &x, const vec &xLow, const vec &xUp)
Map one point to the unit box.
Definition: utils.h:66
Result(int maxEvals, int dim)
Constructor.
Definition: utils.h:153
vec unitRescale(const vec &x)
Map a vector of values to the range [0, 1].
Definition: utils.h:119
VecType squaredPointSetDistance(const VecType &x, const MatType &Y)
Fast level-2 distance computation between one point and a set of points.
Definition: utils.h:32
StopWatch()
Constructor.
Definition: utils.h:330
uvec paretoFront(const vec &x, const vec &y)
Computes the Pareto front.
Definition: utils.h:272
double mfBest
Definition: utils.h:145
vec fromUnitBox(const vec &x, const vec &xLow, const vec &xUp)
Map one point from the unit box to another hypercube.
Definition: utils.h:94
double randn()
Generate a N(0,1) realization.
Definition: utils.h:375
mat X() const
Method for getting the evaluated points.
Definition: utils.h:193
void addEval(const vec &x, double funVal)
Method for adding a finished evaluation.
Definition: utils.h:227
SOT namespace.
Definition: sot.h:27
std::mt19937 mt(0)
The global random number generator.
arma::mat mat
Default matrix class.
Definition: common.h:16
void reset()
Method for resetting the object.
Definition: utils.h:253
int numEvals() const
Method for getting the number of finished evaluations.
Definition: utils.h:174
mat mX
Definition: utils.h:144
vec mfX
Definition: utils.h:143
void setSeed(unsigned seed)
Set the seed to a given seed.
Definition: utils.h:417
void start()
Starts the watch.
Definition: utils.h:337