Rivet API documentation

Rivet 4.1.3
MendelMin.hh
1#ifndef RIVET_MendelMin_H
2#define RIVET_MendelMin_H
3
4#include "Rivet/Tools/Random.hh"
5#include <cmath>
6#include <functional>
7#include <iomanip>
8#include <iostream>
9#include <map>
10#include <random>
11#include <valarray>
12#include <vector>
13
14namespace Rivet {
15
16 using std::valarray;
17
18
24 class MendelMin {
25 public:
26
28 using Params = std::valarray<double>;
30 using FuncT = std::function<double(const Params&, const Params&)>;
32 using FuncNoFixedT = std::function<double(const Params&)>;
33 // /// Typedef for the [0,1] random number generator
34 // using RndT = std::function<double()>;
35
36
46 MendelMin(const FuncT& fin,
47 unsigned int ndim,
48 const Params& fixpar, //const RndT & rndin,
49 unsigned int npop = 20, //unsigned int ngen=20, //< unused
50 double margin = 0.1)
51 : _f(fin),
52 _q(fixpar), //_rnd(rndin),
53 _NDim(ndim),
54 _margin(margin),
55 _pop(npop),
56 _fit(npop, -1.0),
57 showTrace(false) { }
58
59
69 unsigned int ndim,
70 //const RndT & rndin,
71 unsigned int npop = 20,
72 unsigned int ngen = 20,
73 double margin = 0.1)
74 : MendelMin([&](const Params& ps, const Params&) -> double { return fin(ps); },
75 ndim,
76 {},
77 npop,
78 /* ngen, */ margin) { }
79
80
83 void guess(const Params& p) {
84 _pop.push_back(p);
85 limit01(_pop.back());
86 _fit.push_back(f(_pop.back()));
87 }
88
89
92 double evolve(unsigned int nGen) {
93 for (unsigned n = 0; n < nGen; ++n) {
94 // Calculate the fitness.
95 auto mm = minmax();
96 // Always kill the fittest individual.
97 if (showTrace) _debug();
98 for (unsigned int i = 1; i < _pop.size(); ++i) {
99 if (_fit[i] > rnd() * (mm.second - mm.first))
100 // Kill all individuals that have low fitness or are just unlucky.
101 _fit[i] = -1.0;
102 else
103 // Improve This individual to be more like the fittest.
104 move(_pop[i], _pop[0]);
105 }
106 }
107 return _fit[0];
108 }
109
111 Params fittest() const {
112 return _pop[0];
113 }
114
116 double fit() const {
117 return _fit[0];
118 }
119
121 double rnd() const {
122 return rand01(); //_rnd();
123 }
124
127 Params ret(_NDim);
128 for (unsigned int i = 0; i < _NDim; ++i) ret[i] = rnd();
129 return ret;
130 }
131
133 void limit01(Params& p) const {
134 for (unsigned int i = 0; i < _NDim; ++i) p[i] = std::max(0.0, std::min(p[i], 1.0));
135 }
136
141 void move(Params& bad, const Params& better) const {
142 bad += (better - bad) * (rndParams() * (1.0 + 2.0 * _margin) - _margin);
143 limit01(bad);
144 }
145
147 double f(const Params& p) const {
148 return _f(p, _q);
149 }
150
151
154 std::pair<double, double> minmax() {
155 std::pair<double, double> mm(std::numeric_limits<double>::max(), 0.0);
156 unsigned int iwin = 0;
157 for (unsigned int i = 0; i < _pop.size(); ++i) {
158 double& v = _fit[i];
159 // negative fitness value means the individual is dead, so we
160 // welocme a new immigrant.
161 if (v < 0.0) _pop[i] = rndParams();
162
163 // The calculated fitness value cannot be negative.
164 v = std::max(0.0, f(_pop[i]));
165
166 // Compare to the best and worst fitness so far.
167 if (v < mm.first) iwin = i;
168 mm.first = std::min(v, mm.first);
169 mm.second = std::max(mm.second, v);
170 }
171
172 // Move the winner to the top.
173 if (iwin != 0) {
174 std::swap(_pop[0], _pop[iwin]);
175 std::swap(_fit[0], _fit[iwin]);
176 }
177 return mm;
178 }
179
181 void _debug() {
182 std::cout << "GenAlgMax population status:" << std::endl;
183 for (unsigned int i = 0; i < _pop.size(); ++i) {
184 std::cout << std::setw(10) << _fit[i] << " (" << _pop[i][0];
185 for (unsigned int ip = 1; ip < _NDim; ++ip) std::cout << "," << _pop[i][ip];
186 std::cout << ")" << std::endl;
187 }
188 }
189
190
191 private:
192
194 const FuncT _f;
195
197 Params _q;
198
200 // const double _q;
201
203 //const RndT _rnd;
204
206 unsigned int _NDim;
207
212 double _margin;
213
215 std::vector<Params> _pop;
216
217
219 std::vector<double> _fit;
220
221 public:
222
225 };
226
227
235 // template <typename FuncT, typename RndT>
236 // MendelMin <FuncT, RndT>
237 // makeMendelMin(const FuncT & f, const RndT & rnd, unsigned int ndim,
238 // unsigned int npop = 20, double margin = 0.1) {
239 // return MendelMin<FuncT, RndT>(f, rnd, ndim, npop, margin);
240 // }
241
242}
243
244#endif // RIVET_MendelMin_H
void guess(const Params &p)
Definition MendelMin.hh:83
Params fittest() const
Return the fittest parameter point found.
Definition MendelMin.hh:111
void limit01(Params &p) const
Limit a parameter point to inside the unit hypercube.
Definition MendelMin.hh:133
void move(Params &bad, const Params &better) const
Definition MendelMin.hh:141
double fit() const
Return the fittest value found.
Definition MendelMin.hh:116
bool showTrace
Set true to get a verbose record of the evolution.
Definition MendelMin.hh:224
std::function< double(const Params &, const Params &)> FuncT
Typedef for the function to be minimised.
Definition MendelMin.hh:30
std::pair< double, double > minmax()
Definition MendelMin.hh:154
Params rndParams() const
Return a random parameter point in the unit hypercube.
Definition MendelMin.hh:126
std::valarray< double > Params
Typedef for a valaray of parameters to the function to be minimised.
Definition MendelMin.hh:28
std::function< double(const Params &)> FuncNoFixedT
Typedef for the function to be minimised.
Definition MendelMin.hh:32
MendelMin(const FuncNoFixedT &fin, unsigned int ndim, unsigned int npop=20, unsigned int ngen=20, double margin=0.1)
Definition MendelMin.hh:68
double f(const Params &p) const
Simple wrapper around the function to be minimised.
Definition MendelMin.hh:147
MendelMin(const FuncT &fin, unsigned int ndim, const Params &fixpar, unsigned int npop=20, double margin=0.1)
Definition MendelMin.hh:46
double evolve(unsigned int nGen)
Definition MendelMin.hh:92
double rnd() const
Simple wrapper around the random number generator.
Definition MendelMin.hh:121
pair< double, double > minmax(const vector< double > &in, double errval=DBL_NAN)
Find the minimum and maximum values in the vector.
Definition Utils.hh:772
double p(const ParticleBase &p)
Unbound function access to p.
Definition ParticleBaseUtils.hh:819
Definition LHCbCommon.hh:9
double rand01()
Return a uniformly sampled random number between 0 and 1.