OverSim
simplex.cc
Go to the documentation of this file.
1 /* Numerical Methods, S06
2  * Note 8, Function optimization using the downhill Simplex method.
3  * Peter Seidler
4  * Source Code taken from: http://whome.phys.au.dk/~seidler/numeric/ */
5 
6 #include "simplex.h"
7 //#include "CoordNodeFunctions.h"
8 #include <NeighborCache.h>
9 
10 #include <cmath>
11 
12 using namespace std;
13 
14 
15 /***************************
16  * Simplex class defintions.
17  ***************************/
18 
19 Simplex::Simplex(int dimension)
20 {
21  dim = dimension;
22  nverts = dim+1;
23  verts = new Vec_DP*[nverts];
24  for (int i=0; i<nverts; i++)
25  verts[i] = new Vec_DP(dim);
26 }
27 
29 {
30  for (int i=0; i<nverts; i++)
31  delete verts[i];
32  delete[] verts;
33 }
34 
35 int Simplex::high(double* val) const
36 {
37  double test;
38  double max = functionObject->f(*verts[0]);
39  int idx = 0;
40  for (int i=1; i<nverts; i++) {
41  test = functionObject->f(*verts[i]);
42  if (test > max) {
43  max = test;
44  idx = i;
45  }
46  }
47  if (0 != val)
48  *val = max;
49  return idx;
50 }
51 
52 int Simplex::low(double* val) const
53 {
54  double test;
55  double min = functionObject->f(*verts[0]);;
56  int idx = 0;
57  for (int i=1; i<nverts; i++) {
58  test = functionObject->f(*verts[i]);
59  if (test < min) {
60  min = test;
61  idx = i;
62  }
63  }
64  if (0 != val)
65  *val = min;
66  return idx;
67 }
68 
69 void Simplex::centroid(Vec_DP& vec) const
70 {
71  Vec_DP ce(dim);
72  int hi = high();
73 
74  for (int i=0; i<nverts; i++)
75  if (i != hi)
76  ce += *verts[i];
77 
78  vec = ce / (nverts-1);
79 }
80 
81 // Size is defined to be sum of distances from centroid to
82 // all points in simplex.
83 double Simplex::size() const
84 {
85  Vec_DP ce(dim);
86  centroid(ce);
87  double dp, size = 0;
88 
89  for (int i=0; i<nverts; i++) {
90  dp = dot(*verts[i]-ce, *verts[i]-ce);
91  size += sqrt(dp);
92  }
93  return size;
94 }
95 
97 {
98  int hi = high();
99  Vec_DP ce(dim);
100 
101  centroid(ce);
102  *verts[hi] = ce + (ce - *verts[hi]);
103  return hi;
104 }
105 
107 {
108  int hi = high();
109  Vec_DP ce(dim);
110 
111  centroid(ce);
112  *verts[hi] = ce + 2*(ce - *verts[hi]);
113  return hi;
114 }
115 
117 {
118  int hi = high();
119  Vec_DP ce(dim);
120 
121  centroid(ce);
122  *verts[hi] = ce + 0.5*(*verts[hi] - ce);
123  return hi;
124 }
125 
127 {
128  int lo = low();
129 
130  for (int i = 0; i<nverts; i++) {
131  if (i != lo) {
132  *verts[i] = 0.5 * (*verts[i] + *verts[lo]);
133  }
134  }
135 }
136 
137