contrib/rpl/rrel/rrel_ran_sam_search.h
Go to the documentation of this file.
00001 #ifndef rrel_ran_sam_search_h_
00002 #define rrel_ran_sam_search_h_
00003 //:
00004 // \file
00005 // \brief Random sampling search for minimization of a robust objective function
00006 // \author Chuck Stewart (stewart@cs.rpi.edu)
00007 // \date March 2001
00008 
00009 #include <vnl/vnl_vector.h>
00010 #include <vnl/vnl_random.h>
00011 #include <vcl_vector.h>
00012 
00013 class rrel_objective;
00014 class rrel_estimation_problem;
00015 
00016 //: Random sampling search for minimization of a robust objective function.
00017 //  The code organization follows the design of the rrel
00018 //  library where there is a separation between objective function
00019 //  (M-estimator, LMS, etc), search technique, and estimation problem.
00020 //  See discussion in rrel_estimation_problem.
00021 //
00022 //  The algorithm implemented was discovered independently by Fischler
00023 //  and Bolles in the CACM RANSAC paper from 1981 and Rousseeuw in a
00024 //  Journal of the American Statistical Association paper from 1984.
00025 //  The implementation follows Rousseeuw's approach by not allowing
00026 //  the short-circuiting of RANSAC, which can cause incorrect results
00027 //  for a large number of outliers.
00028 //
00029 //  The number of samples taken is computed to accommodate the
00030 //  possibility of more than one population in the data, as described
00031 //  in Stewart, PAMI 1995.  It is a relatively straightforward
00032 //  generalization of the ordinary method for calculating the number
00033 //  of samples.
00034 //
00035 //  Using this class requires calling set_sampling_params (or
00036 //  set_gen_all_samples, which can be quite expensive), and then
00037 //  calling estimate().  Results may be obtained through the functions
00038 //  params() and scale().
00039 
00040 class rrel_ran_sam_search
00041 {
00042  public:
00043   //: Constructor using a non-deterministic random-sampling seed.
00044   rrel_ran_sam_search( );
00045 
00046   //: Constructor using a given random-sampling seed.
00047   rrel_ran_sam_search( int seed );
00048 
00049   virtual ~rrel_ran_sam_search();
00050 
00051   //  Parameters to control the search technique.  The default set
00052   //  when the constructor is called is to sample as in generate
00053   //  samples as specified in least-median of squares.
00054 
00055   //: Indicate that all possible minimal subset samples should be tried.
00056   void set_gen_all_samples();
00057 
00058   //: Set the parameters for random sampling.
00059   void set_sampling_params( double max_outlier_frac = 0.5,
00060                             double desired_prob_good = 0.99,
00061                             unsigned int max_populations_expected = 1,
00062                             unsigned int min_samples = 0 );
00063 
00064   // ----------------------------------------
00065   //  Main estimation functions
00066   // ----------------------------------------
00067 
00068   //: \brief Estimation for an "ordinary" estimation problem.
00069   virtual bool
00070   estimate( const rrel_estimation_problem* problem,
00071             const rrel_objective* obj_fcn );
00072 
00073   // -----------------------------------------
00074   // Access to results and computed parameters
00075   // -----------------------------------------
00076 
00077   //:  Get the scale estimate.
00078   double scale() const { return scale_; }
00079 
00080   //:  Get the parameter estimate.
00081   const vnl_vector<double>& params() const { return params_; }
00082 
00083   //:  Get the indices of best data sample
00084   const vcl_vector<int>& index() const { return indices_; }
00085 
00086   //:  Get the residuals for best sample
00087   const vcl_vector<double>& residuals() const { return residuals_; }
00088 
00089   //:  Get the cost for best sample returned by rrel_objective function
00090   double cost() const { return min_obj_; }
00091 
00092   //:  Get the number of samples tested in during estimation.
00093   int samples_tested() const { return samples_to_take_; }
00094 
00095   //:  Print the sampling parameters.  Used for debugging.
00096   void print_params() const;
00097 
00098   void set_trace_level( int level ) { trace_level_ = level; }
00099 
00100  protected:
00101   // ------------------------------------------------------------
00102   //  Random sampling functions.  Don't call directly.  These are
00103   //  public for test purposes.
00104   // ------------------------------------------------------------
00105 
00106   //: Calculate number of samples --- non-unique matching estimation problems
00107   virtual void
00108   calc_num_samples( const rrel_estimation_problem* problem );
00109 
00110   //: Determine the next random sample, filling in the "sample" vector.
00111   virtual void
00112   next_sample( unsigned int taken, unsigned int num_points, vcl_vector<int>& sample,
00113                unsigned int points_per_sample );
00114 
00115  private:
00116 
00117   void trace_sample( const vcl_vector<int>& point_indices ) const;
00118   void trace_residuals( const vcl_vector<double>& residuals ) const;
00119 
00120  protected:
00121   //
00122   //  Parameters
00123   //
00124   double max_outlier_frac_;
00125   double desired_prob_good_;
00126   unsigned int max_populations_expected_;
00127   unsigned int min_samples_;
00128   bool generate_all_;
00129 
00130   //: Random number generator.
00131   // Normally, this will point to the "global" generator, but a could
00132   // point to a local one if the user wants to specify a seed.
00133   vnl_random* generator_;
00134   bool own_generator_;
00135 
00136   //
00137   //  The estimate
00138   //
00139   vnl_vector<double> params_;
00140   double scale_;
00141   vcl_vector<int> indices_;
00142   vcl_vector<double> residuals_;
00143 
00144   double min_obj_;
00145   //
00146   //  Sampling variables
00147   //
00148   unsigned int samples_to_take_;
00149 
00150   int trace_level_;
00151 };
00152 
00153 #endif