simplex.cc

Go to the documentation of this file.
00001 /* Numerical Methods, S06
00002  * Note 8, Function optimization using the downhill Simplex method.
00003  * Peter Seidler
00004  * Source Code taken from: http://whome.phys.au.dk/~seidler/numeric/            */
00005 
00006 #include "simplex.h"
00007 //#include "CoordNodeFunctions.h"
00008 #include <NeighborCache.h>
00009 
00010 #include <cmath>
00011 
00012 using namespace std;
00013 
00014 
00015 /***************************
00016  * Simplex class defintions.
00017  ***************************/
00018 
00019 Simplex::Simplex(int dimension)
00020 {
00021     dim = dimension;
00022     nverts = dim+1;
00023     verts = new Vec_DP*[nverts];
00024     for (int i=0; i<nverts; i++)
00025         verts[i] = new Vec_DP(dim);
00026 }
00027 
00028 Simplex::~Simplex()
00029 {
00030     for (int i=0; i<nverts; i++)
00031         delete verts[i];
00032     delete[] verts;
00033 }
00034 
00035 int Simplex::high(double* val) const
00036 {
00037     double test;
00038     double max = functionObject->f(*verts[0]);
00039     int idx = 0;
00040     for (int i=1; i<nverts; i++) {
00041         test = functionObject->f(*verts[i]);
00042         if (test > max) {
00043             max = test;
00044             idx = i;
00045         }
00046     }
00047     if (0 != val)
00048         *val = max;
00049     return idx;
00050 }
00051 
00052 int Simplex::low(double* val) const
00053 {
00054     double test;
00055     double min = functionObject->f(*verts[0]);;
00056     int idx = 0;
00057     for (int i=1; i<nverts; i++) {
00058         test = functionObject->f(*verts[i]);
00059         if (test < min) {
00060             min = test;
00061             idx = i;
00062         }
00063     }
00064     if (0 != val)
00065         *val = min;
00066     return idx;
00067 }
00068 
00069 void Simplex::centroid(Vec_DP& vec) const
00070 {
00071     Vec_DP ce(dim);
00072     int hi = high();
00073 
00074     for (int i=0; i<nverts; i++)
00075         if (i != hi)
00076             ce += *verts[i];
00077 
00078     vec = ce / (nverts-1);
00079 }
00080 
00081 // Size is defined to be sum of distances from centroid to
00082 // all points in simplex.
00083 double Simplex::size() const
00084 {
00085     Vec_DP ce(dim);
00086     centroid(ce);
00087     double dp, size = 0;
00088 
00089     for (int i=0; i<nverts; i++) {
00090         dp = dot(*verts[i]-ce, *verts[i]-ce);
00091         size += sqrt(dp);
00092     }
00093     return size;
00094 }
00095 
00096 int Simplex::reflect()
00097 {
00098     int hi = high();
00099     Vec_DP ce(dim);
00100 
00101     centroid(ce);
00102     *verts[hi] = ce + (ce - *verts[hi]);
00103     return hi;
00104 }
00105 
00106 int Simplex::reflect_exp()
00107 {
00108     int hi = high();
00109     Vec_DP ce(dim);
00110 
00111     centroid(ce);
00112     *verts[hi] = ce + 2*(ce - *verts[hi]);
00113     return hi;
00114 }
00115 
00116 int Simplex::contract()
00117 {
00118     int hi = high();
00119     Vec_DP ce(dim);
00120 
00121     centroid(ce);
00122     *verts[hi] = ce + 0.5*(*verts[hi] - ce);
00123     return hi;
00124 }
00125 
00126 void Simplex::reduce()
00127 {
00128     int lo = low();
00129 
00130     for (int i = 0; i<nverts; i++) {
00131         if (i != lo) {
00132             *verts[i] = 0.5 * (*verts[i] + *verts[lo]);
00133         }
00134     }
00135 }
00136 
00137 
Generated on Wed May 26 16:21:15 2010 for OverSim by  doxygen 1.6.3