26 #ifndef MLN_NORM_L2_HH
27 # define MLN_NORM_L2_HH
35 # include <mln/math/sqr.hh>
36 # include <mln/math/sqrt.hh>
37 # include <mln/algebra/vec.hh>
38 # include <mln/value/ops.hh>
47 template <
unsigned n,
typename T>
class vec;
56 template <
unsigned n,
typename C>
57 mln_sum_product(C,C) l2(const C (&vec)[n]);
59 template <
unsigned n, typename C>
60 mln_sum_product(C,C) l2(const algebra::vec<n,C>& vec);
65 template <
unsigned n, typename C>
66 mln_sum_product(C,C)
sqr_l2(const C (&vec)[n]);
68 template <
unsigned n, typename C>
69 mln_sum_product(C,C)
sqr_l2(const algebra::vec<n,C>& vec);
74 template <
unsigned n, typename C>
75 mln_sum_product(C,C)
l2_distance(const C (&vec1)[n], const C (&vec2)[n]);
77 template <
unsigned n, typename C>
78 mln_sum_product(C,C)
l2_distance(const algebra::vec<n,C>& vec1,
79 const algebra::vec<n,C>& vec2);
83 # ifndef MLN_INCLUDE_ONLY
88 template <
unsigned n,
typename C,
typename V>
93 typedef mln_sum_product(C,C) M;
95 for (
unsigned i = 0; i < n; ++i)
97 M sqr_v_i =
static_cast<M
>(mln::math::sqr(vec[i]));
98 m =
static_cast<M
>(m + sqr_v_i);
100 return mln::math::sqrt(m);
103 template <
unsigned n,
typename C,
typename V>
106 sqr_l2_(const V& vec)
108 mln_sum_product(C,C) m = 0;
109 for (
unsigned i = 0; i < n; ++i)
110 m += mln::math::sqr(vec[i]);
114 template <
unsigned n, typename C, typename V>
117 l2_distance_(const V& vec1, const V& vec2)
119 typedef mln_sum_product(C,C) D;
121 for (
unsigned i = 0; i < n; ++i)
123 D sqr_v1_v2 =
static_cast<D
>(mln::math::sqr(vec1[i] - vec2[i]));
124 d =
static_cast<D
>(d + sqr_v1_v2);
126 return mln::math::sqrt(d);
136 template <
unsigned n,
typename C>
139 l2(const C (&vec)[n])
141 return impl::l2_<n, C>(vec);
144 template <
unsigned n,
typename C>
147 l2(const algebra::vec<n,C>& vec)
149 return impl::l2_<n, C>(vec);
153 template <
unsigned n,
typename C>
158 return impl::sqr_l2_<n, C>(vec);
161 template <
unsigned n,
typename C>
164 sqr_l2(const algebra::vec<n,C>& vec)
166 return impl::sqr_l2_<n, C>(vec);
170 template <
unsigned n,
typename C>
175 return impl::l2_distance_<n, C>(vec1, vec2);
178 template <
unsigned n,
typename C>
181 l2_distance(const algebra::vec<n,C>& vec1, const algebra::vec<n,C>& vec2)
183 return impl::l2_distance_<n, C>(vec1, vec2);
186 # endif // ! MLN_INCLUDE_ONLY
193 #endif // ! MLN_NORM_L2_HH