-
Notifications
You must be signed in to change notification settings - Fork 79
Defining a custom algorithm based on libcmaes primitives
beniz edited this page Dec 19, 2014
·
2 revisions
It is possible to directly expose the inner calls of the library in order to develop new algorithms.
This is typically useful to craft new restart strategies, or specialized optimization loops with custom control.
The code below is available from examples/sample-code-ask-tell.cc and demonstrates how to override the default optimization strategy class.
Since the library is fully object oriented, a user custom space can be easily created by inheriting the default CMAStrategy class, overloading and customizing functions and classes at will:
#include "cmaes.h"
#include <iostream>
using namespace libcmaes;
FitFunc fsphere = [](const double *x, const int N)
{
double val = 0.0;
for (int i=0;i<N;i++)
val += x[i]*x[i];
return val;
};
class customCMAStrategy : public CMAStrategy<CovarianceUpdate>
{
public:
customCMAStrategy(FitFunc &func,
CMAParameters<> ¶meters)
:CMAStrategy<CovarianceUpdate>(func,parameters)
{
}
~customCMAStrategy() {}
dMat ask()
{
return CMAStrategy<CovarianceUpdate>::ask();
}
void eval(const dMat &candidates,
const dMat &phenocandidates=dMat(0,0))
// custom eval.
for (int r=0;r<candidates.cols();r++)
{
_solutions.get_candidate(r)._x = candidates.col(r);
if (phenocandidates.size()) // if candidates in phenotype space are given
_solutions.get_candidate(r).set_fvalue(_func(phenocandidates.col(r).data(),candidates.rows()));
else _solutions.get_candidate(r).set_fvalue(_func(candidates.col(r).data(),candidates.rows()));
//std::cerr << "candidate x: " << _solutions._candidate(r).get_x_dvec().transpose() << std::endl;
}
update_fevals(candidates.cols());
}
void tell()
{
return CMAStrategy<CovarianceUpdate>::tell();
}
bool stop()
{
return CMAStrategy<CovarianceUpdate>::stop();
}
};
int main(int argc, char *argv[])
{
int dim = 10; // problem dimensions.
std::vector<double> x0(dim,10.0);
double sigma = 0.1;
CMAParameters<> cmaparams(x0,sigma);
//ESOptimizer<CMAStrategy<CovarianceUpdate>,CMAParameters<>> optim(fsphere,cmaparams); // default call
ESOptimizer<customCMAStrategy,CMAParameters<>> optim(fsphere,cmaparams);
while(!optim.stop())
{
dMat candidates = optim.ask();
optim.eval(candidates);
optim.tell();
optim.inc_iter(); // important step: signals next iteration.
}
std::cout << optim.get_solutions() << std::endl;
}