vpdt_norm_metric.h
Go to the documentation of this file.
1 // This is core/vpdl/vpdt/vpdt_norm_metric.h
2 #ifndef vpdt_norm_metric_h_
3 #define vpdt_norm_metric_h_
4 //:
5 // \file
6 // \author Matthew Leotta
7 // \date March 5, 2009
8 // \brief Metrics derived from norms
9 //
10 // \verbatim
11 // Modifications
12 // <None yet>
13 // \endverbatim
14 
15 
16 #include <limits>
17 #include <cmath>
19 #include <vpdl/vpdt/vpdt_access.h>
21 #ifdef _MSC_VER
22 # include <vcl_msvc_warnings.h>
23 #endif
24 #include <cassert>
25 
26 
27 //: A metric in field \c F with metric tensor \c Tensor
28 // \note the \c Disambiguate template parameter is a dummy used to
29 // prevent ambiguous instantiations
30 template<class F, class Tensor, class Disambiguate= void>
32 
33 
34 //: A metric in field \c F with vpdt_eigen_sym_matrix covariance
35 template<class F>
36 struct vpdt_norm_metric<F, typename vpdt_eigen_sym_matrix_gen<F>::type,
37  typename vpdt_field_traits<F>::type_is_vector >
38 {
39  //: the data type used for the metric tensor
41  //: the data type used for scalars
43  //: the data type used for vectors
45  //: the data type used for matrices
47 
48  //: Compute the Mahalanobis distance between two points
49  static inline T distance(const F& pt1, const F& pt2, const covar_type& c)
50  {
51  return std::sqrt(sqr_distance(pt1,pt2,c));
52  }
53 
54  //: Compute the square Mahalanobis distance between two points
55  static inline T sqr_distance(const F& pt1, const F& pt2, const covar_type& c)
56  {
57  // F must provide operator-(F,F) that returns (or can cast to) the vector type
58  vector d(pt1-pt2);
59  return c.inverse_quad_form(d);
60  }
61 
62  //: Compute the square Mahalanobis distance and also the derivative \a g wrt \a pt1
63  static inline T sqr_distance_deriv(const F& pt1, const F& pt2,
64  const covar_type& c, vector& g)
65  {
66  // F must provide operator-(F,F) that returns (or can cast to) the vector type
67  vector d(pt1-pt2);
68  c.inverse_product(d,g);
69  T sqr_dist = dot_product(d,g);
70  g *= 2;
71  return sqr_dist;
72  }
73 
74  //: Compute the covariance matrix (metric tensor) at a point
75  // \note this metric is independent of the point
76  static inline void compute_covar(matrix& covar, const F& /*pt*/, const covar_type& c)
77  {
78  c.form_matrix(covar);
79  }
80 
81  //: Compute the determinant of the covariance matrix (metric tensor) at a point
82  // \note this metric is independent of the point
83  static inline T covar_det(const F& /*pt*/, const covar_type& c)
84  {
85  return c.determinant();
86  }
87 };
88 
89 
90 //: A metric in field \c F with vector (diagonal matrix) covariance.
91 // In this case each dimension is independent
92 template<class F>
93 struct vpdt_norm_metric<F, typename vpdt_field_traits<F>::vector_type,
94  typename vpdt_field_traits<F>::type_is_vector >
95 {
96  //: the data type used for the metric tensor
98  //: the data type used for scalars
100  //: the data type used for vectors
102  //: the data type used for matrices
104 
105  //: Compute the Mahalanobis distance between two points
106  static inline T distance(const F& pt1, const F& pt2, const covar_type& c)
107  {
108  return std::sqrt(sqr_distance(pt1,pt2,c));
109  }
110 
111  //: Compute the square Mahalanobis distance between two points
112  static inline T sqr_distance(const F& pt1, const F& pt2, const covar_type& c)
113  {
114  const unsigned int d = vpdt_size(c);
115  assert(vpdt_size(pt1) == d);
116  assert(vpdt_size(pt2) == d);
117  T val = T(0);
118  for (unsigned int i=0; i<d; ++i)
119  {
120  T tmp = (vpdt_index(pt1,i)-vpdt_index(pt2,i));
121  val += tmp*tmp/vpdt_index(c,i);
122  }
123  return val;
124  }
125 
126  //: Compute the square Mahalanobis distance and also the derivative \a g wrt \a pt1
127  static inline T sqr_distance_deriv(const F& pt1, const F& pt2,
128  const covar_type& c, vector& g)
129  {
130  const unsigned int d = vpdt_size(c);
131  vpdt_set_size(g,d);
132  assert(vpdt_size(pt1) == d);
133  assert(vpdt_size(pt2) == d);
134  T val = T(0);
135  for (unsigned int i=0; i<d; ++i)
136  {
137  T tmp = (vpdt_index(pt1,i)-vpdt_index(pt2,i));
138  T& g_i = vpdt_index(g,i) = tmp/vpdt_index(c,i);
139  val += tmp*g_i;
140  g_i *= 2;
141  }
142  return val;
143  }
144 
145  //: Compute the covariance matrix (metric tensor) at a point
146  // \note this metric is independent of the point
147  static inline void compute_covar(matrix& covar, const F& /*pt*/, const covar_type& c)
148  {
149  const unsigned int d = c.size();
150  vpdt_set_size(covar,d);
151  assert(vpdt_size(covar) == d);
152  for (unsigned int i=0; i<d; ++i)
153  {
154  vpdt_index(covar,i,i) = vpdt_index(c,i);
155  for (unsigned int j=i+1; j<d; ++j)
156  vpdt_index(covar,i,j) = vpdt_index(covar,j,i) = T(0);
157  }
158  }
159 
160  //: Compute the determinant of the covariance matrix (metric tensor) at a point
161  // \note this metric is independent of the point
162  static inline T covar_det(const F& pt, const covar_type& c)
163  {
164  const unsigned int d = c.size();
165  double det = 1.0;
166  for (unsigned int i=0; i<d; ++i)
167  det *= vpdt_index(c,i);
168  return static_cast<T>(det);
169  }
170 };
171 
172 
173 //: A metric in field \c F with scalar (scaled identity matrix) covariance.
174 // In this case the metric is a scaled L2 norm
175 template<class F>
176 struct vpdt_norm_metric<F, typename vpdt_field_traits<F>::scalar_type,
177  typename vpdt_field_traits<F>::type_is_vector >
178 {
179  //: the data type used for the metric tensor
181  //: the data type used for scalars
183  //: the data type used for vectors
185  //: the data type used for matrices
187 
188  //: Compute the Mahalanobis distance between two points
189  static inline T distance(const F& pt1, const F& pt2, const covar_type& c)
190  {
191  return std::sqrt(sqr_distance(pt1,pt2,c));
192  }
193 
194  //: Compute the square Mahalanobis distance between two points
195  static inline T sqr_distance(const F& pt1, const F& pt2, const covar_type& c)
196  {
197  const unsigned int d = vpdt_size(pt1);
198  assert(vpdt_size(pt2) == d);
199  T val = T(0);
200  for (unsigned int i=0; i<d; ++i)
201  {
202  T tmp = (vpdt_index(pt1,i)-vpdt_index(pt2,i));
203  val += tmp*tmp/c;
204  }
205  return val;
206  }
207 
208  //: Compute the square Mahalanobis distance and also the derivative \a g wrt \a pt1
209  static inline T sqr_distance_deriv(const F& pt1, const F& pt2,
210  const covar_type& c, vector& g)
211  {
212  const unsigned int d = vpdt_size(pt1);
213  vpdt_set_size(g,d);
214  assert(vpdt_size(pt2) == d);
215  T val = T(0);
216  for (unsigned int i=0; i<d; ++i)
217  {
218  T tmp = (vpdt_index(pt1,i)-vpdt_index(pt2,i));
219  T& g_i = vpdt_index(g,i) = tmp/c;
220  val += tmp*g_i;
221  g_i *= 2;
222  }
223  return val;
224  }
225 
226  //: Compute the covariance matrix (metric tensor) at a point
227  // \note this metric is independent of the point
228  static inline void compute_covar(matrix& covar, const F& pt, const covar_type& c)
229  {
230  const unsigned int d = vpdt_size(pt);
231  vpdt_set_size(covar,d);
232  assert(vpdt_size(covar) == d);
233  for (unsigned int i=0; i<d; ++i)
234  {
235  vpdt_index(covar,i,i) = c;
236  for (unsigned int j=i+1; j<d; ++j)
237  vpdt_index(covar,i,j) = vpdt_index(covar,j,i) = T(0);
238  }
239  }
240 
241  //: Compute the determinant of the covariance matrix (metric tensor) at a point
242  // \note this metric is independent of the point
243  static inline T covar_det(const F& pt, const covar_type& c)
244  {
245  const unsigned int d = vpdt_size(pt);
246  double det = 1.0;
247  for (unsigned int i=0; i<d; ++i)
248  det *= c;
249  return static_cast<T>(det);
250  }
251 };
252 
253 
254 //: A metric in field \c F with scalar variance.
255 // In this case the metric is a scaled L2 norm
256 template<class F>
257 struct vpdt_norm_metric<F, typename vpdt_field_traits<F>::scalar_type,
258  typename vpdt_field_traits<F>::type_is_scalar >
259 {
260  //: the data type used for the metric tensor
262  //: the data type used for scalars
264  //: the data type used for vectors
266  //: the data type used for matrices
268 
269  //: Compute the Mahalanobis distance between two points
270  static inline T distance(const F& pt1, const F& pt2, const covar_type& c)
271  {
272  return std::sqrt(sqr_distance(pt1,pt2,c));
273  }
274 
275  //: Compute the square Mahalanobis distance between two points
276  static inline T sqr_distance(const F& pt1, const F& pt2, const covar_type& c)
277  {
278  T tmp = pt1-pt2;
279  return tmp*tmp/c;
280  }
281 
282  //: Compute the square Mahalanobis distance and also the derivative \a g wrt \a pt1
283  static inline T sqr_distance_deriv(const F& pt1, const F& pt2,
284  const covar_type& c, vector& g)
285  {
286  T tmp = pt1-pt2;
287  g = 2*tmp/c;
288  return tmp*tmp/c;
289  }
290 
291  //: Compute the covariance matrix (metric tensor) at a point
292  // \note this metric is independent of the point
293  static inline void compute_covar(matrix& covar, const F& /*pt*/, const covar_type& c)
294  {
295  covar = c;
296  }
297 
298  //: Compute the determinant of the covariance matrix (metric tensor) at a point
299  // \note this metric is independent of the point
300  static inline T covar_det(const F& /*pt*/, const covar_type& c)
301  {
302  return c;
303  }
304 };
305 
306 
307 #endif // vpdt_norm_metric_h_
static T sqr_distance(const F &pt1, const F &pt2, const covar_type &c)
Compute the square Mahalanobis distance between two points.
static T distance(const F &pt1, const F &pt2, const covar_type &c)
Compute the Mahalanobis distance between two points.
static T sqr_distance(const F &pt1, const F &pt2, const covar_type &c)
Compute the square Mahalanobis distance between two points.
VNL_EXPORT T dot_product(m const &, m const &)
static T covar_det(const F &pt, const covar_type &c)
Compute the determinant of the covariance matrix (metric tensor) at a point.
static T covar_det(const F &, const covar_type &c)
Compute the determinant of the covariance matrix (metric tensor) at a point.
static T sqr_distance_deriv(const F &pt1, const F &pt2, const covar_type &c, vector &g)
Compute the square Mahalanobis distance and also the derivative g wrt pt1.
static T distance(const F &pt1, const F &pt2, const covar_type &c)
Compute the Mahalanobis distance between two points.
static T sqr_distance(const F &pt1, const F &pt2, const covar_type &c)
Compute the square Mahalanobis distance between two points.
static void compute_covar(matrix &covar, const F &pt, const covar_type &c)
Compute the covariance matrix (metric tensor) at a point.
static T sqr_distance_deriv(const F &pt1, const F &pt2, const covar_type &c, vector &g)
Compute the square Mahalanobis distance and also the derivative g wrt pt1.
static T sqr_distance(const F &pt1, const F &pt2, const covar_type &c)
Compute the square Mahalanobis distance between two points.
static T covar_det(const F &, const covar_type &c)
Compute the determinant of the covariance matrix (metric tensor) at a point.
static T sqr_distance_deriv(const F &pt1, const F &pt2, const covar_type &c, vector &g)
Compute the square Mahalanobis distance and also the derivative g wrt pt1.
T & vpdt_index(vnl_vector< T > &v, unsigned int i)
Index into a vnl_vector.
Definition: vpdt_access.h:101
static T distance(const F &pt1, const F &pt2, const covar_type &c)
Compute the Mahalanobis distance between two points.
static void compute_covar(matrix &covar, const F &, const covar_type &c)
Compute the covariance matrix (metric tensor) at a point.
static T sqr_distance_deriv(const F &pt1, const F &pt2, const covar_type &c, vector &g)
Compute the square Mahalanobis distance and also the derivative g wrt pt1.
specialized template trait classes for properties of a field type
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).
static T distance(const F &pt1, const F &pt2, const covar_type &c)
Compute the Mahalanobis distance between two points.
generate the vpdt_eigen_sys_matrix type from a field type.
Overloaded functions to allow uniform API access to various field types.
static void compute_covar(matrix &covar, const F &, const covar_type &c)
Compute the covariance matrix (metric tensor) at a point.
A metric in field F with metric tensor Tensor.
A symmetric matrix represented in eigenvalue decomposition.
static void compute_covar(matrix &covar, const F &, const covar_type &c)
Compute the covariance matrix (metric tensor) at a point.
vpdt_eigen_sym_matrix_gen< F >::type covar_type
the data type used for the metric tensor.
unsigned int vpdt_size(const vnl_vector< T > &v)
Access the size of a vnl_vector.
Definition: vpdt_access.h:36
static T covar_det(const F &pt, const covar_type &c)
Compute the determinant of the covariance matrix (metric tensor) at a point.