core/vpdl/vpdl_gaussian_sphere.h
Go to the documentation of this file.
00001 // This is core/vpdl/vpdl_gaussian_sphere.h
00002 #ifndef vpdl_gaussian_sphere_h_
00003 #define vpdl_gaussian_sphere_h_
00004 //:
00005 // \file
00006 // \author Matthew Leotta
00007 // \date February 11, 2009
00008 // \brief A Gaussian with (hyper-)spherical covariance
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   <None yet>
00013 // \endverbatim
00014 
00015 #include <vpdl/vpdl_gaussian_base.h>
00016 #include <vnl/vnl_erf.h>
00017 #include <vcl_limits.h>
00018 #include <vcl_cassert.h>
00019 
00020 #include <vpdl/vpdt/vpdt_gaussian.h>
00021 #include <vpdl/vpdt/vpdt_probability.h>
00022 #include <vpdl/vpdt/vpdt_log_probability.h>
00023 
00024 //: A Gaussian with (hyper-)spherical covariance
00025 template<class T, unsigned int n=0>
00026 class vpdl_gaussian_sphere : public vpdl_gaussian_base<T,n>
00027 {
00028  public:
00029   //: the data type used for vectors
00030   typedef typename vpdt_field_default<T,n>::type vector;
00031   //: the data type used for matrices
00032   typedef typename vpdt_field_traits<vector>::matrix_type matrix;
00033   //: the type used internally for covariance
00034   typedef T covar_type;
00035 
00036   //: Constructor
00037   // Optionally initialize the dimension for when n==0.
00038   // Otherwise var_dim is ignored
00039   vpdl_gaussian_sphere(unsigned int var_dim = n)
00040   : impl_(var_dim) {}
00041 
00042   //: Constructor - from mean and variance
00043   vpdl_gaussian_sphere(const vector& mean_val, const covar_type& var)
00044   : impl_(mean_val,var) {}
00045 
00046   //: Destructor
00047   virtual ~vpdl_gaussian_sphere() {}
00048 
00049   //: Create a copy on the heap and return base class pointer
00050   virtual vpdl_distribution<T,n>* clone() const
00051   {
00052     return new vpdl_gaussian_sphere<T,n>(*this);
00053   }
00054 
00055   //: Return the run time dimension, which does not equal \c n when \c n==0
00056   virtual unsigned int dimension() const { return impl_.dimension(); }
00057 
00058   //: Evaluate the unnormalized density at a point
00059   virtual T density(const vector& pt) const
00060   {
00061     return impl_.density(pt);
00062   }
00063 
00064   //: Evaluate the probability density at a point
00065   virtual T prob_density(const vector& pt) const
00066   {
00067     return vpdt_prob_density(impl_,pt);
00068   }
00069 
00070   //: Evaluate the log probability density at a point
00071   virtual T log_prob_density(const vector& pt) const
00072   {
00073     return vpdt_log_prob_density(impl_,pt);
00074   };
00075 
00076   //: Compute the gradient of the unnormalized density at a point
00077   // \return the density at \a pt since it is usually needed as well, and
00078   //         is often trivial to compute while computing gradient
00079   // \retval g the gradient vector
00080   virtual T gradient_density(const vector& pt, vector& g) const
00081   {
00082     return impl_.gradient_density(pt,g);
00083   }
00084 
00085   //: The normalization constant for the density
00086   // When density() is multiplied by this value it becomes prob_density
00087   // norm_const() is reciprocal of the integral of density over the entire field
00088   T norm_const() const
00089   {
00090     return impl_.norm_const();
00091   }
00092 
00093   //: The squared Mahalanobis distance to this point
00094   // Non-virtual for efficiency
00095   T sqr_mahal_dist(const vector& pt) const
00096   {
00097     return impl_.sqr_mahal_dist(pt);
00098   }
00099 
00100   //: Evaluate the cumulative distribution function at a point
00101   // This is the integral of the density function from negative infinity
00102   // (in all dimensions) to the point in question
00103   virtual T cumulative_prob(const vector& pt) const
00104   {
00105     return impl_.cumulative_prob(pt);
00106   }
00107 
00108   //: The probability of being in an axis-aligned box
00109   // The box is defined by two points, the minimum and maximum.
00110   // Reimplemented for efficiency since the axis are independent
00111   T box_prob(const vector& min_pt, const vector& max_pt) const
00112   {
00113     const unsigned int dim = this->dimension();
00114 
00115     double s2 = 1/vcl_sqrt(2*impl_.covar);
00116     // return zero for ill-defined box
00117     double prob = T(1);
00118     for (unsigned int i=0; i<dim; ++i) {
00119       if (vpdt_index(max_pt,i)<=vpdt_index(min_pt,i))
00120         return T(0);
00121       prob *= (vnl_erf(s2*(vpdt_index(max_pt,i)-vpdt_index(impl_.mean,i))) -
00122                vnl_erf(s2*(vpdt_index(min_pt,i)-vpdt_index(impl_.mean,i))))/2;
00123     }
00124     return static_cast<T>(prob);
00125   }
00126 
00127   //: Access the mean directly
00128   virtual const vector& mean() const { return impl_.mean; }
00129 
00130   //: Set the mean
00131   virtual void set_mean(const vector& mean_val) { impl_.mean = mean_val; }
00132 
00133   //: Compute the mean of the distribution.
00134   virtual void compute_mean(vector& mean_val) const { mean_val = impl_.mean; }
00135 
00136   //: Access the scalar variance
00137   const covar_type& covariance() const { return impl_.covar; }
00138 
00139   //: Set the scalar variance
00140   void set_covariance(const covar_type& var) { impl_.covar = var; }
00141 
00142   //: Compute the covariance of the distribution.
00143   // Should be the identity matrix times var_
00144   virtual void compute_covar(matrix& covar) const
00145   {
00146     impl_.compute_covar(covar);
00147   }
00148 
00149  protected:
00150   //: the Gaussian implementation from vpdt
00151   vpdt_gaussian<vector,covar_type> impl_;
00152 };
00153 
00154 
00155 #endif // vpdl_gaussian_sphere_h_