vpdl_kernel_gaussian_sfbw.h
Go to the documentation of this file.
1 // This is core/vpdl/vpdl_kernel_gaussian_sfbw.h
2 #ifndef vpdl_kernel_gaussian_sfbw_h_
3 #define vpdl_kernel_gaussian_sfbw_h_
4 //:
5 // \file
6 // \author Matthew Leotta
7 // \date February 24, 2009
8 // \brief A fixed bandwidth spherical Gaussian kernel distribution
9 //
10 // \verbatim
11 // Modifications
12 // None
13 // \endverbatim
14 
15 #include <limits>
16 #include <vpdl/vpdl_kernel_base.h>
17 #include <vpdl/vpdt/vpdt_access.h>
18 #include <vnl/vnl_erf.h>
19 #include <vnl/vnl_math.h> // for twopi
20 #ifdef _MSC_VER
21 # include <vcl_msvc_warnings.h>
22 #endif
23 #include <cassert>
24 
25 //: A fixed bandwidth spherical Gaussian kernel distribution
26 // The bandwidth is the standard deviation of the Gaussian kernel.
27 template<class T, unsigned int n=0>
29 {
30  public:
31  //: the data type used for vectors
33  //: the data type used for matrices
35 
36  //: Default Constructor
38 
39  //: Constructor - from sample centers and bandwidth (variance)
40  vpdl_kernel_gaussian_sfbw(const std::vector<vector>& samplez,
41  T bandwid = T(1))
42  : vpdl_kernel_fbw_base<T,n>(samplez,bandwid) {}
43 
44  //: Create a copy on the heap and return base class pointer
45  virtual vpdl_distribution<T,n>* clone() const
46  {
47  return new vpdl_kernel_gaussian_sfbw<T,n>(*this);
48  }
49 
50  //: Evaluate the unnormalized density at a point
51  virtual T density(const vector& pt) const
52  {
53  const unsigned int nc = this->num_components();
54  if (nc <= 0)
55  return 0.0;
56 
57  const unsigned int d = this->dimension();
58  T sum = T(0);
59  typedef typename std::vector<vector>::const_iterator vitr;
60  for (vitr s=this->samples().begin(); s!=this->samples().end(); ++s) {
61  T ssd = T(0);
62  for (unsigned int i=0; i<d; ++i) {
63  T tmp = (vpdt_index(pt,i)-vpdt_index(*s,i))/this->bandwidth();
64  ssd += tmp*tmp;
65  }
66  sum += T(std::exp(-0.5*ssd));
67  }
68 
69  return sum;
70  }
71 
72  //: Evaluate the probability density at a point
73  virtual T prob_density(const vector& pt) const
74  {
75  const unsigned int nc = this->num_components();
76  if (nc <= 0)
77  return 0.0;
78 
79  return density(pt)*this->norm_const();
80  }
81 
82  //: Compute the gradient of the unnormalized density at a point
83  // \return the density at \a pt since it is usually needed as well, and
84  // is often trivial to compute while computing gradient
85  // \retval g the gradient vector
86  virtual T gradient_density(const vector& pt, vector& g) const
87  {
88  const unsigned int d = this->dimension();
89  vpdt_set_size(g,d);
90  vpdt_fill(g,T(0));
91  const unsigned int nc = this->num_components();
92  if (nc <= 0)
93  return 0.0;
94 
95  T sum = T(0);
96  vector g_s;
97  vpdt_set_size(g_s,d);
98  typedef typename std::vector<vector>::const_iterator vitr;
99  for (vitr s=this->samples().begin(); s!=this->samples().end(); ++s) {
100  T ssd = T(0);
101  for (unsigned int i=0; i<d; ++i) {
102  T tmp = (vpdt_index(pt,i)-vpdt_index(*s,i))/this->bandwidth();
103  vpdt_index(g_s,i) = tmp/this->bandwidth();
104  ssd += tmp*tmp;
105  }
106  T dens = T(std::exp(-0.5*ssd));
107  g_s *= -dens;
108  sum += dens;
109  g += g_s;
110  }
111 
112  return sum;
113  }
114 
115  //: Evaluate the cumulative distribution function at a point
116  // This is the integral of the density function from negative infinity
117  // (in all dimensions) to the point in question
118  virtual T cumulative_prob(const vector& pt) const
119  {
120  const unsigned int nc = this->num_components();
121  if (nc <= 0)
122  return 0.0;
123 
124  const unsigned int d = this->dimension();
125  double s2 = 1/(this->bandwidth()*std::sqrt(2.0));
126 
127  double sum = 0.0;
128  typedef typename std::vector<vector>::const_iterator vitr;
129  for (vitr s=this->samples().begin(); s!=this->samples().end(); ++s) {
130  double val = 1.0;
131  for (unsigned int i=0; i<d; ++i) {
132  val *= 0.5*vnl_erf(s2*(vpdt_index(pt,i)-vpdt_index(*s,i))) + 0.5;
133  }
134  sum += val;
135  }
136  return static_cast<T>(sum/nc);
137  }
138 
139  //: The probability of being in an axis-aligned box
140  // The box is defined by two points, the minimum and maximum.
141  // Reimplemented for efficiency since the axis are independent
142  T box_prob(const vector& min_pt, const vector& max_pt) const
143  {
144  const unsigned int nc = this->num_components();
145  if (nc <= 0)
146  return 0.0;
147 
148  const unsigned int dim = this->dimension();
149  double s2 = 1/(this->bandwidth()*std::sqrt(2.0));
150 
151  double sum = 0.0;
152  typedef typename std::vector<vector>::const_iterator vitr;
153  for (vitr s=this->samples().begin(); s!=this->samples().end(); ++s) {
154  double prob = 1.0;
155  for (unsigned int i=0; i<dim; ++i) {
156  if (vpdt_index(max_pt,i)<=vpdt_index(min_pt,i))
157  return T(0);
158  prob *= (vnl_erf(s2*(vpdt_index(max_pt,i)-vpdt_index(*s,i))) -
159  vnl_erf(s2*(vpdt_index(min_pt,i)-vpdt_index(*s,i))))/2;
160  }
161  sum += prob;
162  }
163  return static_cast<T>(sum/nc);
164  }
165 
166  //: Compute the covariance of the distribution.
167  virtual void compute_covar(matrix& covar) const
168  {
169  const unsigned int d = this->dimension();
170  const unsigned int nc = this->num_components();
171  vector mean;
172  vpdt_set_size(covar,d);
173  vpdt_fill(covar,T(0));
174  vpdt_set_size(mean,d);
175  vpdt_fill(mean,T(0));
176  typedef typename std::vector<vector>::const_iterator samp_itr;
177  for (samp_itr s = this->samples().begin(); s != this->samples().end(); ++s) {
178  covar += outer_product(*s,*s);
179  mean += *s;
180  }
181  mean /= T(nc);
182  covar /= T(nc);
183  covar -= outer_product(mean,mean);
184  T var = this->bandwidth()*this->bandwidth();
185  for (unsigned int i=0; i<d; ++i)
186  vpdt_index(covar,i,i) += var;
187  }
188 
189  //: The normalization constant for the kernel
190  virtual T kernel_norm_const() const
191  {
192  const unsigned int dim = this->dimension();
193  double v2pi = this->bandwidth()*this->bandwidth()*vnl_math::twopi;
194  double denom = v2pi;
195  for (unsigned int i=1; i<dim; ++i)
196  denom *= v2pi;
197 
198  return static_cast<T>(std::sqrt(1/denom));
199  }
200 };
201 
202 
203 #endif // vpdl_kernel_gaussian_sfbw_h_
vpdt_field_traits< field_type >::matrix_type matrix
the data type used for matrices.
virtual unsigned int dimension() const
Return the run time dimension, which does not equal n when n==0.
virtual T cumulative_prob(const vector &pt) const
Evaluate the cumulative distribution function at a point.
T bandwidth() const
Access the bandwidth.
virtual T prob_density(const vector &pt) const
Evaluate the probability density at a point.
virtual T density(const vector &pt) const
Evaluate the unnormalized density at a point.
vpdt_field_traits< vector >::matrix_type matrix
the data type used for matrices.
vpdl_kernel_gaussian_sfbw()
Default Constructor.
virtual T kernel_norm_const() const
The normalization constant for the kernel.
virtual vpdl_distribution< T, n > * clone() const
Create a copy on the heap and return base class pointer.
virtual T gradient_density(const vector &pt, vector &g) const
Compute the gradient of the unnormalized density at a point.
unsigned int num_components() const
Return the number of components in the mixture.
vpdt_field_default< T, n >::type vector
the data type used for vectors.
A fixed bandwidth spherical Gaussian kernel distribution.
T & vpdt_index(vnl_vector< T > &v, unsigned int i)
Index into a vnl_vector.
Definition: vpdt_access.h:101
vpdl_kernel_gaussian_sfbw(const std::vector< vector > &samplez, T bandwid=T(1))
Constructor - from sample centers and bandwidth (variance).
double vnl_erf(double x)
void vpdt_set_size(vnl_vector< T > &v, unsigned int s)
Set the size of a vnl_vector.
Definition: vpdt_access.h:63
The field traits class (scalar).
The base class for all probability distributions.
Overloaded functions to allow uniform API access to various field types.
virtual void compute_covar(matrix &covar) const
Compute the covariance of the distribution.
const std::vector< vector > & samples() const
Access the sample points.
virtual T norm_const() const
The normalization constant for the density.
Base classes for kernel (aka Parzen window) distributions.
void vpdt_fill(vnl_vector< T > &v, const T &val)
Fill a vnl_vector.
Definition: vpdt_access.h:78
T box_prob(const vector &min_pt, const vector &max_pt) const
The probability of being in an axis-aligned box.
float outer_product(const float &v1, const float &v2)
vnl defines outer_product for vectors but not scalars.
Definition: vpdt_access.h:149
A base class for fixed bandwidth kernel distributions.