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