contrib/mul/vpdfl/vpdfl_mixture_builder.h
Go to the documentation of this file.
00001 // This is mul/vpdfl/vpdfl_mixture_builder.h
00002 // Copyright: (C) 2000 Victoria University of Manchester
00003 #ifndef vpdfl_mixture_builder_h_
00004 #define vpdfl_mixture_builder_h_
00005 //:
00006 // \file
00007 // \brief Implements builder for a mixture model PDF.
00008 // \author Tim Cootes
00009 // \date 21-July-98
00010 //
00011 // \verbatim
00012 //  Modifications
00013 //   IMS   Converted to VXL 14 May 2000, with redesign
00014 // \endverbatim
00015 
00016 //=======================================================================
00017 
00018 #include <vpdfl/vpdfl_builder_base.h>
00019 #include <vpdfl/vpdfl_mixture_builder.h>
00020 #include <vpdfl/vpdfl_mixture.h>
00021 #include <vcl_iosfwd.h>
00022 
00023 //=======================================================================
00024 
00025 class vpdfl_mixture;
00026 
00027 //: Uses the EM algorithm to build vpdfl_mixture objects.
00028 class vpdfl_mixture_builder : public vpdfl_builder_base
00029 {
00030   vcl_vector<vpdfl_builder_base*> builder_;
00031   double min_var_;
00032   int max_its_;
00033   vcl_vector<vnl_vector<double> > initial_means_;
00034 
00035   //: Whether weights changed during iterations
00036   bool weights_fixed_;
00037 
00038     //: Assumes means set up.  Estimates starting components.
00039     // \param mean_sep : Rough guess of mean separation between points
00040   void initialise_given_means(vpdfl_mixture& model,
00041                               const vnl_vector<double>* data,
00042                               const vcl_vector<vnl_vector<double> >& mean,
00043                               const vcl_vector<double>& wts) const;
00044 
00045     //: Means centred on data[i*f]
00046   void initialise_to_regular_samples(vpdfl_mixture& model,
00047                                      const vnl_vector<double>* data,
00048                                      const vcl_vector<double>& wts) const;
00049 
00050     //: Select positions along diagonal of bounding box
00051   void initialise_diagonal(vpdfl_mixture& model,
00052                            const vnl_vector<double>* data,
00053                            const vcl_vector<double>& wts) const;
00054 
00055     //: Select positions and widths for components to start
00056   void initialise(vpdfl_mixture& model,
00057                   const vnl_vector<double>* data,
00058                   const vcl_vector<double>& wts) const;
00059 
00060   //: The Expectation part of the EM algorithm
00061   void e_step(vpdfl_mixture& model,
00062               vcl_vector<vnl_vector<double> >& probs,
00063               const vnl_vector<double>* data,
00064               const vcl_vector<double>& wts) const;
00065 
00066   //: The Maximisation part of the EM algorithm
00067   double m_step(vpdfl_mixture& model,
00068                 const vcl_vector<vnl_vector<double> >& probs,
00069                 const vnl_vector<double>* data,
00070                 const vcl_vector<double>& wts) const;
00071 
00072   void init();
00073   void delete_stuff();
00074 
00075  public:
00076 
00077   //: Dflt ctor
00078   vpdfl_mixture_builder();
00079 
00080   //: Copy ctor
00081   vpdfl_mixture_builder(const vpdfl_mixture_builder&);
00082 
00083   //: Copy operator
00084   vpdfl_mixture_builder& operator=(const vpdfl_mixture_builder&);
00085 
00086   //: Destructor
00087   virtual ~vpdfl_mixture_builder();
00088 
00089   //: Initialise n builders of type builder
00090   //  Clone taken of builder
00091   void init(const vpdfl_builder_base& builder, int n);
00092 
00093   //: Whether weights on components left unchanged during iterations
00094   bool weights_fixed() const { return weights_fixed_; }
00095 
00096   //: Whether weights on components left unchanged during iterations
00097   void set_weights_fixed(bool b);
00098 
00099   //: Define maximum number of EM iterations allowed
00100   void set_max_iterations(int n);
00101 
00102   //: Define maximum number of EM iterations allowed
00103   int max_iterations() const { return max_its_; }
00104 
00105   //: Number of basis builders
00106   unsigned n_builders() const { return builder_.size(); }
00107 
00108   //: Return i-th builder
00109   vpdfl_builder_base& builder(unsigned i) { return *builder_[i]; }
00110 
00111   //: Create empty model
00112   virtual vpdfl_pdf_base* new_model() const;
00113 
00114   //: Define lower threshold on variance for built models
00115   virtual void set_min_var(double min_var);
00116 
00117   //: Get lower threshold on variance for built models
00118   virtual double min_var() const;
00119 
00120   //: Calculate and set the mixture's mean and variance
00121   // This should be used after the weights or components of
00122   // the model have been altered.
00123   static void calc_mean_and_variance(vpdfl_mixture& model);
00124 
00125   //: Build default model with given mean
00126   virtual void build(vpdfl_pdf_base& model,
00127                      const vnl_vector<double>& mean) const;
00128 
00129   //: Build model from data
00130   //  Use EM algorithm to best fit mixture model to given data
00131   //  If model does not have the correct number of components
00132   //  they will be initialised to means scattered through the
00133   //  data.  If they model has the correct number of components
00134   //  it is assumed that they have been set to sensible initial
00135   //  values.  The EM algorithm will be used to optimise their
00136   //  parameters.
00137   virtual void build(vpdfl_pdf_base& model,
00138                      mbl_data_wrapper<vnl_vector<double> >& data) const;
00139 
00140   //: Build model from weighted data
00141   //  Use EM algorithm to best fit mixture model to given data
00142   //  If model does not have the correct number of components
00143   //  they will be initialised to means scattered through the
00144   //  data.  If they model has the correct number of components
00145   //  it is assumed that they have been set to sensible initial
00146   //  values.  The EM algorithm will be used to optimise their
00147   //  parameters.
00148   virtual void weighted_build(vpdfl_pdf_base& model,
00149                               mbl_data_wrapper<vnl_vector<double> >& data,
00150                               const vcl_vector<double>& wts) const;
00151 
00152   //: Preset initial component means
00153   // When initialise is called these means will be used as the initial guess
00154   // Note that the vector must  is copied
00155   void preset_initial_means(const vcl_vector<vnl_vector<double> >& component_means);
00156 
00157 
00158   //: Version number for I/O
00159   short version_no() const;
00160 
00161   //: Name of the class
00162   virtual vcl_string is_a() const;
00163 
00164   //: Does the name of the class match the argument?
00165   virtual bool is_class(vcl_string const& s) const;
00166 
00167   //: Create a copy on the heap and return base class pointer
00168   virtual vpdfl_builder_base* clone() const;
00169 
00170   //: Print class to os
00171   virtual void print_summary(vcl_ostream& os) const;
00172 
00173   //: Save class to binary file stream
00174   virtual void b_write(vsl_b_ostream& bfs) const;
00175 
00176   //: Load class from binary file stream
00177   virtual void b_read(vsl_b_istream& bfs);
00178 
00179   //: Read initialisation settings from a stream.
00180   // Parameters:
00181   // \verbatim
00182   // {
00183   //   min_var: 1.0e-6
00184   //   // Number of pdf bases to use
00185   //   n_pdfs: 3
00186   //   // Type of basis pdf
00187   //   basis_pdf: axis_gaussian { min_var: 0.0001 }
00188   //   // Maximum number of iterations
00189   //   max_its: 10
00190   //   // When true, fix weights during EM
00191   //   weights_fixed: false
00192   // }
00193   // \endverbatim
00194   // \throw mbl_exception_parse_error if the parse fails.
00195   virtual void config_from_stream(vcl_istream & is);
00196 };
00197 
00198 #endif // vpdfl_mixture_builder_h_