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_