core/vpdl/vpdt/vpdt_probability.h
Go to the documentation of this file.
00001 // This is core/vpdl/vpdt/vpdt_probability.h
00002 #ifndef vpdt_probability_h_
00003 #define vpdt_probability_h_
00004 //:
00005 // \file
00006 // \author Matthew Leotta
00007 // \brief The basic functions for probability calculations
00008 // \date March 13, 2009
00009 //
00010 // These functions provide default implementations for various probability
00011 // calculation functions.  They are written in terms of distribution
00012 // member functions
00013 //
00014 // \verbatim
00015 //  Modifications
00016 //   <None yet>
00017 // \endverbatim
00018 
00019 
00020 #include <vpdl/vpdt/vpdt_dist_traits.h>
00021 #include <vnl/vnl_math.h>
00022 #include <vcl_cassert.h>
00023 
00024 //: Compute the probability from the density and normalization constant.
00025 template <class dist>
00026 inline typename vpdt_dist_traits<dist>::scalar_type
00027 vpdt_prob_density(const dist& d,
00028                   const typename vpdt_dist_traits<dist>::field_type& pt)
00029 {
00030   typedef typename vpdt_dist_traits<dist>::scalar_type T;
00031   T norm = d.norm_const();
00032   if (vnl_math_isinf(norm))
00033     return T(0);
00034   return norm * d.density(pt);
00035 }
00036 
00037 
00038 //: The probability of being in an axis-aligned box.
00039 // The box is defined by two points, the minimum and maximum.
00040 // Implemented in terms of \c vpdt_cumulative_prob() by default.
00041 template <class dist>
00042 typename vpdt_dist_traits<dist>::scalar_type
00043 vpdt_box_prob(const dist& d,
00044               const typename vpdt_dist_traits<dist>::field_type& min_pt,
00045               const typename vpdt_dist_traits<dist>::field_type& max_pt)
00046 {
00047   typedef typename vpdt_dist_traits<dist>::scalar_type T;
00048   typedef typename vpdt_dist_traits<dist>::field_type F;
00049   const unsigned int dim = d.dimension();
00050 
00051   // return zero for ill-defined box
00052   for (unsigned int j=0; j<dim; ++j){
00053     if (vpdt_index(max_pt,j)<=vpdt_index(min_pt,j))
00054       return T(0);
00055   }
00056 
00057   // this method is not tractable for large dimensions
00058   assert(sizeof(unsigned long)*8 > dim);
00059   // compute the number of corners of the box (2^dim)
00060   const unsigned long num_corners = 1 << dim;
00061 
00062   T prob = T(0);
00063   F corner(min_pt);
00064   for (unsigned long i=0; i<num_corners; ++i)
00065   {
00066     // In odd dimensions, corners with an odd number of maximal axis
00067     // are added to the sum.  In even dimensions, corners with an even
00068     // number of maximal axis are added. The other corners are subtracted.
00069     bool plus = (dim%2 != 1);
00070     // create the corner position by selecting elements from max_pt and min_pt
00071     for (unsigned int j=0; j<dim; ++j){
00072       bool is_max = (i>>j) & 1;
00073       plus ^= is_max; // toggle plus if is_max
00074       vpdt_index(corner,j) = is_max?vpdt_index(max_pt,j):vpdt_index(min_pt,j);
00075     }
00076     if (plus)
00077       prob += d.cumulative_prob(corner);
00078     else
00079       prob -= d.cumulative_prob(corner);
00080   }
00081 
00082   return prob;
00083 }
00084 
00085 #endif // vpdt_probability_h_