00001 // This is core/vnl/algo/vnl_lbfgsb.h 00002 #ifndef vnl_lbfgsb_h_ 00003 #define vnl_lbfgsb_h_ 00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00005 #pragma interface 00006 #endif 00007 //: 00008 // \file 00009 // \brief Limited memory Broyden Fletcher Goldfarb Shannon constrained opt 00010 // \author Brad King, Kitware Inc. 00011 // \date 28 Aug 07 00012 // 00013 // \verbatim 00014 // Modifications 00015 // 070828 BJK Initial version. 00016 // \endverbatim 00017 // 00018 00019 #include <vnl/vnl_cost_function.h> 00020 #include <vnl/vnl_nonlinear_minimizer.h> 00021 #include <vnl/vnl_vector.h> 00022 00023 //: Limited memory Broyden Fletcher Goldfarb Shannon minimization with constraints. 00024 // Lower and upper bounds may be specified for the variables to be optimized. 00025 // The algorithm minimizes a nonlinear function f(x) of n variables 00026 // subject to simple bound constraints of l <= x <= u. 00027 00028 class vnl_lbfgsb : public vnl_nonlinear_minimizer 00029 { 00030 public: 00031 vnl_lbfgsb(); 00032 vnl_lbfgsb(vnl_cost_function& f); 00033 00034 //: Find a minimum in the feasible region given an initial guess. 00035 // Returns true if a minimum is found and false for failure. 00036 bool minimize(vnl_vector<double>& x); 00037 00038 //: Set the bounds to be enforced on each variable. 00039 // The argument should have one entry per unknown. 00040 // Each entry may have one of these values: 00041 // 0 - variable is not constrained 00042 // 1 - variable has only a lower bound 00043 // 2 - variable has both lower and upper bounds 00044 // 3 - variable has only an upper bound 00045 void set_bound_selection(vnl_vector<long> const& nbd) 00046 { this->bound_selection_ = nbd; } 00047 00048 //: Get the bounds currently enforced on each variable. 00049 void get_bound_selection(vnl_vector<long>& nbd) const 00050 { nbd = this->bound_selection_; } 00051 00052 //: Set the lower bounds for all variables. 00053 // The argument should have one entry per unknown. 00054 // The lower bound is used only if the corresponding entry 00055 // in the bound selection vector is set to 1 or 2. 00056 void set_lower_bound(vnl_vector<double> const& l) 00057 { this->lower_bound_ = l; } 00058 00059 //: Get the lower bounds for all variables. 00060 void get_lower_bound(vnl_vector<double>& l) const 00061 { l = this->lower_bound_; } 00062 00063 //: Set the upper bounds for all variables. 00064 // The argument should have one entry per unknown. 00065 // The upper bound is used only if the corresponding entry 00066 // in the bound selection vector is set to 2 or 3. 00067 void set_upper_bound(vnl_vector<double> const& u) 00068 { this->upper_bound_ = u; } 00069 00070 //: Get the upper bounds for all variables. 00071 void get_upper_bound(vnl_vector<double>& u) const 00072 { u = this->upper_bound_; } 00073 00074 //: Set the maximum number of variable metric corrections. 00075 // This is used to determine the size of the limited-memory matrix. 00076 // The default value is 5. 00077 void set_max_variable_metric_corrections(long m) 00078 { this->max_corrections_ = m; } 00079 00080 //: Get the maximum number of variable metric corrections. 00081 long get_max_variable_metric_corrections() const 00082 { return this->max_corrections_; } 00083 00084 //: Set the cost function convergence factor. 00085 // When an iteration changes the function value by an amount smaller than 00086 // this factor times the machine epsilon (scaled by function magnitude) 00087 // convergence is assumed. The default value is 1e+7. 00088 void set_cost_function_convergence_factor(double factor) 00089 { this->convergence_factor_ = factor; } 00090 00091 //: Get the cost function convergence factor. 00092 double get_cost_function_convergence_factor() const 00093 { return this->convergence_factor_; } 00094 00095 //: Set the projected gradient tolerance. 00096 // When the projected gradient vector has no component larger than 00097 // the given value convergence is assumed. The default value is 00098 // 1e-5. 00099 void set_projected_gradient_tolerance(double tol) 00100 { this->projected_gradient_tolerance_ = tol; } 00101 00102 //: Get the projected gradient tolerance. 00103 double get_projected_gradient_tolerance() const 00104 { return this->projected_gradient_tolerance_; } 00105 00106 //: Get the current infinity norm of the projected gradient. 00107 double get_inf_norm_projected_gradient() const 00108 { return this->inf_norm_projected_gradient_; } 00109 00110 protected: 00111 00112 vnl_vector<double> lower_bound_; 00113 vnl_vector<double> upper_bound_; 00114 vnl_vector<long> bound_selection_; 00115 long max_corrections_; 00116 double convergence_factor_; 00117 double projected_gradient_tolerance_; 00118 double inf_norm_projected_gradient_; 00119 00120 private: 00121 void init_parameters(); 00122 vnl_cost_function* f_; 00123 }; 00124 00125 #endif // vnl_lbfgsb_h_