contrib/mul/vpdfl/vpdfl_gaussian.h
Go to the documentation of this file.
00001 // This is mul/vpdfl/vpdfl_gaussian.h
00002 #ifndef vpdfl_gaussian_h
00003 #define vpdfl_gaussian_h
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief Multi-variate gaussian PDF with arbitrary axes.
00010 // \author Tim Cootes
00011 // \date 16-Oct-98
00012 // \verbatim
00013 //  Modifications
00014 //   IMS   Converted to VXL 18 April 2000
00015 // \endverbatim
00016 
00017 #include <vpdfl/vpdfl_pdf_base.h>
00018 #include <vnl/vnl_matrix.h>
00019 #include <vnl/vnl_vector.h>
00020 #include <vcl_iosfwd.h>
00021 
00022 //: Class for multi-variate gaussians with arbitrary axes.
00023 //  Covariance matrix is represented by its eigenvectors and values
00024 class vpdfl_gaussian : public vpdfl_pdf_base
00025 {
00026   vnl_matrix<double> evecs_;
00027   vnl_vector<double> evals_;
00028   double log_k_;
00029   void calcLogK();
00030 
00031   //: Calculate (x-mu)' * Sigma^-1 * (x-mu)
00032   // This is the Mahalanobis distance squared from the mean.
00033   double dx_sigma_dx(const vnl_vector<double>& x) const;
00034 
00035  protected: // Workspace may be accessed by sub-classes
00036   //: Workspace
00037   // The difference between an input vector and the mean
00038   mutable vnl_vector<double> dx_;
00039   //: Workspace
00040   // Usually the input vector after normalisation.
00041   mutable vnl_vector<double> b_;
00042 
00043 
00044  public:
00045   //: Dflt ctor
00046   vpdfl_gaussian();
00047 
00048   //: Destructor
00049   virtual ~vpdfl_gaussian();
00050 
00051   //: Initialise
00052   // WARNING - the error checking for inconsistent parameters is not
00053   // foolproof.
00054   void set(const vnl_vector<double>& mean,
00055            const vnl_vector<double>& variance,
00056            const vnl_matrix<double>& evecs,
00057            const vnl_vector<double>& evals);
00058 
00059   //: Initialise safely
00060   // Calculates the variance, and checks that
00061   // the Eigenvalues are ordered and the Eigenvectors are unit normal
00062   //
00063   // Turn off assertions to remove error checking.
00064   //
00065   // This functions should only be used by builders.
00066   virtual void set(const vnl_vector<double>& mean,
00067                    const vnl_matrix<double>& evecs,
00068                    const vnl_vector<double>& evals);
00069 
00070   //: Initialise from mean and covariance matrix
00071   //  Note, eigenvectors computed from covar, and those corresponding
00072   //  to evals smaller than min_eval are truncated
00073   //
00074   // This functions should only be used by builders.
00075   void set(const vnl_vector<double>& mean,
00076            const vnl_matrix<double>& covar,
00077            double min_eval = 1e-6);
00078 
00079   //: Modify just the mean of the distribution
00080   // This functions should only be used by builders.
00081   void set_mean(const vnl_vector<double>& mean);
00082 
00083   //: Eigenvectors of covariance matrix
00084   // List ordering corresponds to eVals();
00085   const vnl_matrix<double>& eigenvecs() const { return evecs_; }
00086 
00087   //: Eigenvalues of covariance matrix
00088   // The list is ordered - largest Eigenvalues first.
00089   const vnl_vector<double>& eigenvals() const { return evals_; }
00090 
00091   //: The Covariance matrix of the Gaussian.
00092   // This value is calculated on the fly each time so calling this function
00093   // may not be very efficient
00094   vnl_matrix<double> covariance() const;
00095 
00096   //: log of normalisation constant for gaussian
00097   double log_k() const { return log_k_; }
00098 
00099   //: Create a sampler object on the heap
00100   // Caller is responsible for deletion.
00101   virtual vpdfl_sampler_base* new_sampler() const;
00102 
00103   //: Log of probability density at x
00104   // This value is also the Normalised Mahalanobis distance
00105   // from the centroid to the given vector.
00106   virtual double log_p(const vnl_vector<double>& x) const;
00107 
00108   //: Gradient of PDF at x
00109   virtual void gradient(vnl_vector<double>& g,
00110                         const vnl_vector<double>& x,
00111                         double& p) const;
00112 
00113   //: Compute threshold for PDF to pass a given proportion
00114   virtual double log_prob_thresh(double pass_proportion) const;
00115 
00116   //: Compute nearest point to x which has a density above a threshold
00117   //  If log_p(x)>log_p_min then x unchanged.  Otherwise x is moved
00118   //  directly towards the mean (i.e. to the nearest plausible point using a
00119   //  Mahalanobis distance) until log_p(x)=log_p_min.
00120   // \param x This may be modified to the nearest plausible position.
00121   // \param log_p_min lower threshold for log_p(x)
00122   virtual void nearest_plausible(vnl_vector<double>& x, double log_p_min) const;
00123 
00124   //: Version number for I/O
00125   short version_no() const;
00126 
00127   //: Name of the class
00128   virtual vcl_string is_a() const;
00129 
00130   //: Does the name of the class match the argument?
00131   virtual bool is_class(vcl_string const& s) const;
00132 
00133   //: Create a copy on the heap and return base class pointer
00134   virtual vpdfl_pdf_base* clone() const;
00135 
00136   //: Print class to os
00137   virtual void print_summary(vcl_ostream& os) const;
00138 
00139   //: Save class to binary file stream
00140   virtual void b_write(vsl_b_ostream& bfs) const;
00141 
00142 
00143   //: Load class from binary file stream
00144   virtual void b_read(vsl_b_istream& bfs);
00145 };
00146 
00147 #endif // vpdfl_gaussian_h