vpdl_distribution.hxx
Go to the documentation of this file.
1 // This is core/vpdl/vpdl_distribution.hxx
2 #ifndef vpdl_distribution_hxx_
3 #define vpdl_distribution_hxx_
4 //:
5 // \file
6 
7 #include <limits>
8 #include "vpdl_distribution.h"
10 #ifdef _MSC_VER
11 # include <vcl_msvc_warnings.h>
12 #endif
13 #include <cassert>
14 
15 //: Default implementation of numerical CDF inverse computation.
16 // This function is called by the virtual function inverse_cdf() by default
17 // in the univariate case.
18 
19 template <class T>
20 T vpdl_compute_inverse_cdf(const vpdl_distribution<T,1>& /*dist*/, double /*p*/)
21 {
22  // FIXME: implement CDF inverse computation here
23  return T(0.0);
24 }
25 
26 
27 namespace{
28 
29 //: Define helper classes to create partial specialization of member functions.
30 template <class T, unsigned int n>
31 class inverse_cdf_helper
32 {
33  public:
34  typedef typename vpdl_distribution<T,n>::vector vector;
35 
36  //: Do the actual inversion
37  static inline vector invert(const vpdl_distribution<T,n>& /*dist*/, const T& /*p*/)
38  {
39  return vector(std::numeric_limits<T>::quiet_NaN());
40  }
41 };
42 
43 template <class T>
44 class inverse_cdf_helper<T,1>
45 {
46  public:
47  typedef typename vpdl_distribution<T,1>::vector vector;
48 
49  //: Do the actual inversion
50  static inline vector invert(const vpdl_distribution<T,1>& dist, const T& p)
51  {
52  return vpdl_compute_inverse_cdf(dist,p);
53  }
54 };
55 
56 template <class T>
57 class inverse_cdf_helper<T,0>
58 {
59  public:
60  typedef typename vpdl_distribution<T,0>::vector vector;
61 
62  //: Do the actual inversion
63  static inline vector invert(const vpdl_distribution<T,0>& dist, const T& /*p*/)
64  {
65  return vector(dist.dimension(), std::numeric_limits<T>::quiet_NaN());
66  }
67 };
68 
69 }
70 
71 
72 //: Compute the inverse of the cumulative_prob() function
73 // The value of x: P(x'<x) = P for x' drawn from the distribution.
74 // This is only valid for univariate distributions
75 // multivariate distributions will return -infinity
76 template <class T, unsigned int n>
79 {
80  // use a static helper class to do partial specialization
81  return inverse_cdf_helper<T,n>::invert(*this, p);
82 }
83 
84 
85 //: The probability of being in an axis-aligned box
86 // The box is defined by two points, the minimum and maximum.
87 // Implemented in terms of \c cumulative_prob() by default.
88 template <class T, unsigned int n>
90  const vector& max_pt) const
91 {
92  const unsigned int dim = this->dimension();
93 
94  // return zero for ill-defined box
95  for (unsigned int j=0; j<dim; ++j){
96  if (vpdt_index(max_pt,j)<=vpdt_index(min_pt,j))
97  return T(0);
98  }
99 
100  // this method is not tractable for large dimensions
101  assert(sizeof(unsigned long)*8 > dim);
102  // compute the number of corners of the box (2^dim)
103  const unsigned long num_corners = 1 << dim;
104 
105  T prob = T(0);
106  vector corner(min_pt);
107  for (unsigned long i=0; i<num_corners; ++i)
108  {
109  // In odd dimensions, corners with an odd number of maximal axis
110  // are added to the sum. In even dimensions, corners with an even
111  // number of maximal axis are added. The other corners are subtracted.
112  bool plus = (dim%2 != 1);
113  // create the corner position by selecting elements from max_pt and min_pt
114  for (unsigned int j=0; j<dim; ++j){
115  bool is_max = (i>>j) & 1;
116  plus ^= is_max; // toggle plus if is_max
117  vpdt_index(corner,j) = is_max?vpdt_index(max_pt,j):vpdt_index(min_pt,j);
118  }
119  if (plus)
120  prob += cumulative_prob(corner);
121  else
122  prob -= cumulative_prob(corner);
123  }
124 
125  return prob;
126 }
127 
128 
129 #undef VPDL_DISTRIBUTION_INSTANTIATE
130 #define VPDL_DISTRIBUTION_INSTANTIATE(T,n) \
131 template class vpdl_distribution<T,n >
132 
133 // instantiate this function only for n == 1
134 #undef VPDL_INVERSE_CDF_INSTANTIATE
135 #define VPDL_INVERSE_CDF_INSTANTIATE(T) \
136 template T vpdl_compute_inverse_cdf(const vpdl_distribution<T,1>& dist, double p)
137 
138 #endif // vpdl_distribution_hxx_
T vpdl_compute_inverse_cdf(const vpdl_distribution< T, 1 > &, double)
Default implementation of numerical CDF inverse computation.
virtual T box_prob(const vector &min_pt, const vector &max_pt) const
The probability of being in an axis-aligned box.
virtual vector inverse_cdf(const T &p) const
Compute the inverse of the cumulative_prob() function.
The templated base class for all distributions.
T & vpdt_index(vnl_vector< T > &v, unsigned int i)
Index into a vnl_vector.
Definition: vpdt_access.h:101
virtual unsigned int dimension() const =0
Return the run time dimension, which does not equal n when n==0.
The base class for all probability distributions.
Overloaded functions to allow uniform API access to various field types.