vpdt_update_gaussian.h
Go to the documentation of this file.
1 // This is core/vpdl/vpdt/vpdt_update_gaussian.h
2 #ifndef vpdt_update_gaussian_h_
3 #define vpdt_update_gaussian_h_
4 //:
5 // \file
6 // \author Matt Leotta (mleotta@lems.brown.edu)
7 // \date March 7, 2009
8 // \brief Iterative updating of Gaussians
9 
10 
13 
14 
15 //==============================================================================
16 // A helper class used to update the various covariance types
17 
18 //: Specialized classes to update covariance of different types
19 // \note the \c Disambiguate template parameter is a dummy used to
20 // prevent ambiguous instantiations
21 template<class F, class Covar, class Disambiguate= void>
23 
24 //: Specialized classes to update covariance of different types
25 template<class F>
27  typename vpdt_field_traits<F>::type_is_vector>
28 {
29  //: the data type used for covariance
31  //: the data type used for scalars
33  //: the data type used for vectors
35 
36  //: update the covariance matrix with a weighted vector difference
37  static inline void increment(Covar& c, const T& s, const vector& d)
38  {
39  // FIXME this could be more efficient if we could iteratively update the eigen decomposition
41  c.form_matrix(m);
42  m += s * outer_product(d,d);
43  c.set_matrix(m);
44  }
45 
46  //: enforce a minimum covariance value in all dimensions
47  static inline void enforce_min(Covar& c, const T& min_var)
48  {
49  vector ev = c.eigenvalues();
50  const unsigned int dim = vpdt_size(ev);
51  for (unsigned int i=0; i<dim; ++i){
52  T& evi = vpdt_index(ev,i);
53  if (evi < min_var)
54  evi = min_var;
55  }
56  c.set_eigenvalues(ev);
57  }
58 };
59 
60 
61 //: Specialized classes to update covariance of different types
62 template<class F>
63 struct vpdt_update_covariance<F, typename vpdt_field_traits<F>::vector_type,
64  typename vpdt_field_traits<F>::type_is_vector>
65 {
66  //: the data type used for scalars
68  //: the data type used for vectors
70 
71  //: update the covariance matrix with a weighted vector difference
72  static inline void increment(vector& c, const T& s, const vector& d)
73  {
74  c += s * element_product(d,d);
75  }
76 
77  //: enforce a minimum covariance value in all dimensions
78  static inline void enforce_min(vector& c, const T& min_var)
79  {
80  const unsigned int dim = vpdt_size(c);
81  for (unsigned int i=0; i<dim; ++i){
82  T& ci = vpdt_index(c,i);
83  if (ci < min_var)
84  ci = min_var;
85  }
86  }
87 };
88 
89 
90 //: Specialized classes to update covariance of different types
91 template<class F>
92 struct vpdt_update_covariance<F, typename vpdt_field_traits<F>::scalar_type,
93  typename vpdt_field_traits<F>::type_is_vector>
94 {
95  //: the data type used for scalars
97  //: the data type used for vectors
99 
100  //: update the covariance matrix with a weighted vector difference
101  static inline void increment(T& c, const T& s, const vector& d)
102  {
103  c += s * dot_product(d,d);
104  }
105 
106  //: enforce a minimum covariance value in all dimensions
107  static inline void enforce_min(T& c, const T& min_var)
108  {
109  if (c<min_var)
110  c = min_var;
111  }
112 };
113 
114 
115 //: Specialized classes to update covariance of different types
116 template<class F>
117 struct vpdt_update_covariance<F, typename vpdt_field_traits<F>::scalar_type,
118  typename vpdt_field_traits<F>::type_is_scalar>
119 {
120  //: the data type used for scalars
122 
123  //: update the covariance matrix with a weighted vector difference
124  static inline void increment(T& c, const T& s, const T& d)
125  {
126  c += s*d*d;
127  }
128 
129  //: enforce a minimum covariance value in all dimensions
130  static inline void enforce_min(T& c, const T& min_var)
131  {
132  if (c<min_var)
133  c = min_var;
134  }
135 };
136 
137 
138 //==============================================================================
139 // The Gaussian update functions
140 
141 
142 //: Update the statistics given a 1D Gaussian distribution and a learning rate
143 // \note if rho = 1/(num observations) then this just an online cumulative average
144 template <class F, class Covar>
147  const F& sample )
148 {
149  typedef typename vpdt_field_traits<F>::scalar_type T;
150  typedef typename vpdt_field_traits<F>::vector_type vector;
151 
152  // the complement of rho (i.e. rho+rho_comp=1.0)
153  T rho_comp = T(1) - rho;
154  // the difference vector between the sample and the mean
155  vector diff = sample - gaussian.mean;
156 
157  // update the covariance
159  gaussian.covar *= rho_comp;
160 
161  // update the mean
162  gaussian.mean += (rho * diff);
163 }
164 
165 
166 //: Update the statistics given a Gaussian distribution and a learning rate
167 // \param min_var forces the variance to stay above this limit
168 // \note If the same sample is observed repeatedly, the variances will
169 // converge to the minimum value parameter rather than zero.
170 template <class F, class Covar>
173  const F& sample,
174  typename vpdt_field_traits<F>::scalar_type min_var)
175 {
176  vpdt_update_gaussian(gaussian, rho, sample);
178 }
179 
180 
181 #endif // vpdt_update_gaussian_h_
Specialized classes to update covariance of different types.
static void increment(T &c, const T &s, const vector &d)
update the covariance matrix with a weighted vector difference.
VNL_EXPORT T dot_product(m const &, m const &)
covar_type covar
the matrix covariance.
#define m
static void enforce_min(T &c, const T &min_var)
enforce a minimum covariance value in all dimensions.
static void increment(Covar &c, const T &s, const vector &d)
update the covariance matrix with a weighted vector difference.
void vpdt_update_gaussian(vpdt_gaussian< F, Covar > &gaussian, typename vpdt_field_traits< F >::scalar_type rho, const F &sample)
Update the statistics given a 1D Gaussian distribution and a learning rate.
T & vpdt_index(vnl_vector< T > &v, unsigned int i)
Index into a vnl_vector.
Definition: vpdt_access.h:101
static void enforce_min(T &c, const T &min_var)
enforce a minimum covariance value in all dimensions.
VNL_EXPORT m element_product(m const &, m const &)
A Gaussian with variance independent in each dimension.
Definition: vpdt_gaussian.h:39
A generic Gaussian distribution.
specialized template trait classes for properties of a field type
The field traits class (scalar).
generate the vpdt_eigen_sys_matrix type from a field type.
static void increment(vector &c, const T &s, const vector &d)
update the covariance matrix with a weighted vector difference.
F mean
the mean.
static void enforce_min(Covar &c, const T &min_var)
enforce a minimum covariance value in all dimensions.
static void enforce_min(vector &c, const T &min_var)
enforce a minimum covariance value in all dimensions.
unsigned int vpdt_size(const vnl_vector< T > &v)
Access the size of a vnl_vector.
Definition: vpdt_access.h:36
float outer_product(const float &v1, const float &v2)
vnl defines outer_product for vectors but not scalars.
Definition: vpdt_access.h:149
static void increment(T &c, const T &s, const T &d)
update the covariance matrix with a weighted vector difference.