3897: Add fun p2p fold functions.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add fun p2p fold functions. * sandbox/theo/experimental/histo_image.cc: Copy as... * mln/fun/p2p/fold.hh: ...this new file. Keep only fold stuff. Revamp. * mln/fun/p2p/all.hh: Update. * tests/fun/p2p/fold.cc: New. * tests/fun/p2p/Makefile.am: Update. * mln/fun/p2p/translation.hh: Layout. mln/fun/p2p/all.hh | 7 mln/fun/p2p/fold.hh | 451 +++++++++------------------------------------ mln/fun/p2p/translation.hh | 4 tests/fun/p2p/Makefile.am | 2 tests/fun/p2p/fold.cc | 77 +++++++ 5 files changed, 178 insertions(+), 363 deletions(-) Index: mln/fun/p2p/fold.hh --- mln/fun/p2p/fold.hh (revision 3895) +++ mln/fun/p2p/fold.hh (working copy) @@ -1,421 +1,156 @@ -#include <mln/value/int_u8.hh> -#include <mln/value/int_s.hh> -#include <mln/value/rgb8.hh> -#include <mln/trait/value/comp.hh> - -#include <mln/core/alias/box1d.hh> -#include <mln/core/image/image1d.hh> -#include <mln/core/image/image3d.hh> +// Copyright (C) 2009 EPITA Research and Development Laboratory +// (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_FUN_P2P_FOLD_HH +# define MLN_FUN_P2P_FOLD_HH + +/// \file mln/fun/p2p/fold.hh +/// +/// FIXME: Doc! #include <mln/core/concept/function.hh> -#include <mln/metal/ands.hh> - +# include <mln/core/site_set/box.hh> namespace mln { - - // -------------------------------------------------- fun - - namespace fun { - // . . . . . . . . . . . . . . . v2v:: value <-> index - - // This is a revamp of mln/value/internal/convert.hh. It remains - // to be updated with Fred's new function writting. Then we'll be - // able to make it better, i.e., to handle the different cases - // properly. Precisely a case for scalars with low quantization - // (with a special encoding like quantized float, or not), a case - // for vectors with low quant, etc. - - namespace v2v + namespace p2p { - // value -> index - - template <typename T> - struct index_of_value : Function_v2v< index_of_value<T> >, - private metal::bool_<(mln_dim(T) == 1)>::check_t - { - typedef unsigned result; - unsigned operator()(const T& v) const - { - return unsigned( int(v) - int(mln_min(T)) ); + // Forward declaration. + namespace internal { + template <typename F, typename P> + P do_fold(const P& p, const box<P>& b); } - }; - template <> - struct index_of_value<bool> : Function_v2v< index_of_value<bool> > - { - typedef unsigned result; - unsigned operator()(bool b) const - { - return b ? 1u : 0u; - } - }; - template <typename T> - unsigned - meta_index_of_value(const T& v) + template < typename P, + int dir_0 = -1, + int dir_1 = -1, + int dir_2 = -1 > + struct fold : Function_p2p< fold<P,dir_0,dir_1,dir_2> > { - index_of_value<T> f; - return f(v); - } + fold(); + fold(const box<P>& b); - // index -> value - - template <typename T> - struct value_at_index : Function_v2v< value_at_index<T> >, - private metal::bool_<(mln_dim(T) == 1)>::check_t - { - typedef T result; - T operator()(unsigned i) const - { - return T( int(mln_min(T)) + int(i) ); - } - }; + typedef P result; + P operator()(const P& p) const; - template <> - struct value_at_index<bool> : Function_v2v< value_at_index<bool> > - { - typedef bool result; - bool operator()(unsigned i) const - { - mln_precondition(i < 2); - return i == 1u ? true : false; - } + box<P> b; }; - // . . . . . . . . . . . . . . . value -> point n-D - +# ifndef MLN_INCLUDE_ONLY namespace internal { - // FIXME: It can be straightforwardly written using - // fun::ith_component. Yet there is no test file for this - // function. - - template <unsigned dim, typename T> - struct point_from_value; - - template <typename T> - struct point_from_value< 1, T > - { - static point1d run(const T& v) - { - return point1d(meta_index_of_value(v)); - } - }; - - template <typename T> - struct point_from_value< 2, T > - { - static point2d run(const T& v) - { - return point2d(meta_index_of_value(v[0]), - meta_index_of_value(v[1])); - } - }; - - template <typename T> - struct point_from_value< 3, T > - { - static point3d run(const T& v) - { - return point3d(meta_index_of_value(v[0]), - meta_index_of_value(v[1]), - meta_index_of_value(v[2])); - } - }; - - } // mln::fun::v2v::internal - - - template <typename T> - struct point_from_value : Function_v2v< point_from_value<T> > - { - enum { d = mln_dim(T) }; - typedef mln_regular_grid_from_dim(d) G; - typedef mln::point<G, def::coord> result; - - result operator()(const T& v) const - { - return internal::point_from_value<d,T>::run(v); - } - - index_of_value<T> f_; - }; - - template <typename T> - mln_result(point_from_value<T>) - meta_point_from_value(const T& v) - { - point_from_value<T> f; - return f(v); - } - - } // mln::fun::v2v + template <int dim, typename F> + struct do_fold_helper; - - - - // . . . . . . . . . . . . . . . p2p::fold* - - namespace p2p + template <typename P> + struct do_fold_helper< 1, fold< P, -1, -1, -1 > > { - - struct fold1d : Function_p2p< fold1d > - { - typedef point1d result; - result operator()(const point1d& p) const + static P run(const P& p, const box<P>& b) { - point1d tmp(p[0] % b.len(0)); + P tmp(p[0] % b.len(0)); return tmp; } - box1d b; }; - template <bool along_0, bool along_1> - struct fold2d : Function_p2p< fold2d<along_0,along_1> > + template <typename P, int dir_0, int dir_1> + struct do_fold_helper< 2, fold< P, dir_0, dir_1, -1 > > { - typedef point2d result; - result operator()(const point2d& p) const + static P run(const P& p, const box<P>& b) { - point2d tmp(along_0 ? p[0] % b.len(0) : p[0], - along_1 ? p[1] % b.len(1) : p[1]); + P tmp(dir_0 ? p[0] % b.len(0) : p[0], + dir_1 ? p[1] % b.len(1) : p[1]); return tmp; } - box2d b; }; - template <bool along_0, bool along_1, bool along_2> - struct fold3d : Function_p2p< fold3d<along_0,along_1,along_2> > + template <typename P, int dir_0, int dir_1, int dir_2> + struct do_fold_helper< 3, fold< P, dir_0, dir_1, dir_2 > > { - typedef point3d result; - result operator()(const point3d& p) const + static P run(const P& p, const box<P>& b) { - point3d tmp(along_0 ? p[0] % b.len(0) : p[0], - along_1 ? p[1] % b.len(1) : p[1], - along_2 ? p[2] % b.len(2) : p[2]); + P tmp(dir_0 ? p[0] % b.len(0) : p[0], + dir_1 ? p[1] % b.len(1) : p[1], + dir_2 ? p[2] % b.len(2) : p[2]); return tmp; } - box3d b; }; - } // mln::fun::p2p - - - } // mln::fun - - - // -------------------------------------------------- value - - - namespace value + template <typename F, typename P> + inline + P + do_fold(const F&, const P& p, const box<P>& b) { - - template <unsigned n, int inf, int sup> - struct circular - { - }; - - - namespace internal - { - template <typename T> - struct is_circular_helper : metal::false_ - {}; - - template <unsigned n, int inf, int sup> - struct is_circular_helper< circular<n,inf,sup> > : metal::true_ - {}; - - template <typename T> - struct is_circular : is_circular_helper<T>::eval - { - }; - - } // mln::value::internal - - } // mln::value - - - namespace trait - { - - template <unsigned n, int inf, int sup> - struct value_< mln::value::circular<n, inf, sup> > - { - enum { - dim = 1, - nbits = n, - card = mln_value_card_from_(n) - }; - // ... - }; - - } // end of namespace trait - - - // -------------------------------------------------- histo - - - namespace histo - { - - namespace internal - { - - template <int dim, typename T> - struct image_from_value_helper - { - }; - - // dim = 1 - - template <typename T, bool is_c> - struct image_from_value_helper_1; - - template <typename T> - struct image_from_value_helper_1< T, false > - { - typedef image1d<unsigned> ret; - - static ret get_image() - { - ret tmp(mln_card(T)); - return tmp; + return do_fold_helper<P::dim, F>::run(p, b); } - }; - template <typename T> - struct image_from_value_helper_1< T, true > - { - typedef void ret; - }; + } // end of namespace mln::fun::p2p::internal - template <typename T> - struct image_from_value_helper< 1, T > - { - enum { is_c = value::internal::is_circular<T>::value }; - typedef image_from_value_helper_1< T, is_c > helper; - }; - // dim = 3 + // fold. - template <typename C0, bool is_c0, - typename C1, bool is_c1, - typename C2, bool is_c2, - typename T> - struct image_from_value_helper_3; - - template <typename C0, typename C1, typename C2, - typename T> - struct image_from_value_helper_3< C0, false, - C1, false, - C2, false, - T > - { - typedef image3d<unsigned> ret; - static ret get_image() + template <typename P, int dir_0, int dir_1, int dir_2> + inline + fold<P,dir_0,dir_1,dir_2>::fold() { - ret tmp(mln_card(C0), mln_card(C1), mln_card(C2)); - return tmp; } - }; - - template <typename C0, typename C1, typename C2, - typename T> - struct image_from_value_helper_3< C0, true, - C1, false, - C2, false, - T > - { - typedef void ret; - }; - - template <typename T> - struct image_from_value_helper< 3, T > - { - typedef mln_trait_value_comp(T, 0) C0; - typedef mln_trait_value_comp(T, 1) C1; - typedef mln_trait_value_comp(T, 2) C2; - typedef image_from_value_helper_3< C0, value::internal::is_circular<C0>::value, - C1, value::internal::is_circular<C1>::value, - C2, value::internal::is_circular<C2>::value, - T > helper; - }; - template <typename T> - struct image_from_value_ // Entry point. + template <typename P, int dir_0, int dir_1, int dir_2> + inline + fold<P,dir_0,dir_1,dir_2>::fold(const box<P>& b) + : b(b) { - typedef typename image_from_value_helper<mln_dim(T), T>::helper helper; - }; - - - } // mln::histo::internal + } - template <typename T> - struct image_from_value : internal::image_from_value_<T>::helper + template <typename P, int dir_0, int dir_1, int dir_2> + inline + P + fold<P,dir_0,dir_1,dir_2>::operator()(const P& p) const { - }; - - - - // First code: the result of this function shall be replaced by - // an histo::image<T> where T is mln_value(I). As a consequence, - // we will not have to call meta_point_from_value... - - template <typename I> - typename image_from_value<mln_value(I)>::ret - compute_image(const Image<I>& input_) - { - const I& input = exact(input_); - typedef image_from_value<mln_value(I)> helper; - typename helper::ret h = helper::get_image(); - - mln_piter(I) p(input.domain()); - for_all(p) - ++h( fun::v2v::meta_point_from_value(input(p)) ); - - return h; + return internal::do_fold(*this, p, b); } - } // mln::histo +# endif // ! MLN_INCLUDE_ONLY -} // mln + } // end of namespace mln::fun::p2p + } // end of namespace mln::fun -int main() -{ - using namespace mln; +} // end of namespace mln - { - typedef bool T; - std::cout << histo::image_from_value<T>::get_image().domain() << std::endl; - } - { - typedef unsigned char T; - std::cout << histo::image_from_value<T>::get_image().domain() << std::endl; - } - - { - typedef value::int_s<3> T; - std::cout << histo::image_from_value<T>::get_image().domain() << std::endl; - } - - { - typedef value::rgb8 T; - std::cout << histo::image_from_value<T>::get_image().domain() << std::endl; - } - - { - // typedef value::circular<8,0,9> T; - } -} +#endif // ! MLN_FUN_P2P_FOLD_HH Property changes on: mln/fun/p2p/fold.hh ___________________________________________________________________ Added: svn:mergeinfo Index: mln/fun/p2p/all.hh --- mln/fun/p2p/all.hh (revision 3896) +++ mln/fun/p2p/all.hh (working copy) @@ -1,4 +1,5 @@ -// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -30,7 +31,8 @@ /// \file mln/fun/p2p/all.hh /// -/// File that includes all functions from grid point to grid point. +/// \brief File that includes all functions from grid point to grid +/// point. namespace mln @@ -46,6 +48,7 @@ } +# include <mln/fun/p2p/fold.hh> # include <mln/fun/p2p/mirror.hh> # include <mln/fun/p2p/translation.hh> Index: mln/fun/p2p/translation.hh --- mln/fun/p2p/translation.hh (revision 3896) +++ mln/fun/p2p/translation.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2008 EPITA Research and Development Laboratory +// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory // (LRDE) // // This file is part of the Olena Library. This library is free @@ -113,5 +113,3 @@ #endif // ! MLN_FUN_P2P_TRANSLATION_HH - - Index: tests/fun/p2p/fold.cc --- tests/fun/p2p/fold.cc (revision 0) +++ tests/fun/p2p/fold.cc (revision 0) @@ -0,0 +1,77 @@ +// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/// \file tests/fun/p2p/fold.cc +/// +/// Tests on mln::fun::p2p::fold. + +#include <mln/core/alias/box1d.hh> +#include <mln/core/alias/box2d.hh> +#include <mln/core/alias/box3d.hh> +#include <mln/fun/p2p/fold.hh> + + +int main() +{ + using namespace mln; + + { + box1d b(2); + fun::p2p::fold<point1d> f(b); + point1d p(2); + mln_assertion( f(p) == point1d(0) ); + } + { + box2d b(2, 3); + point2d p(2,3); + + fun::p2p::fold<point2d,1,1> f_11(b); + mln_assertion( f_11(p) == point2d(0,0) ); + + fun::p2p::fold<point2d,0,1> f_01(b); + mln_assertion( f_01(p) == point2d(2,0) ); + + fun::p2p::fold<point2d,1,0> f_10(b); + mln_assertion( f_10(p) == point2d(0,3) ); + } + { + box3d b(2, 3, 4); + point3d p(2, 3, 4); + + fun::p2p::fold<point3d,1,1,1> f_111(b); + mln_assertion( f_111(p) == point3d(0,0,0) ); + + fun::p2p::fold<point3d,0,0,1> f_001(b); + mln_assertion( f_001(p) == point3d(2,3,0) ); + + fun::p2p::fold<point3d,0,1,0> f_010(b); + mln_assertion( f_010(p) == point3d(2,0,4) ); + + fun::p2p::fold<point3d,1,0,0> f_100(b); + mln_assertion( f_100(p) == point3d(0,3,4) ); + } +} Index: tests/fun/p2p/Makefile.am --- tests/fun/p2p/Makefile.am (revision 3896) +++ tests/fun/p2p/Makefile.am (working copy) @@ -3,8 +3,10 @@ include $(top_srcdir)/milena/tests/tests.mk check_PROGRAMS = \ + fold \ translation +fold_SOURCES = fold.cc translation_SOURCES = translation.cc TESTS = $(check_PROGRAMS)
participants (1)
-
Thierry Geraud