00001 #ifndef vnl_nonlinear_minimizer_h_ 00002 #define vnl_nonlinear_minimizer_h_ 00003 // This is vxl/vnl/vnl_nonlinear_minimizer.h 00004 00005 //: 00006 // \file 00007 // \brief Base class for nonlinear optimization 00008 // \author Andrew W. Fitzgibbon, Oxford RRG, 22 Aug 99 00009 00010 // Modifications 00011 // 22/03/2001 dac - added binary io and tidied documentation 00012 00013 #include <vnl/vnl_matrix.h> 00014 00015 00016 //: vnl_nonlinear_minimizer is a base class for nonlinear optimization. 00017 // It defines a few common abilities such as get_num_evaluations. 00018 // Known derived classes are: 00019 // vnl_levenberg_marquardt 00020 // vnl_lbfgs 00021 // vnl_conjugate_gradient 00022 // vnl_brent 00023 // vnl_powell 00024 class vnl_nonlinear_minimizer { 00025 public: 00026 vnl_nonlinear_minimizer(); 00027 00028 virtual ~vnl_nonlinear_minimizer(); 00029 00030 00031 //:Set the convergence tolerance on F (sum of squared residuals). When the 00032 // differences in successive RMS errors is less than this, the routine 00033 // terminates. So this is effectively the desired precision of your 00034 // minimization. Setting it too low wastes time, too high might cause early 00035 // convergence. The default of 1e-9 is on the safe side, but if speed is an 00036 // issue, you can try raising it. 00037 void set_f_tolerance(double v) { ftol = v; } 00038 double get_f_tolerance() const { return ftol; } 00039 00040 //:Set the convergence tolerance on X. When the length of the steps taken in X 00041 // are about this long, the routine terminates. The default is 1e-8, which should 00042 // work for many problems, but if you can get away with 1e-4, say, minimizations will 00043 // be much quicker. 00044 void set_x_tolerance(double v) { 00045 xtol = v; 00046 epsfcn = xtol * 0.001; 00047 } 00048 double get_x_tolerance() const { return xtol; } 00049 00050 //:Set the convergence tolerance on Grad(F)' * F. 00051 void set_g_tolerance(double v) { gtol = v; } 00052 double get_g_tolerance() const { return gtol; } 00053 00054 //:Set the termination maximum number of iterations. 00055 void set_max_function_evals(int v) { maxfev = v; } 00056 int get_max_function_evals() const { return maxfev; } 00057 00058 //:Set the step length for FD Jacobian. Be aware that set_x_tolerance will reset this 00059 // to xtol * 0.001. The default is 1e-11. 00060 void set_epsilon_function(double v) { epsfcn = v; } 00061 double get_epsilon_function() const { return epsfcn; } 00062 00063 //:Turn on per-iteration printouts. 00064 void set_trace(bool on) { trace = on; } 00065 bool get_trace() const { return trace; } 00066 00067 //:Set verbose flag 00068 void set_verbose(bool verb) { verbose_ = verb; } 00069 bool get_verbose() const { return verbose_; } 00070 00071 //:Set check_derivatives flag. Negative values may mean fewer checks. 00072 void set_check_derivatives(int cd) { check_derivatives_ = cd; } 00073 int get_check_derivatives() const { return check_derivatives_; } 00074 00075 //:Return the error of the function when it was evaluated at the start 00076 // point of the last minimization. For minimizers driven by a vnl_least_squares_function 00077 // (Levenberg-Marquardt) this is usually the RMS error. 00078 // For those driven by a vnl_cost_function (CG, LBFGS, Amoeba) it is simply the 00079 // value of the vnl_cost_function at the start (usually the sum of squared residuals). 00080 double get_start_error() const { return start_error_; } 00081 00082 //:Return the best error that was achieved by the last minimization, 00083 // corresponding to the returned x. 00084 double get_end_error() const { return end_error_; } 00085 00086 //:Return the total number of times the function was evaluated by 00087 // the last minimization. 00088 int get_num_evaluations() const { return num_evaluations_; } 00089 00090 //:Return the number of {\em iterations} in the last minimization. 00091 // Each iteration may have comprised several function evaluations. 00092 int get_num_iterations() const { return num_iterations_; } 00093 00094 //:Return the covariance of the estimate at the end. 00095 virtual vnl_matrix<double> const& get_covariance(); 00096 00097 //: Return the name of the class 00098 // Used by polymorphic IO 00099 virtual const vcl_string is_a() const; 00100 00101 //: Return true if the name of the class matches the argument 00102 // Used by polymorphic IO 00103 virtual bool is_a(vcl_string const& s) const { return s=="vnl_nonlinear_minimizer"; } 00104 00105 //:Some generic return codes that apply to all minimizers. 00106 enum ReturnCodes { 00107 ERROR_FAILURE =-1, 00108 ERROR_DODGY_INPUT = 0, 00109 CONVERGED_FTOL = 1, 00110 CONVERGED_XTOL = 2, 00111 CONVERGED_XFTOL = 3, 00112 CONVERGED_GTOL = 4, 00113 FAILED_TOO_MANY_ITERATIONS = 5, 00114 FAILED_FTOL_TOO_SMALL = 6, 00115 FAILED_XTOL_TOO_SMALL = 7, 00116 FAILED_GTOL_TOO_SMALL = 8 00117 }; 00118 00119 //:Return the failure code of the last minimization 00120 ReturnCodes get_failure_code() const { return failure_code_; } 00121 00122 protected: 00123 // Data Members-------------------------------------------------------------- 00124 // Input variables 00125 double xtol; // Termination tolerance on X (solution vector) 00126 int maxfev; // Termination maximum number of iterations. 00127 double ftol; // Termination tolerance on F (sum of squared residuals) 00128 double gtol; // Termination tolerance on Grad(F)' * F = 0 00129 double epsfcn; // Step length for FD Jacobian 00130 00131 // Output variables 00132 unsigned num_iterations_; 00133 int num_evaluations_; 00134 double start_error_; 00135 double end_error_; 00136 00137 bool trace; 00138 00139 // Verbose flag. 00140 bool verbose_; 00141 int check_derivatives_; 00142 ReturnCodes failure_code_; 00143 00144 void reset(); 00145 void report_eval(double f); 00146 void report_iter(); 00147 }; 00148 00149 00150 00151 #endif // vnl_nonlinear_minimizer_h_