libcmaes 0.10.2
A C++11 library for stochastic optimization with CMA-ES
Loading...
Searching...
No Matches
genopheno.h
1
22#ifndef GENOPHENO_H
23#define GENOPHENO_H
24
25#include <libcmaes/noboundstrategy.h>
26#include <libcmaes/pwq_bound_strategy.h>
27#include <libcmaes/scaling.h>
28#include <vector>
29
30namespace libcmaes
31{
32 typedef std::function<void (const double*, double*, const int&)> TransFunc;
33
34 template <class TBoundStrategy=NoBoundStrategy,class TScalingStrategy=NoScalingStrategy>
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 {
90 (void)shift;
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:42
an optimizer main class.
Definition esoptimizer.h:72
ESOptimizer()
dummy constructor
Definition esoptimizer.h:77
Definition genopheno.h:36
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
bool _id
Definition genopheno.h:259
linear scaling of the parameter space to achieve similar sensitivity across all components.
Definition acovarianceupdate.h:30