00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_NORM_L2_HH
00027 # define MLN_NORM_L2_HH
00028
00034
00035 # include <mln/math/sqr.hh>
00036 # include <mln/math/sqrt.hh>
00037 # include <mln/algebra/vec.hh>
00038 # include <mln/value/ops.hh>
00039
00040
00041 namespace mln
00042 {
00043
00044
00045 namespace algebra
00046 {
00047 template <unsigned n, typename T> class vec;
00048 }
00049
00050
00051 namespace norm
00052 {
00053
00056 template <unsigned n, typename C>
00057 mln_sum_product(C,C) l2(const C (&vec)[n]);
00058
00059 template <unsigned n, typename C>
00060 mln_sum_product(C,C) l2(const algebra::vec<n,C>& vec);
00062
00065 template <unsigned n, typename C>
00066 mln_sum_product(C,C) sqr_l2(const C (&vec)[n]);
00067
00068 template <unsigned n, typename C>
00069 mln_sum_product(C,C) sqr_l2(const algebra::vec<n,C>& vec);
00071
00074 template <unsigned n, typename C>
00075 mln_sum_product(C,C) l2_distance(const C (&vec1)[n], const C (&vec2)[n]);
00076
00077 template <unsigned n, typename C>
00078 mln_sum_product(C,C) l2_distance(const algebra::vec<n,C>& vec1,
00079 const algebra::vec<n,C>& vec2);
00081
00082
00083 # ifndef MLN_INCLUDE_ONLY
00084
00085 namespace impl
00086 {
00087
00088 template <unsigned n, typename C, typename V>
00089 inline
00090 mln_sum_product(C,C)
00091 l2_(const V& vec)
00092 {
00093 typedef mln_sum_product(C,C) M;
00094 M m = 0;
00095 for (unsigned i = 0; i < n; ++i)
00096 {
00097 M sqr_v_i = static_cast<M>(mln::math::sqr(vec[i]));
00098 m = static_cast<M>(m + sqr_v_i);
00099 }
00100 return mln::math::sqrt(m);
00101 }
00102
00103 template <unsigned n, typename C, typename V>
00104 inline
00105 mln_sum_product(C,C)
00106 sqr_l2_(const V& vec)
00107 {
00108 mln_sum_product(C,C) m = 0;
00109 for (unsigned i = 0; i < n; ++i)
00110 m += mln::math::sqr(vec[i]);
00111 return m;
00112 }
00113
00114 template <unsigned n, typename C, typename V>
00115 inline
00116 mln_sum_product(C,C)
00117 l2_distance_(const V& vec1, const V& vec2)
00118 {
00119 typedef mln_sum_product(C,C) D;
00120 D d = 0;
00121 for (unsigned i = 0; i < n; ++i)
00122 {
00123 D sqr_v1_v2 = static_cast<D>(mln::math::sqr(vec1[i] - vec2[i]));
00124 d = static_cast<D>(d + sqr_v1_v2);
00125 }
00126 return mln::math::sqrt(d);
00127 }
00128
00129 }
00130
00131
00132
00133
00134
00135
00136 template <unsigned n, typename C>
00137 inline
00138 mln_sum_product(C,C)
00139 l2(const C (&vec)[n])
00140 {
00141 return impl::l2_<n, C>(vec);
00142 }
00143
00144 template <unsigned n, typename C>
00145 inline
00146 mln_sum_product(C,C)
00147 l2(const algebra::vec<n,C>& vec)
00148 {
00149 return impl::l2_<n, C>(vec);
00150 }
00151
00152
00153 template <unsigned n, typename C>
00154 inline
00155 mln_sum_product(C,C)
00156 sqr_l2(const C (&vec)[n])
00157 {
00158 return impl::sqr_l2_<n, C>(vec);
00159 }
00160
00161 template <unsigned n, typename C>
00162 inline
00163 mln_sum_product(C,C)
00164 sqr_l2(const algebra::vec<n,C>& vec)
00165 {
00166 return impl::sqr_l2_<n, C>(vec);
00167 }
00168
00169
00170 template <unsigned n, typename C>
00171 inline
00172 mln_sum_product(C,C)
00173 l2_distance(const C (&vec1)[n], const C (&vec2)[n])
00174 {
00175 return impl::l2_distance_<n, C>(vec1, vec2);
00176 }
00177
00178 template <unsigned n, typename C>
00179 inline
00180 mln_sum_product(C,C)
00181 l2_distance(const algebra::vec<n,C>& vec1, const algebra::vec<n,C>& vec2)
00182 {
00183 return impl::l2_distance_<n, C>(vec1, vec2);
00184 }
00185
00186 # endif // ! MLN_INCLUDE_ONLY
00187
00188 }
00189
00190 }
00191
00192
00193 #endif // ! MLN_NORM_L2_HH