SOT
adaptive_sampling.h
1 
8 #ifndef SOT_ADAPTIVE_SAMPLING_H
9 #define SOT_ADAPTIVE_SAMPLING_H
10 
11 #include "common.h"
12 #include "utils.h"
13 #include "problem.h"
14 #include "genetic_algorithm.h"
15 
17 namespace sot {
18 
20 
29  class Sampling {
30  public:
32 
35  virtual void reset(int budget) = 0;
36 
38 
45  virtual mat makePoints(const vec &xBest, const mat &points, const vec &sigma, int newPoints) = 0;
46  };
47 
49 
60  template<class MeritFunction = MeritWeightedDistance>
61  class SRBF : public Sampling {
62  protected:
63  std::shared_ptr<Problem> mData;
64  std::shared_ptr<Surrogate> mSurf;
65  int mNumCand;
66  int mDim;
69  double mDistTol;
70  int mNumEvals = 0;
71  int mBudget;
73  public:
75 
81  SRBF(const std::shared_ptr<Problem>& data, const std::shared_ptr<Surrogate>& surf, int numCand, int budget) {
82  mData = std::shared_ptr<Problem>(data);
83  mSurf = std::shared_ptr<Surrogate>(surf);
84  mBudget = budget;
85  mNumCand = numCand;
86  mDim = data->dim();
87  mxLow = data->lBounds();
88  mxUp = data->uBounds();
89  mDistTol = 1e-3*sqrt(arma::sum(arma::square(mxUp - mxLow)));
90  }
91 
93 
96  void reset(int budget) {
97  mBudget = budget;
98  mNumEvals = 0;
99  }
100 
102 
109  mat makePoints(const vec &xBest, const mat &points, const vec &sigma, int newPoints) {
110 
111  // Generate perturbations
112  mat cand = arma::repmat(xBest, 1, mNumCand);
113  mat pert = arma::randn(mDim, mNumCand);
114  pert.each_col() %= sigma;
115  cand += pert;
116 
117  for(int i=0; i < mNumCand; i++) {
118  for(int j=0; j < mDim; j++) {
119  if(cand(j, i) > mxUp(j)) { //
120  cand(j, i) = fmax(2*mxUp(j) - cand(j, i), mxLow(j));
121  }
122  else if(cand(j, i) < mxLow(j)) {
123  cand(j, i) = fmin(2*mxLow(j) - cand(j, i), mxUp(j));
124  }
125  }
126  }
127 
128  // Update counter
129  mNumEvals += newPoints;
130 
131  return mMerit.pickPoints(cand, mSurf, points, newPoints, mDistTol);
132  }
133  };
134 
136 
152  template<class MeritFunction = MeritWeightedDistance>
153  class DYCORS : public Sampling {
154  protected:
155  std::shared_ptr<Problem> mData;
156  std::shared_ptr<Surrogate> mSurf;
157  int mNumCand;
158  int mDim;
161  double mDistTol;
162  int mNumEvals = 0;
163  int mBudget;
165  public:
167 
173  DYCORS(const std::shared_ptr<Problem>& data, const std::shared_ptr<Surrogate>& surf,
174  int numCand, int budget) {
175  mData = std::shared_ptr<Problem>(data);
176  mSurf = std::shared_ptr<Surrogate>(surf);
177  mBudget = budget;
178  mNumCand = numCand;
179  mDim = data->dim();
180  mxLow = data->lBounds();
181  mxUp = data->uBounds();
182  mDistTol = 1e-3*sqrt(arma::sum(arma::square(mxUp - mxLow)));
183  }
184 
186 
189  void reset(int budget) {
190  mBudget = budget;
191  mNumEvals = 0;
192  }
193 
195 
202  mat makePoints(const vec &xBest, const mat &points, const vec &sigma, int newPoints) {
203  double dds_prob = std::min(20.0/mDim, 1.0) *
204  (1.0 - (std::log(mNumEvals + 1.0) / std::log(double(mBudget))));
205  mat cand = arma::repmat(xBest, 1, mNumCand);
206 
207  for(int i=0; i < mNumCand; i++) {
208 
209  int count = 0;
210  for(int j=0; j < mDim; j++) {
211  if(rand() < dds_prob) {
212  count++;
213  cand(j, i) += sigma(j)*randn();
214  }
215  }
216  // If no index was perturbed we force one
217  if(count == 0) {
218  int ind = randi(mDim-1);
219  cand(ind, i) += sigma(ind)*randn();
220  }
221 
222  // Make sure we are still in the domain
223  for(int j=0; j < mDim; j++) {
224  if(cand(j, i) > mxUp(j)) {
225  cand(j, i) = fmax(2*mxUp(j) - cand(j, i), mxLow(j));
226  }
227  else if(cand(j, i) < mxLow(j)) {
228  cand(j, i) = fmin(2*mxLow(j) - cand(j, i), mxUp(j));
229  }
230  }
231  }
232 
233  // Update counter
234  mNumEvals += newPoints;
235 
236  return mMerit.pickPoints(cand, mSurf, points, newPoints, mDistTol);
237  }
238  };
239 
241 
254  template<class MeritFunction = MeritWeightedDistance>
255  class Uniform : public Sampling {
256  protected:
257  std::shared_ptr<Problem> mData;
258  std::shared_ptr<Surrogate> mSurf;
259  int mNumCand;
260  int mDim;
263  double mDistTol;
264  int mNumEvals = 0;
265  int mBudget;
267  public:
269 
275  Uniform(const std::shared_ptr<Problem>& data, const std::shared_ptr<Surrogate>& surf, int numCand, int budget) {
276  mData = std::shared_ptr<Problem>(data);
277  mSurf = std::shared_ptr<Surrogate>(surf);
278  mBudget = budget;
279  mNumCand = numCand;
280  mDim = data->dim();
281  mxLow = data->lBounds();
282  mxUp = data->uBounds();
283  mDistTol = 1e-3*sqrt(arma::sum(arma::square(mxUp - mxLow)));
284  }
285 
287 
290  void reset(int budget) {
291  mBudget = budget;
292  mNumEvals = 0;
293  }
294 
296 
303  mat makePoints(const vec &xBest, const mat &points, const vec &sigma, int newPoints) {
304 
305  mat cand = arma::randu<mat>(mDim, mNumCand);
306  for(int j=0; j < mDim; j++) {
307  cand.row(j) = mxLow(j) + (mxUp(j) - mxLow(j)) * cand.row(j);
308  }
309 
310  // Update counter
311  mNumEvals += newPoints;
312 
313  return mMerit.pickPoints(cand, mSurf, points, newPoints, mDistTol);
314  }
315  };
316 
318 
326  class GAWrapper : public Problem {
327  protected:
328  std::shared_ptr<Surrogate> mSurf;
329  int mDim;
334  double mMinimum = 0;
335  std::string mName = "GA surrogate wrapper";
336  double mDistTol;
337  public:
339 
345  GAWrapper(const std::shared_ptr<Problem> &data, const std::shared_ptr<Surrogate> &surf,
346  const mat &points, double distTol) {
347  mDim = data->dim();
348  mxLow = data->lBounds();
349  mxUp = data->uBounds();
350  mSurf = std::shared_ptr<Surrogate>(surf);
351  mPoints = points;
352  mDistTol = distTol;
353  }
354  vec lBounds() const { return mxLow; }
355  vec uBounds() const { return mxUp; }
356  int dim() const { return mDim; }
357  double min() const { return mMinimum; }
358  vec optimum() const { return mOptimum; }
359  std::string name() const { return mName; }
360  double eval(const vec &x) const { return 0; }
362 
366  vec evals(const mat &X) const {
367 
368  mat dists = arma::sqrt(squaredPairwiseDistance<mat>(mPoints, X));
369  // Evaluate the Surrogate at the points
370  vec surfVals;
371 
372  if(mSurf->numPoints() == X.n_cols && mPoints.n_cols == X.n_cols) {
373  surfVals = mSurf->evals(X, dists);
374  }
375  else {
376  surfVals = mSurf->evals(X);
377  }
378 
379  vec minDists = arma::min(dists).t();
380  // Set the points that are too close to something large
381  surfVals.elem(arma::find(minDists < mDistTol)).fill(arma::datum::inf);
382  return surfVals;
383  }
384  };
385 
387 
395  class GASampling : public Sampling {
396  protected:
397  std::shared_ptr<Problem> mData;
398  std::shared_ptr<Surrogate> mSurf;
399  int mDim;
404  double mDistTol;
405  public:
407 
413  GASampling(const std::shared_ptr<Problem>& data, const std::shared_ptr<Surrogate>& surf,
414  int numIndividuals, int numGenerations) {
415  mData = std::shared_ptr<Problem>(data);
416  mSurf = std::shared_ptr<Surrogate>(surf);
417  mDim = data->dim();
418  mxLow = data->lBounds();
419  mxUp = data->uBounds();
420  mNumIndividuals = numIndividuals;
421  mNumGenerations = numGenerations;
422  mDistTol = 1e-3*sqrt(arma::sum(arma::square(mxUp - mxLow)));
423  }
424 
425  void reset(int budget) {}
426 
427  mat makePoints(const vec &xBest, const mat &points, const vec &sigma, int newPoints) {
428  if (newPoints > 1) {
429  mat points2 = points;
430  mat xNew = arma::zeros(mDim, newPoints);
431  for(int i=0; i < newPoints; i++) {
432  std::shared_ptr<Problem> gaWrapper(
433  std::make_shared<GAWrapper>(mData, mSurf, points2, arma::norm(sigma)));
434  GeneticAlgorithm ga(gaWrapper, mNumIndividuals, mNumGenerations);
435  Result res = ga.run();
436  xNew.col(i) = res.xBest();
437  points2 = arma::join_horiz(points2, res.xBest());
438  }
439  return xNew;
440  }
441  else {
442  std::shared_ptr<Problem> gaWrapper(
443  std::make_shared<GAWrapper>(mData, mSurf, points, arma::norm(sigma)));
444  GeneticAlgorithm ga(gaWrapper, mNumIndividuals, mNumGenerations);
445  Result res = ga.run();
446  return res.xBest();
447  }
448  }
449  };
450 }
451 
452 #endif
Optimization result class.
Definition: utils.h:138
int mBudget
Definition: adaptive_sampling.h:265
int mNumCand
Definition: adaptive_sampling.h:157
Uniform(const std::shared_ptr< Problem > &data, const std::shared_ptr< Surrogate > &surf, int numCand, int budget)
Constructor.
Definition: adaptive_sampling.h:275
int mDim
Definition: adaptive_sampling.h:158
GAWrapper(const std::shared_ptr< Problem > &data, const std::shared_ptr< Surrogate > &surf, const mat &points, double distTol)
Constructor.
Definition: adaptive_sampling.h:345
Abstract class for a SOT merit function.
Definition: merit_functions.h:28
vec mxLow
Definition: adaptive_sampling.h:67
arma::vec vec
Default (column) vector class.
Definition: common.h:17
vec xBest() const
Method for getting the best solution found so far.
Definition: utils.h:204
MeritFunction mMerit
Definition: adaptive_sampling.h:72
double mDistTol
Definition: adaptive_sampling.h:161
double mDistTol
Definition: adaptive_sampling.h:263
GASampling(const std::shared_ptr< Problem > &data, const std::shared_ptr< Surrogate > &surf, int numIndividuals, int numGenerations)
Constructor.
Definition: adaptive_sampling.h:413
void reset(int budget)
Resets the object for a new budget (useful if a strategy restarts)
Definition: adaptive_sampling.h:189
std::shared_ptr< Surrogate > mSurf
Definition: adaptive_sampling.h:328
std::shared_ptr< Surrogate > mSurf
Definition: adaptive_sampling.h:398
double mDistTol
Definition: adaptive_sampling.h:336
int mBudget
Definition: adaptive_sampling.h:163
vec mOptimum
Definition: adaptive_sampling.h:333
vec mxUp
Definition: adaptive_sampling.h:68
vec mxUp
Definition: adaptive_sampling.h:401
MeritFunction mMerit
Definition: adaptive_sampling.h:164
virtual void reset(int budget)=0
Virtual method for reseting the object.
int mBudget
Definition: adaptive_sampling.h:71
void reset(int budget)
Resets the object for a new budget (useful if a strategy restarts)
Definition: adaptive_sampling.h:96
int mNumIndividuals
Definition: adaptive_sampling.h:402
int mDim
Definition: adaptive_sampling.h:260
std::shared_ptr< Problem > mData
Definition: adaptive_sampling.h:63
Uniformly chosen candidate points.
Definition: adaptive_sampling.h:255
mat mPoints
Definition: adaptive_sampling.h:330
vec mxLow
Definition: adaptive_sampling.h:159
Wrapper to turn a surrogate model into an optimization problem.
Definition: adaptive_sampling.h:326
int mDim
Definition: adaptive_sampling.h:399
Use a GA to minimize the surrogate.
Definition: adaptive_sampling.h:395
std::shared_ptr< Problem > mData
Definition: adaptive_sampling.h:155
double rand()
Generate a U[0,1] realization.
Definition: utils.h:386
vec mxLow
Definition: adaptive_sampling.h:400
std::shared_ptr< Surrogate > mSurf
Definition: adaptive_sampling.h:258
virtual mat makePoints(const vec &xBest, const mat &points, const vec &sigma, int newPoints)=0
Virtual method for proposing new evaluations.
int dim() const
Method for getting the number of dimensions.
Definition: adaptive_sampling.h:356
vec optimum() const
Method for getting the global minimizer.
Definition: adaptive_sampling.h:358
vec uBounds() const
Method for getting the upper variable bounds.
Definition: adaptive_sampling.h:355
double randi(int i)
Generate a random integer.
Definition: utils.h:364
mat makePoints(const vec &xBest, const mat &points, const vec &sigma, int newPoints)
Proposes new evaluations.
Definition: adaptive_sampling.h:202
Genetic Algorithm.
Definition: genetic_algorithm.h:32
vec mxLow
Definition: adaptive_sampling.h:261
int mDim
Definition: adaptive_sampling.h:329
void reset(int budget)
Resets the object for a new budget (useful if a strategy restarts)
Definition: adaptive_sampling.h:290
std::shared_ptr< Problem > mData
Definition: adaptive_sampling.h:397
double min() const
Method for getting global minimum value.
Definition: adaptive_sampling.h:357
std::string name() const
Method for getting the name of the optimization problem.
Definition: adaptive_sampling.h:359
DYnamic COordinate search using Response Surface models.
Definition: adaptive_sampling.h:153
MeritFunction mMerit
Definition: adaptive_sampling.h:266
vec mxLow
Definition: adaptive_sampling.h:331
vec mxUp
Definition: adaptive_sampling.h:332
mat makePoints(const vec &xBest, const mat &points, const vec &sigma, int newPoints)
Virtual method for proposing new evaluations.
Definition: adaptive_sampling.h:427
vec lBounds() const
Method for getting the lower variable bounds.
Definition: adaptive_sampling.h:354
DYCORS(const std::shared_ptr< Problem > &data, const std::shared_ptr< Surrogate > &surf, int numCand, int budget)
Constructor.
Definition: adaptive_sampling.h:173
SRBF(const std::shared_ptr< Problem > &data, const std::shared_ptr< Surrogate > &surf, int numCand, int budget)
Constructor.
Definition: adaptive_sampling.h:81
vec mxUp
Definition: adaptive_sampling.h:262
int mNumCand
Definition: adaptive_sampling.h:259
std::shared_ptr< Surrogate > mSurf
Definition: adaptive_sampling.h:156
vec mxUp
Definition: adaptive_sampling.h:160
mat makePoints(const vec &xBest, const mat &points, const vec &sigma, int newPoints)
Proposes new evaluations.
Definition: adaptive_sampling.h:303
vec evals(const mat &X) const
Method for evaluating the objective function at multiple points.
Definition: adaptive_sampling.h:366
Abstract class for a SOT adaptive sampling class.
Definition: adaptive_sampling.h:29
Stochastic RBF.
Definition: adaptive_sampling.h:61
int mDim
Definition: adaptive_sampling.h:66
int mNumCand
Definition: adaptive_sampling.h:65
double randn()
Generate a N(0,1) realization.
Definition: utils.h:375
Result run()
Runs the optimization algorithm.
Definition: genetic_algorithm.h:143
double mDistTol
Definition: adaptive_sampling.h:69
int mNumGenerations
Definition: adaptive_sampling.h:403
mat makePoints(const vec &xBest, const mat &points, const vec &sigma, int newPoints)
Proposes new evaluations.
Definition: adaptive_sampling.h:109
SOT namespace.
Definition: sot.h:27
double mDistTol
Definition: adaptive_sampling.h:404
virtual mat pickPoints(const mat &cand, const std::shared_ptr< Surrogate > &surf, const mat &points, int newPoints, double distTol)=0
Method for picking the next point.
double eval(const vec &x) const
Method for evaluating the objective function.
Definition: adaptive_sampling.h:360
Abstract class for a SOT optimization problem.
Definition: problem.h:24
arma::mat mat
Default matrix class.
Definition: common.h:16
std::shared_ptr< Surrogate > mSurf
Definition: adaptive_sampling.h:64
void reset(int budget)
Virtual method for reseting the object.
Definition: adaptive_sampling.h:425
std::shared_ptr< Problem > mData
Definition: adaptive_sampling.h:257