core/vnl/algo/vnl_brent_minimizer.h
Go to the documentation of this file.
00001 // This is core/vnl/algo/vnl_brent_minimizer.h
00002 #ifndef vnl_brent_minimizer_h_
00003 #define vnl_brent_minimizer_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \author Tim Cootes
00010 // \date   Feb 2007
00011 //
00012 // \verbatim
00013 // Modifications
00014 // \endverbatim
00015 
00016 #include <vnl/vnl_cost_function.h>
00017 #include <vnl/vnl_nonlinear_minimizer.h>
00018 
00019 struct vnl_brent_data;
00020 
00021 //: Brent 1D minimizer
00022 // Minimizes a 1D function using a cunning combination of golden section
00023 // and parabolic interpolation.  It does not require derivatives to be
00024 // supplied. It is guaranteed to find a minimum, and generally works
00025 // efficiently - ie using few function evaluations.
00026 //
00027 // This implementation is based on that described by R.P. Brent
00028 // in Chapter 5 of "Algorithms for Minimization Without Derivatives", 1973.
00029 // In particular, is a C++ translation of the ALGOL program given at
00030 // the end of that chapter.
00031 //
00032 // Example usage:
00033 // \verbatim
00034 // // Create 1D cost function
00035 // class my_cost_fn : public vnl_cost_function {
00036 //   my_cost_fn() : vnl_cost_function(1) {}
00037 //
00038 //   double f(const vnl_vector<double>& x)
00039 //   { return (2 - x[0]) * (2 - x[0]) + 10; }
00040 // };
00041 //
00042 //   my_cost_fn f1;
00043 //   vnl_brent_minimizer brent(f1);
00044 //
00045 //   double initial_x = 3.5;
00046 //  // Find the position of the minimum
00047 //   double x = brent.minimize(initial_x);
00048 //   double min_f = brent.f_at_last_minimum();
00049 // \endverbatim
00050 class vnl_brent_minimizer : public vnl_nonlinear_minimizer
00051 {
00052  protected:
00053   vnl_cost_function* f_;
00054      //: Function evaluation at value returned by minimize(x)
00055   double f_at_last_minimum_;
00056  public:
00057   vnl_brent_minimizer(vnl_cost_function& functor);
00058  ~vnl_brent_minimizer();
00059 
00060   //: Find a minimum of f(x) near to ax.
00061   //  The evaluation of f(x) at the returned value can be obtained
00062   //  by a call to f_at_last_minimum();
00063   double minimize(double ax);
00064 
00065    //: Function evaluation at value returned by minimize(x)
00066   double f_at_last_minimum() const { return f_at_last_minimum_; }
00067 
00068   //: Find the minimum x of f(x) within a<= x <= c using pure golden section
00069   // \retval The position,x, of the minimum x.
00070   // You need to provide a bracket for the minimum (a<b<c s.t. f(a)>f(b)<f(c).
00071   // The tolerance can be set using prior call to set_x_tolerance(tol).
00072   // Use f_at_last_minimum() to get function evaluation at the returned minima.
00073   double minimize_golden(double ax, double bx, double cx,
00074                          double fa, double fb, double fc);
00075 
00076   //: Find the minimum value of f(x) within a<= x <= c.
00077   // \retval The position,x, of the minimum x.
00078   // You need to provide a bracket for the minimum (a<b<c s.t. f(a)>f(b)<f(c).
00079   // The tolerance can be set using prior call to set_x_tolerance(tol).
00080   // Use f_at_last_minimum() to get function evaluation at the returned minima.
00081   double minimize_given_bounds(double ax, double bx, double cx);
00082 
00083   //: Find the minimum value of f(x) within a<= x <= c.
00084   // \retval The position,x, of the minimum x.
00085   // You need to provide a bracket for the minimum (a<b<c s.t. f(a)>f(b)<f(c),
00086   // and the known value at b (fb=f(b)).
00087   // The tolerance can be set using prior call to set_x_tolerance(tol).
00088   // Use f_at_last_minimum() to get function evaluation at the returned minima.
00089   double minimize_given_bounds_and_one_f(double ax, double bx, double cx,
00090                                          double fb);
00091 
00092   //: Find the minimum value of f(x) within a<= x <= c.
00093   // \retval The position,x, of the minimum x.
00094   // You need to provide a bracket for the minimum (a<b<c s.t. f(a)>f(b)<f(c)),
00095   // and the values fa=f(a), fb=f(b), fc=f(c). This avoids recalculating
00096   // them if you have them already.  If you don't have them, it is
00097   // probably better to use minimize_given_bounds(a,b,c).
00098   //
00099   // The tolerance can be set using prior call to set_x_tolerance(tol).
00100   // Use f_at_last_minimum() to get function evaluation at the returned minima.
00101   double minimize_given_bounds_and_all_f(double ax, double bx, double cx,
00102                                          double fa, double fb, double fc);
00103 };
00104 
00105 #endif // vnl_brent_minimizer_h_