core/vnl/algo/vnl_amoeba.h
Go to the documentation of this file.
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_