Rivet: /Users/chrisg/software/rivet/include/Rivet/Tools/MendelMin.hh Source File

| Rivet 3.1.9

MendelMin.hh
1#ifndef RIVET_MendelMin_H
2#define RIVET_MendelMin_H
3
4#include "Rivet/Tools/Random.hh"
5#include <valarray>
6#include <random>
7#include <functional>
8#include <map>
9#include <vector>
10#include <cmath>
11#include <iostream>
12#include <iomanip>
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, unsigned int ndim,
47 const Params& fixpar, //const RndT & rndin,
48 unsigned int npop=20, unsigned int ngen=20,
49 double margin=0.1)
50 : _f(fin), _q(fixpar), //_rnd(rndin),
51 _NDim(ndim), _margin(margin),
52 _pop(npop), _fit(npop, -1.0), showTrace(false) {}
53
54
63 MendelMin(const FuncNoFixedT& fin, unsigned int ndim,
64 //const RndT & rndin,
65 unsigned int npop=20, unsigned int ngen=20,
66 double margin=0.1)
67 : MendelMin([&](const Params& ps, const Params&) -> double { return fin(ps); },
68 ndim, {}, npop, ngen, margin)
69 { }
70
71
74 void guess(const Params & p) {
75 _pop.push_back(p);
76 limit01(_pop.back());
77 _fit.push_back(f(_pop.back()));
78 }
79
80
83 double evolve(unsigned int NGen) {
84 for ( unsigned n = 0; n < NGen; ++n ) {
85 // Calculate the fitness.
86 auto mm = minmax();
87 // Always kill the fittest individual.
88 if ( showTrace ) _debug();
89 for ( unsigned int i = 1; i < _pop.size(); ++i ) {
90 if ( _fit[i] > rnd()*(mm.second - mm.first) )
91 // Kill all individuals that have low fitness or are just unlucky.
92 _fit[i] = -1.0;
93 else
94 // Improve This individual to be more like the fittest.
95 move(_pop[i],_pop[0]);
96 }
97 }
98 return _fit[0];
99 }
100
102 Params fittest() const {
103 return _pop[0];
104 }
105
107 double fit() const {
108 return _fit[0];
109 }
110
112 double rnd() const {
113 return rand01(); //_rnd();
114 }
115
117 Params rndParams() const {
118 Params ret(_NDim);
119 for ( unsigned int i = 0; i < _NDim; ++i ) ret[i] = rnd();
120 return ret;
121 }
122
124 void limit01(Params & p) const {
125 for ( unsigned int i = 0; i < _NDim; ++i )
126 p[i] = std::max(0.0, std::min(p[i], 1.0));
127 }
128
133 void move(Params & bad, const Params & better) const {
134 bad += (better - bad)*(rndParams()*(1.0 + 2.0*_margin) - _margin);
135 limit01(bad);
136 }
137
139 double f(const Params & p) const {
140 return _f(p, _q);
141 }
142
143
146 std::pair<double, double> minmax() {
147 std::pair<double,double> mm(std::numeric_limits<double>::max(), 0.0);
148 unsigned int iwin = 0;
149 for ( unsigned int i = 0; i < _pop.size(); ++i ) {
150 double & v = _fit[i];
151 // negative fitness value means the individual is dead, so we
152 // welocme a new immigrant.
153 if ( v < 0.0 ) _pop[i] = rndParams();
154
155 // The calculated fitness value cannot be negative.
156 v = std::max(0.0, f(_pop[i]));
157
158 // Compare to the best and worst fitness so far.
159 if ( v < mm.first ) iwin = i;
160 mm.first = std::min(v, mm.first);
161 mm.second = std::max(mm.second, v);
162 }
163
164 // Move the winner to the top.
165 if ( iwin != 0 ) {
166 std::swap(_pop[0], _pop[iwin]);
167 std::swap(_fit[0], _fit[iwin]);
168 }
169 return mm;
170 }
171
173 void _debug() {
174 std::cout << "GenAlgMax population status:" << std::endl;
175 for ( unsigned int i = 0; i < _pop.size(); ++i ) {
176 std::cout << std::setw(10) << _fit[i] << " (" << _pop[i][0];
177 for ( unsigned int ip = 1; ip < _NDim; ++ip )
178 std::cout << "," << _pop[i][ip];
179 std::cout << ")" << std::endl;
180 }
181 }
182
183
184 private:
185
187 const FuncT _f;
188
190 Params _q;
191
193 // const double _q;
194
196 //const RndT _rnd;
197
199 unsigned int _NDim;
200
205 double _margin;
206
208 std::vector<Params> _pop;
209
210
212 std::vector<double> _fit;
213
214 public:
215
217 bool showTrace;
218
219 };
220
221
229 // template <typename FuncT, typename RndT>
230 // MendelMin <FuncT, RndT>
231 // makeMendelMin(const FuncT & f, const RndT & rnd, unsigned int ndim,
232 // unsigned int npop = 20, double margin = 0.1) {
233 // return MendelMin<FuncT, RndT>(f, rnd, ndim, npop, margin);
234 // }
235
236}
237
238#endif // RIVET_MendelMin_H
Rivet::MendelMin
A genetic algorithm functional minimizer.
Definition MendelMin.hh:24
Rivet::MendelMin::guess
void guess(const Params &p)
Definition MendelMin.hh:74
Rivet::MendelMin::fittest
Params fittest() const
Return the fittest parameter point found.
Definition MendelMin.hh:102
Rivet::MendelMin::limit01
void limit01(Params &p) const
Limit a parameter point to inside the unit hypercube.
Definition MendelMin.hh:124
Rivet::MendelMin::move
void move(Params &bad, const Params &better) const
Definition MendelMin.hh:133
Rivet::MendelMin::fit
double fit() const
Return the fittest value found.
Definition MendelMin.hh:107
Rivet::MendelMin::showTrace
bool showTrace
Set true to get a verbose record of the evolution.
Definition MendelMin.hh:217
Rivet::MendelMin::FuncT
std::function< double(const Params &, const Params &)> FuncT
Typedef for the function to be minimised.
Definition MendelMin.hh:30
Rivet::MendelMin::minmax
std::pair< double, double > minmax()
Definition MendelMin.hh:146
Rivet::MendelMin::rndParams
Params rndParams() const
Return a random parameter point in the unit hypercube.
Definition MendelMin.hh:117
Rivet::MendelMin::Params
std::valarray< double > Params
Typedef for a valaray of parameters to the function to be minimised.
Definition MendelMin.hh:28
Rivet::MendelMin::FuncNoFixedT
std::function< double(const Params &)> FuncNoFixedT
Typedef for the function to be minimised.
Definition MendelMin.hh:32
Rivet::MendelMin::MendelMin
MendelMin(const FuncNoFixedT &fin, unsigned int ndim, unsigned int npop=20, unsigned int ngen=20, double margin=0.1)
Definition MendelMin.hh:63
Rivet::MendelMin::f
double f(const Params &p) const
Simple wrapper around the function to be minimised.
Definition MendelMin.hh:139
Rivet::MendelMin::MendelMin
MendelMin(const FuncT &fin, unsigned int ndim, const Params &fixpar, unsigned int npop=20, unsigned int ngen=20, double margin=0.1)
Definition MendelMin.hh:46
Rivet::MendelMin::rnd
double rnd() const
Simple wrapper around the random number generator.
Definition MendelMin.hh:112
Rivet::MendelMin::evolve
double evolve(unsigned int NGen)
Definition MendelMin.hh:83
Rivet::minmax
pair< double, double > minmax(const vector< double > &in, double errval=DBL_NAN)
Find the minimum and maximum values in the vector.
Definition Utils.hh:778
Rivet::Kin::p
double p(const ParticleBase &p)
Unbound function access to p.
Definition ParticleBaseUtils.hh:684
Rivet
Definition MC_Cent_pPb.hh:10
Rivet::rand01
double rand01()
Return a uniformly sampled random number between 0 and 1.