CC Localization
nelder_mead.cc
Go to the documentation of this file.
1 
4 #include "nelder_mead.hh"
5 #include <vector>
6 
7 double const alpha = 1;
8 double const beta = 0.5;
9 double const gamma = 2;
10 double const delta = 0.5;
11 
12 double nelder_mead(func_t f, int n, double * x, double const * steps, double mxrngy, double mxrngx, int mxiter)
13 {
15  auto s = new double [n*(n+1)];
16  for (int i = 0; i<n; i++) s[i] = x[i];
17  for (int i = 0; i<n; i++) {
18  auto d = s+(i+1)*n;
19  for (int j = 0; j<n; j++) d[j] = x[j];
20  d[i] += steps[i];
21  }
22 
23  auto y = new double [n+1];
24  for (int i = 0; i<=n; i ++) y[i] = (*f)(s+i*n);
25 
26  // workspace
27  auto xc = new double [n]; // reflection center
28  auto xn = new double [n]; // next point
29  auto x2 = new double [n]; // next point
30  int li; //lowest
31  int ni; //next-to-highest
32  int hi; //highest
33 
34  // iterate
35  int iter = 0;
36  do {
37  // find lowest, highest, and next-to-highest
38  li = 0;
39  ni = 0;
40  hi = 1;
41  if (y[1]<y[0]) {
42  li = 1;
43  ni = 1;
44  hi = 0;
45  }
46  for (int i = 2; i<=n; i++) {
47  if (y[i]<y[li]) li = i;
48  else if (y[i]>y[hi]) {
49  ni = hi;
50  hi = i;
51  }
52  else if (y[i]>y[ni]) ni = i;
53  }
54  if (ni==li) ni = 2;
55  // check for convergence
56  if (y[hi]-y[li]<mxrngy) { // y-range satisfied, check x
57  double mx = 0;
58  for (int i = 0; i<n; i++) {
59  auto d = s+i;
60  double mnx = * d;
61  double mxx = mnx;
62  for (int j = 0; j<=n; j++) {
63  double xx = s[j*n+i];
64  if (xx<mnx) mnx = xx;
65  if (xx>mxx) mxx = xx;
66  }
67  double r = mxx-mnx;
68  if (r>mx) mx = r;
69  }
70  if (mx<mxrngx) break; // x-range small enough, done!
71  }
72  auto sh = s+hi*n; // highest position
73  // find reflection center and reflected position
74  for (int i = 0; i<n; i++) {
75  xc[i] = 0;
76  for (int j = 0; j<=n; j++) xc[i] += s[j*n+i];
77  xc[i] = (xc[i]-sh[i])/n;
78  xn[i] = xc[i]+(xc[i]-sh[i])*alpha;
79  }
80  double yn = (*f)(xn);
81  if (yn<y[ni]) { // reflection ok?
82  if (yn<y[li]) { // reflection best?
83  // expand
84  for (int i = 0; i<n; i++) x2[i] = xc[i]+(xc[i]-sh[i])*gamma;
85  double y2 = (*f)(x2);
86  if (y2<yn) { // expansion good?
87  y[hi] = y2;
88  for (int i = 0; i<n; i++) sh[i] = x2[i];
89  }
90  else { // scrap expansion
91  y[hi] = yn;
92  for (int i = 0; i<n; i++) sh[i] = xn[i];
93  }
94  }
95  else { // just use reflection
96  y[hi] = yn;
97  for (int i = 0; i<n; i++) sh[i] = xn[i];
98  }
99  }
100  else { // reflection bad
101  if (yn<y[hi]) { // not worst
102  // contract the reflection
103  for (int i = 0; i<n; i++) x2[i] = xc[i]+(xn[i]-xc[i])*beta;
104  double y2 = (*f)(x2);
105  if (y2<yn) { // contraction better?
106  y[hi] = y2;
107  for (int i = 0; i<n; i++) sh[i] = x2[i];
108  }
109  else { // use relection (this differs from Scholarpedia, which shrinks)
110  y[hi] = yn;
111  for (int i = 0; i<n; i++) sh[i] = xn[i];
112  }
113  }
114  else { // worst
115  // contract the original position
116  for (int i = 0; i<n; i++) xn[i] = xc[i]+(sh[i]-xc[i])*beta;
117  yn = (*f)(xn);
118  if (yn<y[hi]) { // improves a bit
119  y[hi] = yn;
120  for (int i = 0; i<n; i++) sh[i] = xn[i];
121  }
122  else { // not working, shink the simplex
123  auto sl = s+li*n;
124  for (int i = 0; i<=n; i++) {
125  if (i==li) continue;
126  auto d = s+i*n;
127  for (int j = 0; j<n; j++) d[j] = sl[j]+(d[j]-sl[j])*delta;
128  y[i] = (*f)(d);
129  }
130  }
131  }
132  }
133  iter ++;
134  } while (iter<mxiter);
135  for (int i = 0; i<n; i++) x[i] = s[li*n+i];
136  delete [] xc;
137  delete [] xn;
138  delete [] x2;
139  return y[li];
140 }
double const alpha
reflection coefficient
Definition: nelder_mead.cc:7
double nelder_mead(func_t f, int n, double *x, double const *steps, double mxrngy, double mxrngx, int mxiter)
Perform minimization with Nelder–Mead method.
Definition: nelder_mead.cc:12
double() func_t(double const *)
Function type with a number of parameters.
Definition: nelder_mead.hh:11
double const gamma
contraction coefficient
Definition: nelder_mead.cc:9
double const beta
expansion coefficient
Definition: nelder_mead.cc:8
double const delta
shrinking coefficient
Definition: nelder_mead.cc:10
Nelder–Mead method for function minimization.