00001 #ifndef rrel_irls_h_ 00002 #define rrel_irls_h_ 00003 //: 00004 // \file 00005 // \author Chuck Stewart (stewart@cs.rpi.edu) 00006 // \date March 2001 00007 // \brief Iteratively-reweighted least-squares minimization of an M-estimator 00008 // 00009 // \verbatim 00010 // 2001-10-22 Amitha Perera. Reorganised and added comments. 00011 // \endverbatim 00012 00013 #include <vnl/vnl_vector.h> 00014 #include <vnl/vnl_matrix.h> 00015 #include <vcl_vector.h> 00016 00017 class rrel_estimation_problem; 00018 class rrel_wls_obj; 00019 00020 //: Iteratively-reweighted least-squares minimization of an M-estimator. 00021 // 00022 // IRLS is a search technique for solving M-estimation problems. The 00023 // technique is to compute weights from a given parameter estimate, 00024 // and use those weights to compute a new estimate via weighted least 00025 // squares. 00026 // 00027 // Several options allow variation in the behavior of estimation: 00028 // 00029 // (1) Scale may be fixed through a parameter setting function or it 00030 // may be estimated in the first few iterations of IRLS. A parameter 00031 // called iterations_for_scale_est_ determines the number of iterations 00032 // during which scale is to be estimated. Scale estimation is either 00033 // weight-based or median-based. 00034 // 00035 // (2) The maximum number of iterations may be set, either in the 00036 // constructor or through parameter setting member functions. 00037 // 00038 // (3) The convergence test, which is based on the objective function, 00039 // may or may not be run. Not running it makes each iteration faster, 00040 // but may result in more iterations than necessary. The convergence 00041 // test is not applied until the scale is no longer allowed to 00042 // change. (The alternative, which was not implemented, is to include 00043 // a ln(sigma) term to the objective function.) 00044 // 00045 // (4) The parameters, the scale, both or neither may be initialized. 00046 // 00047 // See also rrel_estimation_problem and rrel_wls_obj. 00048 00049 class rrel_irls 00050 { 00051 // default parameters 00052 static const double dflt_convergence_tol_; 00053 static const int dflt_max_iterations_; 00054 static const int dflt_iterations_for_scale_ ; 00055 00056 public: 00057 //: Constructor. 00058 rrel_irls( int max_iterations = dflt_max_iterations_ ); 00059 00060 //: Destructor. 00061 ~rrel_irls() {} 00062 00063 // ----------------------------------------------------------- 00064 // Functions related to setting / estimation / access to scale 00065 // ----------------------------------------------------------- 00066 00067 //: Set scale estimation and parameters. 00068 void set_est_scale( int iterations_for_scale=dflt_iterations_for_scale_, 00069 bool use_weighted_scale=false ); 00070 00071 //: Set lower bound of scale estimate 00072 void set_scale_lower_bound( double lower_scale ); 00073 00074 //: Set for no scale estimation. 00075 // Scale must be initialized or supplied by the problem. 00076 void set_no_scale_est( ); 00077 00078 //: Initialize the scale value. 00079 void initialize_scale( double scale ); 00080 00081 //: Indicate that scale has not been initialized. 00082 void reset_scale() { scale_initialized_ = false; } 00083 00084 //: Get the scale estimate (or the fixed scale value). 00085 double scale() const; 00086 00087 // ----------------------------------------------------------- 00088 // Functions related to the number of iterations and convergence 00089 // ----------------------------------------------------------- 00090 00091 //: Set the maximum number of iterations. 00092 void set_max_iterations( int max_iterations=dflt_max_iterations_ ); 00093 00094 //: Indicate that a convergence test is to be used. 00095 void set_convergence_test( double convergence_tol=dflt_convergence_tol_ ); 00096 00097 //: Indicate that no convergence test is to be used. 00098 void set_no_convergence_test( ); 00099 00100 00101 // ------------------------------------------------------------ 00102 // Parameter initialization and re-initialization 00103 // ------------------------------------------------------------ 00104 00105 //: Initialize the parameter estimate. 00106 void initialize_params( const vnl_vector<double>& init_params ); 00107 00108 //: Reset the parameters. 00109 void reset_params() { params_initialized_ = false; } 00110 00111 void set_trace_level( int level ) { trace_level_ = level; } 00112 00113 // ------------------------------------------------------------ 00114 // Main estimation functions 00115 // ------------------------------------------------------------ 00116 00117 //: Estimate the parameters. 00118 // The initial step is to initialize the parameter estimate, if 00119 // necessary, and then the scale estimate, if necessary. Then the 00120 // following basic loop is applied: 00121 // 00122 // 1. Calculate residuals 00123 // 2. Test for convergence, if desired. 00124 // 3. Calculate weights 00125 // 4. Calculate scale 00126 // 5. Calculate new estimate 00127 // 00128 // The loop can end in one of three ways: (a) convergence, (b) the 00129 // maximum number of iterations is reached, (c) the weighted 00130 // least-squares estimate fails. 00131 bool estimate( const rrel_estimation_problem* problem, 00132 const rrel_wls_obj* m_estimator ); 00133 00134 // ------------------------------------------------------------ 00135 // Get information about results... 00136 // ------------------------------------------------------------ 00137 00138 //: Get the parameter estimate. 00139 const vnl_vector<double>& params() const; 00140 00141 //: Get the cofactor matrix (the covariance matrix / scale^2). 00142 const vnl_matrix<double>& cofactor() const; 00143 00144 //: Determine if the estimation converged. 00145 bool converged() const { return test_converge_ && converged_; } 00146 00147 //: The number of iterations that were used. 00148 int iterations_used() const; 00149 00150 //: \brief Print the residuals. Used for debugging. 00151 void trace_residuals( const vcl_vector<double>& residuals ) const; 00152 00153 //: \brief Print the IRLS weights. Used for debugging. 00154 void trace_weights( const vcl_vector<double>& weights ) const; 00155 00156 //: \brief Print the set of parameters. 00157 void print_params() const; 00158 00159 private: 00160 bool has_converged( const vcl_vector<double>& residuals, 00161 const rrel_wls_obj* m_estimator, 00162 const rrel_estimation_problem* problem, 00163 vnl_vector<double>* params ); 00164 00165 protected: 00166 // Parameters 00167 int max_iterations_; 00168 bool test_converge_; 00169 double convergence_tol_; 00170 bool est_scale_during_; 00171 bool use_weighted_scale_; 00172 int iterations_for_scale_est_; 00173 double scale_lower_bound_; 00174 int trace_level_; 00175 00176 // Variables of estimation. 00177 vnl_vector<double> params_; 00178 vnl_matrix<double> cofact_; 00179 bool params_initialized_; 00180 double scale_; 00181 bool scale_initialized_; 00182 double obj_fcn_, prev_obj_fcn_; 00183 bool converged_; 00184 int iteration_; 00185 }; 00186 00187 #endif // rrel_irls_h_