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 // \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_