00001 // This is core/vnl/algo/vnl_amoeba.h 00002 #ifndef vnl_amoeba_h_ 00003 #define vnl_amoeba_h_ 00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00005 #pragma interface 00006 #endif 00007 //: 00008 // \file 00009 // \brief Nelder-Meade downhill simplex. 00010 // \author Andrew W. Fitzgibbon, Oxford RRG 00011 // \date 23 Oct 97 00012 // 00013 // \verbatim 00014 // Modifications 00015 // 971023 AWF Initial version 00016 // dac (Manchester) 26/03/2001: tidied up documentation 00017 // Tim Cootes 7-Jan-02: Added documentation and additional methods 00018 // Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line 00019 // \endverbatim 00020 00021 //----------------------------------------------------------------------------- 00022 00023 #include <vnl/vnl_vector.h> 00024 00025 class vnl_cost_function; 00026 class vnl_least_squares_function; 00027 00028 //: Nelder-Meade downhill simplex. 00029 // vnl_amoeba is an implementation of the Nelder-Meade downhill simplex 00030 // algorithm. For most problems, it's a few times slower than 00031 // vnl_levenberg_marquardt, but it can perform much better on noisy error 00032 // functions. 00033 // 00034 // It works by creating a simplex (n+1 points in n-D space) which then 00035 // crawls about the space searching for the solution. 00036 // 00037 // By default the set of (n+1) starting points are generated by applying 00038 // a scaling (relative_diameter) to each element of the supplied starting 00039 // vector, with a small offset used instead if the value is zero. 00040 // 00041 // Alternatively, if one uses minimize(x,dx), then the starting points 00042 // are obtained by adding each dx[i] to the elements of x, one at a time. 00043 // This is useful if you know roughly the scale of your space. 00044 00045 class vnl_amoeba 00046 { 00047 public: 00048 int verbose; 00049 int maxiter; 00050 double X_tolerance; 00051 double F_tolerance; 00052 00053 //: Define maximum number of iterations to use 00054 void set_max_iterations(int n) { maxiter = n; } 00055 00056 //: Define tolerance on elements of x 00057 void set_x_tolerance(double tol) { X_tolerance = tol; } 00058 00059 //: Define tolerance on function evaluation 00060 void set_f_tolerance(double tol) { F_tolerance = tol; } 00061 00062 //: Define scaling used to select starting vertices relative to initial x0. 00063 // I.e. the i'th vertex has x[i] = x0[i]*(1+relative_diameter) 00064 void set_relative_diameter(double r) { relative_diameter = r; } 00065 00066 //: Scaling used to select starting vertices relative to initial x0. 00067 // I.e. the i'th vertex has x[i] = x0[i]*(1+relative_diameter) 00068 double relative_diameter; 00069 00070 //: Construct and supply function to be minimized 00071 vnl_amoeba(vnl_cost_function& f); 00072 00073 //: Modify x to minimise function supplied in constructor 00074 // Start simplex defined by scaling elements of x 00075 void minimize(vnl_vector<double>& x); 00076 00077 //: Perform optimisation. 00078 // Start simplex defined by adding dx[i] to each x[i] 00079 void minimize(vnl_vector<double>& x, const vnl_vector<double>& dx); 00080 00081 //: Number of evaluations used in last call to minimize 00082 int get_num_evaluations() const { return num_evaluations_; } 00083 00084 public: 00085 //: Modify x so as to minimise f(x) 00086 static void minimize(vnl_cost_function& f, vnl_vector<double>& x); 00087 00088 //: Modify x so as to minimise f(x) 00089 // Start simplex defined by adding dx[i] to each x[i] 00090 static void minimize(vnl_cost_function& f, vnl_vector<double>& x, 00091 const vnl_vector<double>& dx); 00092 00093 //: Modify x so as to minimise f(x) 00094 // delta defines relative size of initial simplex 00095 // ie the i'th vertex has xi[i] = x[i]*(1+delta) 00096 static void minimize(vnl_cost_function& f, vnl_vector<double>& x, 00097 double delta); 00098 00099 //: Modify x so as to minimise f(x) 00100 static void minimize(vnl_least_squares_function& f, vnl_vector<double>& x); 00101 00102 static bool default_verbose; 00103 00104 protected: 00105 vnl_cost_function* fptr; 00106 int num_evaluations_; 00107 }; 00108 00109 // Private struct needs to be declared in the header file 00110 // in order to instantiate STL container of it elsewhere. 00111 struct vnl_amoeba_SimplexCorner 00112 { 00113 vnl_vector<double> v; 00114 double fv; 00115 00116 vnl_amoeba_SimplexCorner(int = 0); 00117 vnl_amoeba_SimplexCorner& operator= (const vnl_amoeba_SimplexCorner& that); 00118 static int compare(vnl_amoeba_SimplexCorner const& s1, 00119 vnl_amoeba_SimplexCorner const& s2); 00120 }; 00121 00122 #endif // vnl_amoeba_h_