libcmaes
A C++11 library for stochastic optimization with CMA-ES
 All Classes Namespaces Functions Variables Typedefs
genopheno.h
1 
22 #ifndef GENOPHENO_H
23 #define GENOPHENO_H
24 
25 #include "noboundstrategy.h"
26 #include "pwq_bound_strategy.h"
27 #include "scaling.h"
28 #include <vector>
29 
30 namespace libcmaes
31 {
32  typedef std::function<void (const double*, double*, const int&)> TransFunc;
33 
34  template <class TBoundStrategy=NoBoundStrategy,class TScalingStrategy=NoScalingStrategy>
35  class GenoPheno
36  {
37  friend class CMASolutions;
38 
39  public:
40  GenoPheno()
41  :_id(true)
42  {}
43 
44  GenoPheno(TransFunc &genof, TransFunc &phenof)
45  :_genof(genof),_phenof(phenof),_id(false)
46  {}
47 
48  GenoPheno(const double *lbounds, const double *ubounds, const int &dim)
49  :_boundstrategy(lbounds,ubounds,dim),_id(true),_scalingstrategy(lbounds,ubounds,dim)
50  {
51  if (_scalingstrategy._id)
52  _boundstrategy = TBoundStrategy(lbounds,ubounds,dim);
53  else
54  {
55  std::vector<double> lb(dim,_scalingstrategy._intmin);
56  std::vector<double> ub(dim,_scalingstrategy._intmax);
57  _boundstrategy = TBoundStrategy(&lb.front(),&ub.front(),lbounds,ubounds,dim);
58  }
59  }
60 
61  GenoPheno(TransFunc &genof, TransFunc &phenof,
62  const double *lbounds, const double *ubounds, const int &dim)
63  :_boundstrategy(lbounds,ubounds,dim),_genof(genof),_phenof(phenof),_id(false),_scalingstrategy(lbounds,ubounds,dim)
64  {
65  if (_scalingstrategy._id)
66  _boundstrategy = TBoundStrategy(lbounds,ubounds,dim);
67  else
68  {
69  std::vector<double> lb(dim,_scalingstrategy._intmin);
70  std::vector<double> ub(dim,_scalingstrategy._intmax);
71  _boundstrategy = TBoundStrategy(&lb.front(),&ub.front(),lbounds,ubounds,dim);
72  }
73  }
74 
83  GenoPheno(const dVec &scaling,
84  const dVec &shift,
85  const double *lbounds=nullptr,
86  const double *ubounds=nullptr)
87  :_id(true)
88  {
89  (void)scaling;
90  (void)shift;
91  (void)lbounds;
92  (void)ubounds;
93  }
94 
95  ~GenoPheno() {}
96 
97  private:
98  dMat pheno_candidates(const dMat &candidates) const
99  {
100  if (!_id)
101  {
102  dMat ncandidates = dMat(candidates.rows(),candidates.cols());
103 #pragma omp parallel for if (candidates.cols() >= 100)
104  for (int i=0;i<candidates.cols();i++)
105  {
106  dVec ext = dVec(candidates.rows());
107  _phenof(candidates.col(i).data(),ext.data(),candidates.rows());
108  ncandidates.col(i) = ext;
109  }
110  return ncandidates;
111  }
112  return candidates;
113  }
114 
115  dMat geno_candidates(const dMat &candidates) const
116  {
117  if (!_id)
118  {
119  dMat ncandidates = dMat(candidates.rows(),candidates.cols());
120 #pragma omp parallel for if (candidates.cols() >= 100)
121  for (int i=0;i<candidates.cols();i++)
122  {
123  dVec in = dVec(candidates.rows());
124  _genof(candidates.col(i).data(),in.data(),candidates.rows());
125  ncandidates.col(i) = in;
126  }
127  return ncandidates;
128  }
129  return candidates;
130  }
131 
132  public:
133  dMat pheno(const dMat &candidates) const
134  {
135  // apply custom pheno function.
136  dMat ncandidates = pheno_candidates(candidates);
137 
138  // apply bounds.
139 #pragma omp parallel for if (ncandidates.cols() >= 100)
140  for (int i=0;i<ncandidates.cols();i++)
141  {
142  dVec ycoli;
143  _boundstrategy.to_f_representation(ncandidates.col(i),ycoli);
144  ncandidates.col(i) = ycoli;
145  }
146 
147  // apply scaling.
148  if (!_scalingstrategy._id)
149  {
150 #pragma omp parallel for if (ncandidates.cols() >= 100)
151  for (int i=0;i<ncandidates.cols();i++)
152  {
153  dVec ycoli;
154  _scalingstrategy.scale_to_f(ncandidates.col(i),ycoli);
155  ncandidates.col(i) = ycoli;
156  }
157  }
158  return ncandidates;
159  }
160 
161  dMat geno(const dMat &candidates) const
162  {
163  // reverse scaling.
164  dMat ncandidates = candidates;
165  if (!_scalingstrategy._id)
166  {
167 #pragma omp parallel for if (ncandidates.cols() >= 100)
168  for (int i=0;i<ncandidates.cols();i++)
169  {
170  dVec ycoli;
171  _scalingstrategy.scale_to_internal(ycoli,ncandidates.col(i));
172  ncandidates.col(i) = ycoli;
173  }
174  }
175 
176  // reverse bounds.
177 #pragma omp parallel for if (ncandidates.cols() >= 100)
178  for (int i=0;i<ncandidates.cols();i++)
179  {
180  dVec ycoli;
181  _boundstrategy.to_internal_representation(ycoli,ncandidates.col(i));
182  ncandidates.col(i) = ycoli;
183  }
184 
185  // apply custom geno function.
186  ncandidates = geno_candidates(ncandidates);
187  return ncandidates;
188  }
189 
190  dVec pheno(const dVec &candidate) const
191  {
192  // apply custom pheno function.
193  dVec ncandidate;
194  if (!_id)
195  {
196  ncandidate = dVec(candidate.rows());
197  _phenof(candidate.data(),ncandidate.data(),candidate.rows());
198  }
199 
200  // apply bounds.
201  dVec phen = dVec::Zero(candidate.rows());
202  if (_id)
203  _boundstrategy.to_f_representation(candidate,phen);
204  else _boundstrategy.to_f_representation(ncandidate,phen);
205 
206  // apply scaling.
207  if (!_scalingstrategy._id)
208  {
209  dVec sphen = dVec::Zero(phen.rows());
210  _scalingstrategy.scale_to_f(phen,sphen);
211  phen = sphen;
212  }
213  return phen;
214  }
215 
216  dVec geno(const dVec &candidate) const
217  {
218  dVec ccandidate = candidate;
219  dVec gen = dVec::Zero(candidate.rows());
220 
221  // reverse scaling.
222  if (!_scalingstrategy._id)
223  {
224  _scalingstrategy.scale_to_internal(gen,candidate);
225  ccandidate = gen;
226  }
227 
228  // reverse bounds.
229  _boundstrategy.to_internal_representation(gen,ccandidate);
230 
231  // apply custom geno function.
232  if (!_id)
233  {
234  dVec ncandidate(gen.rows());
235  _genof(gen.data(),ncandidate.data(),gen.rows());
236  return ncandidate;
237  }
238  else return gen;
239  }
240 
241  TBoundStrategy get_boundstrategy() const { return _boundstrategy; }
242 
243  TBoundStrategy& get_boundstrategy_ref() { return _boundstrategy; }
244 
245  TScalingStrategy get_scalingstrategy() const { return _scalingstrategy; }
246 
247  void remove_dimensions(const std::vector<int> &k)
248  {
249  if (!_scalingstrategy.is_id())
250  _scalingstrategy.remove_dimensions(k);
251  if (!_boundstrategy.is_id())
252  _boundstrategy.remove_dimensions(k);
253  }
254 
255  private:
256  TBoundStrategy _boundstrategy;
257  TransFunc _genof;
258  TransFunc _phenof;
259  bool _id = false;
260  TScalingStrategy _scalingstrategy;
261  };
262 
263  // specialization when no bound strategy nor scaling applies.
264  template<> inline dMat GenoPheno<NoBoundStrategy,NoScalingStrategy>::pheno(const dMat &candidates) const
265  {
266  if (_id)
267  return candidates;
268  else return pheno_candidates(candidates);
269  }
270  template<> inline dVec GenoPheno<NoBoundStrategy,NoScalingStrategy>::pheno(const dVec &candidate) const
271  {
272  if (_id)
273  return candidate;
274  else
275  {
276  dVec ncandidate(candidate.rows());
277  _phenof(candidate.data(),ncandidate.data(),candidate.rows());
278  return ncandidate;
279  }
280  }
281  template<> inline dVec GenoPheno<NoBoundStrategy,NoScalingStrategy>::geno(const dVec &candidate) const
282  {
283  if (_id)
284  return candidate;
285  else
286  {
287  dVec ncandidate(candidate.rows());
288  _genof(candidate.data(),ncandidate.data(),candidate.rows());
289  return ncandidate;
290  }
291  }
292 
293  template<> inline dVec GenoPheno<NoBoundStrategy,linScalingStrategy>::pheno(const dVec &candidate) const
294  {
295  dVec ncandidate(candidate.rows());
296  if (!_id)
297  _phenof(candidate.data(),ncandidate.data(),candidate.rows());
298 
299  dVec sphen;
300  if (!_id)
301  _scalingstrategy.scale_to_f(ncandidate,sphen);
302  else _scalingstrategy.scale_to_f(candidate,sphen);
303  return sphen;
304  }
305  template<> inline dVec GenoPheno<NoBoundStrategy,linScalingStrategy>::geno(const dVec &candidate) const
306  {
307  dVec scand = dVec::Zero(candidate.rows());
308  _scalingstrategy.scale_to_internal(scand,candidate);
309  if (_id)
310  return scand;
311  else
312  {
313  dVec ncandidate(candidate.rows());
314  _genof(scand.data(),scand.data(),candidate.rows());
315  return ncandidate;
316  }
317  }
318  template<> inline dMat GenoPheno<NoBoundStrategy,linScalingStrategy>::pheno(const dMat &candidates) const
319  {
320  dMat ncandidates;
321  if (!_id)
322  ncandidates = pheno_candidates(candidates);
323  else ncandidates = candidates;
324 
325  // apply scaling.
326 #pragma omp parallel for if (ncandidates.cols() >= 100)
327  for (int i=0;i<ncandidates.cols();i++)
328  {
329  dVec ycoli;
330  _scalingstrategy.scale_to_f(ncandidates.col(i),ycoli);
331  ncandidates.col(i) = ycoli;
332  }
333  return ncandidates;
334  }
335 
336  template<> inline GenoPheno<NoBoundStrategy,linScalingStrategy>::GenoPheno(const dVec &scaling,
337  const dVec &shift,
338  const double *lbounds,
339  const double *ubounds)
340  :_id(true)
341  {
342  (void)lbounds;
343  (void)ubounds;
344  _scalingstrategy = linScalingStrategy(scaling,shift);
345  }
346 
347  template<> inline GenoPheno<pwqBoundStrategy,linScalingStrategy>::GenoPheno(const dVec &scaling,
348  const dVec &shift,
349  const double *lbounds,
350  const double *ubounds)
351  :_id(true)
352  {
353  _scalingstrategy = linScalingStrategy(scaling,shift);
354  if (lbounds == nullptr || ubounds == nullptr)
355  return;
356  dVec vlbounds = Eigen::Map<dVec>(const_cast<double*>(lbounds),scaling.size());
357  dVec vubounds = Eigen::Map<dVec>(const_cast<double*>(ubounds),scaling.size());
358  dVec nlbounds, nubounds;
359  _scalingstrategy.scale_to_internal(nlbounds,vlbounds);
360  _scalingstrategy.scale_to_internal(nubounds,vubounds);
361  _boundstrategy = pwqBoundStrategy(nlbounds.data(),nubounds.data(),scaling.size());
362  }
363 }
364 
365 #endif
Holder of the set of evolving solutions from running an instance of CMA-ES.
Definition: cmasolutions.h:41
GenoPheno(const dVec &scaling, const dVec &shift, const double *lbounds=nullptr, const double *ubounds=nullptr)
this is a dummy constructor to accomodate an easy to use linear scaling with pwq bounds from a given ...
Definition: genopheno.h:83
linear scaling of the parameter space to achieve similar sensitivity across all components.
Definition: acovarianceupdate.cc:25
Definition: genopheno.h:35