core/vpdl/vpdl_distribution.h
Go to the documentation of this file.
00001 // This is core/vpdl/vpdl_distribution.h
00002 #ifndef vpdl_distribution_h_
00003 #define vpdl_distribution_h_
00004 //:
00005 // \file
00006 // \author Matthew Leotta
00007 // \date February 5, 2009
00008 // \brief The templated base class for all distributions
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   None
00013 // \endverbatim
00014 
00015 #include <vpdl/vpdt/vpdt_field_traits.h>
00016 #include <vpdl/vpdt/vpdt_field_default.h>
00017 #include <vcl_cmath.h>
00018 
00019 //: The base class for all probability distributions.
00020 // There is a distinct polymorphic class hierarchy for each choice of
00021 // template parameters.  The vector and matrix data types vary with both \c T and \c n.
00022 // \tparam T is the scalar type use for numerical calculations (generally double or float)
00023 // \tparam n is the fixed dimension of the space with special case 0 (the default)
00024 //           indicating dynamic dimension set at run time.
00025 // - For n > 1 the data types are vnl_vector_fixed<T,n> and vnl_matrix_fixed<T,n,n>
00026 // - For n == 1 the data types are T and T
00027 // - For n == 0 the data types are vnl_vector<T> and vnl_matrix<T>
00028 //
00029 template<class T, unsigned int n=0>
00030 class vpdl_distribution 
00031 {
00032  public:
00033   virtual ~vpdl_distribution() {}
00034 
00035   //: the data type used for vectors
00036   typedef typename vpdt_field_default<T,n>::type field_type;
00037 
00038   //: the data type used for vectors
00039   typedef typename vpdt_field_default<T,n>::type vector;
00040   //: the data type used for matrices
00041   typedef typename vpdt_field_traits<field_type>::matrix_type matrix;
00042  
00043   //: Return the run time dimension, which does not equal \c n when \c n==0
00044   virtual unsigned int dimension() const = 0;
00045 
00046   //: Create a copy on the heap and return base class pointer
00047   virtual vpdl_distribution<T,n>* clone() const = 0;
00048 
00049   //: Evaluate the unnormalized density at a point
00050   // \note This is not a probability density. 
00051   // To make this a probability multiply by norm_const()
00052   // \sa prob_density
00053   virtual T density(const vector& pt) const = 0;
00054 
00055   //: Evaluate the probability density at a point
00056   virtual T prob_density(const vector& pt) const
00057   {
00058     return density(pt) * norm_const();
00059   }
00060 
00061   //: Evaluate the log probability density at a point
00062   virtual T log_prob_density(const vector& pt) const
00063   {
00064     return vcl_log(prob_density(pt));
00065   };
00066 
00067   //: Compute the gradient of the unnormalized density at a point
00068   // \return the density at \a pt since it is usually needed as well, and
00069   //         is often trivial to compute while computing gradient
00070   // \retval g the gradient vector
00071   virtual T gradient_density(const vector& pt, vector& g) const = 0;
00072 
00073   //: The normalization constant for the density
00074   // When density() is multiplied by this value it becomes prob_density
00075   // norm_const() is reciprocal of the integral of density over the entire field
00076   virtual T norm_const() const = 0;
00077 
00078   //: Evaluate the cumulative distribution function at a point
00079   // This is the integral of the density function from negative infinity
00080   // (in all dimensions) to the point in question
00081   // \note It is not possible to compute this value for all functions in
00082   //       closed form.  In some cases, numerical integration may be used.
00083   //       If no good solutions exists the function should return a quiet NaN.
00084   virtual T cumulative_prob(const vector& pt) const = 0;
00085 
00086   //: Compute the inverse of the cumulative_prob() function
00087   // The value of x: P(x'<x) = P for x' drawn from the distribution.
00088   // \note This is only valid for univariate distributions
00089   //       multivariate distributions will return a quiet NaN
00090   virtual vector inverse_cdf(const T& p) const;
00091 
00092   //: The probability of being in an axis-aligned box
00093   // The box is defined by two points, the minimum and maximum.
00094   // Implemented in terms of \c cumulative_prob() by default.
00095   virtual T box_prob(const vector& min_pt, const vector& max_pt) const;
00096 
00097   //: Compute the mean of the distribution.
00098   // This may be trivial for distributions like Gaussians,
00099   // but actually involves computation for others.
00100   virtual void compute_mean(vector& mean) const = 0;
00101 
00102   //: Compute the covariance of the distribution.
00103   // This may be trivial for distributions like Gaussians,
00104   // but actually involves computation for others.
00105   virtual void compute_covar(matrix& covar) const = 0;
00106 };
00107 
00108 
00109 //: Default implementation of numerical CDF inverse computation.
00110 // This function is called by the virtual function inverse_cdf() by default
00111 // in the univariate case.
00112 template <class T>
00113 T vpdl_compute_inverse_cdf(const vpdl_distribution<T,1>& dist, double p);
00114 
00115 
00116 //=============================================================================
00117 // These global functions allow vpdl_distributions be used efficiently as
00118 // components in vpdt distributions like vpdt_mixture_of
00119 
00120 //: probability density wrapper for vpdt
00121 template<class T, unsigned int n>
00122 inline T vpdt_prob_density(const vpdl_distribution<T,n>& d, 
00123                            const typename vpdt_field_default<T,n>::type& pt)
00124 {
00125   return d.prob_density(pt);
00126 }
00127 
00128 //: The box probability wrapper for vpdt
00129 template<class T, unsigned int n>
00130 inline T vpdt_box_prob(const vpdl_distribution<T,n>& d,
00131                        const typename vpdt_field_default<T,n>::type& min_pt,
00132                        const typename vpdt_field_default<T,n>::type& max_pt)
00133 {
00134   return d.box_prob(min_pt,max_pt);
00135 }
00136 
00137 //: The log density wrapper for vpdt
00138 template<class T, unsigned int n>
00139 inline T vpdt_log_density(const vpdl_distribution<T,n>& d, 
00140                           const typename vpdt_field_default<T,n>::type& pt)
00141 {
00142   return d.log_density(pt);
00143 }
00144 
00145 //: The log probability density wrapper for vpdt
00146 template<class T, unsigned int n>
00147 inline T vpdt_log_prob_density(const vpdl_distribution<T,n>& d, 
00148                                const typename vpdt_field_default<T,n>::type& pt)
00149 {
00150   return d.log_prob_density(pt);
00151 }
00152 
00153 
00154 #endif // vpdl_distribution_h_