1#if !defined(LOOS_MC_FIT_HPP)
7#include <boost/random/linear_congruential.hpp>
8#include <boost/random/uniform_real.hpp>
9#include <boost/random/variate_generator.hpp>
13typedef boost::minstd_rand rand_num;
15struct ConstantAcceptor {
16 ConstantAcceptor() : val(0.25) { }
17 ConstantAcceptor(
double d) : val(d) { }
18 double operator()(
const uint iter) {
return(val); }
24struct ExponentialAcceptor {
25 ExponentialAcceptor() : k(1.0) { }
26 ExponentialAcceptor(
const double scale) : k(scale) { }
27 double operator()(
const uint iter) {
return(exp(-k * iter)); }
33template<
typename T =
double>
35 typedef std::vector< std::vector<T> > VVectors;
44 void setParams(
const vector<T>& v) {
48 vector<T> getParams()
const {
return(myparams); }
73 vector<T> randomize(
const vector<T>& current,
const vector<T>& sizes) {
80 for (
int i = 0; i < previous.getParams->paramSize(); ++i){
88 boost::uniform_real<> uni_dist(-1, 1);
89 boost::variate_generator<rand_num&, boost::uniform_real<> > uni(generator, uni_dist);
90 double scaled_random = (uni() + uni()) * current[i];
91 newParams.push_back(scaled_random + current[i]);
97 T randomize(uint iter){
99 T upperbound = acceptance(iter);
100 boost::uniform_real<> uni_dist(0, upperbound*2);
101 boost::variate_generator<rand_num&, boost::uniform_real<> > uni(single_random, uni_dist);
102 double my_random = uni();
119 template<
class C,
class Acceptor = ConstantAcceptor>
120 vector<T> takeStep(
const vector<T>& current,
const vector<T>& sizes, C& ftor, Acceptor& acc, uint iter) {
122 vector<T> newStep = randomize(current, sizes);
123 T prev = ftor(current);
124 T val = ftor(newStep);
128 }elseif (randomize(iter) < acc(iter)){
137 template<
class C,
class A = ConstantAcceptor>
138 vector<T> optimize(
const vector<T>& current, C& ftor, A& ator) {
140 vector<T> params(current);
141 vector<T> sizes(initial_sizes);
145 vector<T> params = takeStep(params, sizes, ftor, ator, iter);
151 void setSizes(
const vector<T>& s) {
159 vector<T> initial_sizes;
170 int i, next_worst, j, mpts;
171 T best, current, previous;
175 for (j=0; j<ndim; j++) {
176 for (sum = 0.0, i = 0; i<mpts; i++)
178 sum += simplex[i][j];
184 while (n_evals <= maxiters) {
186 if (values[0] > values[1]) {
197 for (i=0; i<mpts; i++) {
198 if (values[i] <= values[best])
200 if (values[i] > values[worst]) {
203 }
else if (values[i] > values[next_worst] && i != worst)
211 num = fabs(values[worst] - values[best]);
212 den = fabs(values[worst]) + fabs(values[best]);
213 rtol = 2.0 * num / den;
214 if (rtol < tol || num == den)
220 val = modify(-1.0, ftor);
221 if (val <= values[best])
222 val = modify(2.0, ftor);
223 else if (val >= values[next_worst]) {
225 saved = values[worst];
226 val = modify(0.5, ftor);
229 for (i=0; i<mpts; i++) {
231 for (j=0; j<ndim; j++)
232 simplex[i][j] = simpsum[j] = 0.5 * (simplex[i][j] + simplex[best][j]);
233 values[i] = ftor(simpsum);
238 for (j=0; j<ndim; j++) {
239 for (sum=0.0, i=0; i<mpts; i++)
240 sum += simplex[i][j];
253 void allocateSpace(
const int n) {
254 q = std::vector<T>(n+1, 0.0);
255 qq = std::vector<T>(n+1, 0.0);
256 simpsum = std::vector<T>(n, 0.0);
257 values = std::vector<T>(n+1, 0.0);
258 trial = std::vector<T>(n, 0.0);
260 for (
int i=0; i<n+1; ++i)
261 simplex.push_back(std::vector<T>(n, 0.0));
268 Simplex(
const int n) : tol(1e-3), ndim(n), maxiters(2000), best(-1), worst(-1) {
273 void dim(
const int n) { ndim = n; allocateSpace(n); }
276 void seedLengths(
const std::vector<T>& seeds) { characteristics = seeds; }
279 void tolerance(
const double d) { tol = d; }
282 void maximumIterations(
const int n) { maxiters = n; }
285 std::vector<T> finalParameters(
void)
const {
287 throw(std::logic_error(
"Simplex has not been optimized"));
288 return(simplex[best]);
292 T finalValue(
void)
const {
return(values[best]); }
296 std::vector<T> optimize(std::vector<T>& f, C& ftor) {
299 if (characteristics.size() != f.size())
300 throw(std::logic_error(
"Invalid seed"));
306 for (i=0; i<ndim; i++) {
307 q[i] = characteristics[i] * ( (sqrtf(n) + ndim) / (n * sqrt(2.0)) );
308 qq[i] = characteristics[i] * ( (sqrtf(n) - 1.0) / (n * sqrt(2.0)) );
312 for (i=0; i<ndim; i++)
314 simplex[j][i] = f[i] + qq[i];
316 simplex[j][i] = f[i] + q[i];
318 for (j=0; j<n; ++j) {
319 values[j] = ftor(simplex[j]);
323 return(simplex[best]);
328 int ndim, maxiters, best, worst;
331 std::vector<T> characteristics;
332 std::vector<T> simpsum;
333 std::vector<T> values;
336 std::vector<T> trial;
Nelder-Meade Simplex Optimizer (based loosely on the NRC (1996) implementation)
Definition Simplex.hpp:58
base_generator_type & rng_singleton(void)
Suite-wide random number generator singleton.
Definition utils_random.cpp:27