1419: Refactor the L-infinity-norm, and test it.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Refactor the L-infinity-norm, and test it. * mln/norm/infty.hh: Rename as... * mln/norm/linfty.hh: ...this. Use type `mln_value_sum(C)' instead of `float' to handle L-infinity-norm values. (mln::norm::impl::linfty_, mln::norm::impl::linfty_distance_): New. Use to factor the implementations of... (mln::norm::linfty, mln::norm::linfty_distance): ...these functions. (linfty_distance(const metal::vec<n,C>&, const metal::vec<n,C>&)): New function. * tests/linfty.cc: New test. * tests/Makefile.am (check_PROGRAMS): Add linfty. (linfty_SOURCES): New. mln/norm/linfty.hh | 104 ++++++++++++++++++++++++++++++++++++----------------- tests/Makefile.am | 2 + tests/linfty.cc | 34 ++++++++--------- 3 files changed, 91 insertions(+), 49 deletions(-) Index: mln/norm/linfty.hh --- mln/norm/linfty.hh (revision 1417) +++ mln/norm/linfty.hh (working copy) @@ -25,15 +25,17 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_NORM_INFTY_HH -# define MLN_NORM_INFTY_HH +#ifndef MLN_NORM_LINFTY_HH +# define MLN_NORM_LINFTY_HH -/*! \file mln/norm/infty.hh +/*! \file mln/norm/linfty.hh * - * \brief Define some infinity-norm related routines. + * \brief Define some L-infinity-norm related routines. + * \see http://mathworld.wolfram.com/L-Infinity-Norm.html for more + * information. */ -# include <cmath> +# include <mln/math/abs.hh> # include <mln/metal/vec.hh> @@ -43,56 +45,94 @@ namespace norm { - /// Infinity-norm of a vector \p v (being a C static array). + /// L-infinity-norm of a vector \a vec. + /// \{ template <unsigned n, typename C> - C infty(const C (&v)[n]); + C linfty(const C (&vec)[n]); - /// Infinity-norm of a vector \p v (being a metal::vec). template <unsigned n, typename C> - C infty(const metal::vec<n,C>& v); + C linfty(const metal::vec<n,C>& vec); + /// \} - /// Infinity-norm distance between vectors \p v1 and \p v2. + /// L-infinity-norm distance between vectors \a vec1 and \a vec2. + /// \{ template <unsigned n, typename C> - C infty_distance(const C (&v1)[n], const C (&v2)[n]); + C linfty_distance(const C (&vec1)[n], const C (&vec2)[n]); + + template <unsigned n, typename C> + C linfty_distance(const metal::vec<n,C>& vec1, + const metal::vec<n,C>& vec2); + /// \} # ifndef MLN_INCLUDE_ONLY - template <unsigned n, typename C> - C infty(const C (&v)[n]) + namespace impl { - C c = 0; - for (unsigned i = 0; i < n; ++i) - if (std::abs(v[i]) > c) - c = std::abs(v[i]); - return c; - } - template <unsigned n, typename C> - C infty(const metal::vec<n,C>& v) + template <unsigned n, typename C, typename V> + C linfty_(const V& vec) { - // FIXME: Add a ctor to metal::vec... - C c = 0; + C m = 0; for (unsigned i = 0; i < n; ++i) - if (std::abs(v[i]) > c) - c = std::abs(v[i]); - return c; + { + // Compute the maximal component absolute value of the + // vector. + C mc = mln::math::abs(vec[i]); + if (mc > m) + m = mc; + } + return m; } - template <unsigned n, typename C> - C infty_distance(const C (&v1)[n], const C (&v2)[n]) + template <unsigned n, typename C, typename V> + C linfty_distance_(const V& vec1, const V& vec2) { C d = 0; for (unsigned i = 0; i < n; ++i) { - C dd = v2[i] > v1[i] ? v2[i] - v1[i] : v1[i] - v2[i]; - if (dd > d) - d = dd; + // Compute the maximal absolute value of the distance + // between components of the same index. + C dc = mln::math::abs(vec1[i] - vec2[i]); + if (dc > d) + d = dc; } return d; } + } // end of namespace mln::norm::impl + + + /*----------. + | Facades. | + `----------*/ + + template <unsigned n, typename C> + C linfty(const C (&vec)[n]) + { + return impl::linfty_<n, C>(vec); + } + + template <unsigned n, typename C> + C linfty(const metal::vec<n,C>& vec) + { + return impl::linfty_<n, C>(vec); + } + + template <unsigned n, typename C> + C linfty_distance(const C (&vec1)[n], const C (&vec2)[n]) + { + return impl::linfty_distance_<n, C>(vec1, vec2); + } + + template <unsigned n, typename C> + C linfty_distance(const metal::vec<n,C>& vec1, + const metal::vec<n,C>& vec2) + { + return impl::linfty_distance_<n, C>(vec1, vec2); + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::norm @@ -100,4 +140,4 @@ } // end of namespace mln -#endif // ! MLN_NORM_INFTY_HH +#endif // ! MLN_NORM_LINFTY_HH Index: tests/linfty.cc --- tests/linfty.cc (revision 1417) +++ tests/linfty.cc (working copy) @@ -25,50 +25,50 @@ // reasons why the executable file might be covered by the GNU General // Public License. -/// \file tests/l2.hh -/// \brief Test the L2-norm. +/// \file tests/linfty.hh +/// \brief Test the L-infinity-norm. #include <cmath> #include <cassert> #include <mln/metal/vec.hh> #include <mln/math/abs.hh> -#include <mln/norm/l2.hh> +#include <mln/norm/linfty.hh> // FIXME: We should have a almost_equal function somewhere in Milena. static const float epsilon = 0.0001; using mln::metal::vec; -using mln::norm::l2; +using mln::norm::linfty; template <typename V> -void check_l2 (const V& vec1, const V& vec2) +void check_linfty (const V& vec1, const V& vec2) { - assert (mln::math::abs(mln::norm::l2(vec1) - mln::norm::l2(vec2)) + assert (mln::math::abs(mln::norm::linfty(vec1) - mln::norm::linfty(vec2)) < epsilon); } template <typename V, typename S> -void check_l2_distance (const V& vec1, const V& vec2, const S& ref_val) +void check_linfty_distance (const V& vec1, const V& vec2, const S& ref_val) { - assert (mln::math::abs(mln::norm::l2_distance(vec1, vec2) - ref_val) + assert (mln::math::abs(mln::norm::linfty_distance(vec1, vec2) - ref_val) < epsilon); } int main () { - vec<3, int> t; t.set (2, -2, 3); + vec<3, int> t; t.set (2, -2, 4); vec<3, int> u; u.set (4, 1, 0); - float d = std::sqrt((4 - 2) * (4 - 2) + - (1 + 2) * (1 + 2) + - (0 - 3) * (0 - 3)); + float d = std::max(std::abs(4 - 2), + std::max(std::abs(1 + 2), + std::abs(0 - 4))); - check_l2(t, u); - check_l2_distance (t, u, d); + check_linfty(t, u); + check_linfty_distance (t, u, d); - int v[] = {2, -2, 3}; + int v[] = {2, -2, 4}; int w[] = {4, 1, 0}; - check_l2(v, w); - check_l2_distance (v, w, d); + check_linfty(v, w); + check_linfty_distance (v, w, d); } Index: tests/Makefile.am --- tests/Makefile.am (revision 1419) +++ tests/Makefile.am (working copy) @@ -86,6 +86,7 @@ \ l1 \ l2 \ + linfty \ labeling_algo \ labeling_estimate \ labeling_foreground \ @@ -274,6 +275,7 @@ l1_SOURCES = l1.cc l2_SOURCES = l2.cc +linfty_SOURCES = linfty.cc labeling_algo_SOURCES = labeling_algo.cc labeling_estimate_SOURCES = labeling_estimate.cc labeling_foreground_SOURCES = labeling_foreground.cc
participants (1)
-
Roland Levillain