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_