00001 // This is mul/vpdfl/vpdfl_mixture.h 00002 // Copyright: (C) 2000 Victoria University of Manchester 00003 #ifndef vpdfl_mixture_h_ 00004 #define vpdfl_mixture_h_ 00005 //: 00006 // \file 00007 // \brief Implements a mixture model (a set of individual pdfs + weights) 00008 // \author Tim Cootes 00009 // \date 21-July-98 00010 // 00011 // \verbatim 00012 // Modifications 00013 // IMS Converted to VXL 12 May 2000 00014 // \endverbatim 00015 00016 //======================================================================= 00017 00018 #include <vpdfl/vpdfl_pdf_base.h> 00019 #include <vcl_vector.h> 00020 #include <vcl_iosfwd.h> 00021 00022 //======================================================================= 00023 00024 //: Represents a mixture model (a set of individual pdfs + weights) 00025 class vpdfl_mixture : public vpdfl_pdf_base 00026 { 00027 vcl_vector<vpdfl_pdf_base*> component_; 00028 vcl_vector<double> weight_; 00029 00030 //: Workspace so we don't have to keep creating vectors 00031 mutable vnl_vector<double> ws_; 00032 00033 void delete_stuff(); 00034 public: 00035 00036 //: Dflt ctor 00037 vpdfl_mixture(); 00038 00039 //: Copy ctor 00040 vpdfl_mixture(const vpdfl_mixture&); 00041 00042 //: Copy operator 00043 vpdfl_mixture& operator=(const vpdfl_mixture&); 00044 00045 //: Destructor 00046 virtual ~vpdfl_mixture(); 00047 00048 //: Probability density at x 00049 virtual double operator()(const vnl_vector<double>& x) const; 00050 00051 //: Log of probability density at x 00052 virtual double log_p(const vnl_vector<double>& x) const; 00053 00054 //: Gradient of PDF at x 00055 virtual void gradient(vnl_vector<double>& g, 00056 const vnl_vector<double>& x, double& p) const; 00057 00058 //: Not Yet Implemented 00059 // Compute nearest point to x which has a density above a threshold 00060 // If log_p(x)>log_p_min then x unchanged. Otherwise x is moved 00061 // (typically up the gradient) until log_p(x)>=log_p_min. 00062 // \param x This may be modified to the nearest plausible position. 00063 // \param log_p_min lower threshold for log_p(x) 00064 virtual void nearest_plausible(vnl_vector<double>& x, double log_p_min) const; 00065 00066 //: Initialise to use n components of type comp_type 00067 // Clones taken by comp_type 00068 void init(const vpdfl_pdf_base& comp_type, unsigned n); 00069 00070 //: Return instance object for this PDF 00071 // Object is created on heap. Caller responsible for deletion. 00072 virtual vpdfl_sampler_base * new_sampler() const; 00073 00074 //: Number of components in mixture 00075 unsigned n_components() const { return component_.size(); } 00076 00077 //: Get i<I>th</I> weight. 00078 double weight(unsigned i) const { return weight_[i]; } 00079 00080 //: Array of weights 00081 // Use weight(i) where possible 00082 const vcl_vector<double>& weights() const { return weight_; } 00083 00084 //: Array of weights 00085 // Warning care must be taken to ensure consistency when modifying weights 00086 // Warning. Use weight(i) where possible 00087 vcl_vector<double>& weights() { return weight_; } 00088 00089 //: Return index of component nearest to x 00090 unsigned nearest_comp(const vnl_vector<double>& x) const; 00091 00092 //: Set the contents of the mixture model. 00093 // Clones are taken of all the data, and the class will be responsible for their deletion. 00094 void set(const vcl_vector<vpdfl_pdf_base*> components, const vcl_vector<double> & weights); 00095 00096 //: Add a component to current model 00097 // Clone taken of comp 00098 void add_component(const vpdfl_pdf_base& comp); 00099 00100 //: Remove all components cleanly 00101 void clear(); 00102 00103 //: Get i<I>th</I> component. 00104 const vpdfl_pdf_base & component(unsigned i) const { return *component_[i]; } 00105 00106 //: Access to components - for use by builders 00107 // Care must be taken to ensure consistency when modifying 00108 // Use component(i) where possible 00109 vcl_vector<vpdfl_pdf_base*>& components() { return component_; } 00110 00111 //: Access to components - for use by builders 00112 // Use component(i) where possible 00113 const vcl_vector<vpdfl_pdf_base*>& components() const { return component_; } 00114 00115 //: Set the whole pdf mean and variance values. 00116 // Components and Weights should already be correct so that 00117 // the error checking can work. 00118 // #define NDEBUG to turn off error checking. 00119 void set_mean_and_variance(vnl_vector<double>&m, vnl_vector<double>&v); 00120 00121 //: Return true if the object represents a valid PDF. 00122 // This will return false, if n_dims() is 0, for example just ofter 00123 // default construction. 00124 virtual bool is_valid_pdf() const; 00125 00126 //: Version number for I/O 00127 short version_no() const; 00128 00129 //: Name of the class 00130 virtual vcl_string is_a() const; 00131 00132 //: Does the name of the class match the argument? 00133 virtual bool is_class(vcl_string const& s) const; 00134 00135 //: Create a copy on the heap and return base class pointer 00136 virtual vpdfl_pdf_base* clone() const; 00137 00138 //: Print class to os 00139 virtual void print_summary(vcl_ostream& os) const; 00140 00141 //: Save class to binary file stream 00142 virtual void b_write(vsl_b_ostream& bfs) const; 00143 00144 //: Load class from binary file stream 00145 virtual void b_read(vsl_b_istream& bfs); 00146 }; 00147 00148 #endif // vpdfl_mixture_h_