cleanup-2008 2505: Add multiple-size windows and dual neighborhoods.

https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add multiple-size windows and dual neighborhoods. * tests/make: New. * tests/make/dual_neighb.cc: New. * tests/make/Makefile.am: New. * tests/Makefile.am: Update. * mln/core/concept/window.hh (todo): New. * mln/make/dual_neighb.hh: New. * mln/make/double_neighb2d.hh: Fix dox. (todo): New. * mln/README: Remove; obsolete file contents. * mln/win/multiple.hh: Remove non-activate code. (W): New static checks. Copy to... * mln/win/multiple_size.hh: ...this new file. (size_around): Activate. (multiple): Rename as... (multiple_size): ...this new class. (size_): Replace this attribute by... (size_): ...this new method. (change_target): Remove; useless. (siae): Remove; obsolete. (set_window): Remove no more valid tests. * mln/win/all.hh: Update. mln/core/concept/window.hh | 2 mln/make/double_neighb2d.hh | 4 - mln/make/dual_neighb.hh | 94 ++++++++++++++++++++++++ mln/win/all.hh | 1 mln/win/multiple.hh | 33 ++------ mln/win/multiple_size.hh | 166 +++++++++++++++++++------------------------- tests/Makefile.am | 1 tests/make/Makefile.am | 10 ++ tests/make/dual_neighb.cc | 65 +++++++++++++++++ 9 files changed, 260 insertions(+), 116 deletions(-) Index: tests/make/dual_neighb.cc --- tests/make/dual_neighb.cc (revision 0) +++ tests/make/dual_neighb.cc (revision 0) @@ -0,0 +1,65 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory +// +// 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/make/dual_neighb.cc + * + * \brief Tests on mln::make::dual_neighb. + */ + +#include <mln/make/dual_neighb.hh> +#include <mln/core/alias/neighb2d.hh> +#include <mln/core/image/image2d.hh> + + + +template <typename I, typename N> +unsigned count(const I& ima, const N& nbh) +{ + mln_piter(I) p(ima.domain()); + mln_niter(N) n(nbh, p); + unsigned c = 0; + for_all(p) + for_all(n) + { std::cout << n << std::endl; ++c; } + return c; +} + + +int main() +{ + using namespace mln; + + image2d<bool> ima(1, 2, 1); + ima.at(0, 0) = true; + ima.at(0, 1) = false; + + mln_assertion( count(ima, make::dual_neighb(ima, c4(), c8())) + == c4().size() + c8().size() ); + + // We can observe that the neighboord is not restricted by the + // respective domains defined by ima(p) == false and true. +} Index: tests/make/Makefile.am --- tests/make/Makefile.am (revision 0) +++ tests/make/Makefile.am (revision 0) @@ -0,0 +1,10 @@ +## Process this file through Automake to create Makefile.in -*- Makefile -*- + +include $(top_srcdir)/milena/tests/tests.mk + +check_PROGRAMS = \ + dual_neighb + +dual_neighb_SOURCES = dual_neighb.cc + +TESTS = $(check_PROGRAMS) Index: tests/Makefile.am --- tests/Makefile.am (revision 2504) +++ tests/Makefile.am (working copy) @@ -25,6 +25,7 @@ linear \ literal \ logical \ + make \ math \ metal \ morpho \ Index: mln/core/concept/window.hh --- mln/core/concept/window.hh (revision 2504) +++ mln/core/concept/window.hh (working copy) @@ -32,6 +32,8 @@ * \brief Definition of the concept of mln::Window. * * \todo Operator== should test if the cmp is possible. + * + * \todo Add an is_valid() method. */ # include <mln/core/concept/object.hh> Index: mln/make/dual_neighb.hh --- mln/make/dual_neighb.hh (revision 0) +++ mln/make/dual_neighb.hh (revision 0) @@ -0,0 +1,94 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory +// +// 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_MAKE_DUAL_NEIGHB_HH +# define MLN_MAKE_DUAL_NEIGHB_HH + +/*! \file mln/make/dual_neighb.hh + * + * \brief Routine to create a dual neighborhood. + */ + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/pw/value.hh> +# include <mln/win/multiple_size.hh> +# include <mln/core/neighb.hh> + + +namespace mln +{ + + namespace make + { + + template <typename I, typename N> + neighb< win::multiple_size< mln_window(N), pw::value_<I> > > + dual_neighb(const Image<I>& ima, + const Neighborhood<N>& nbh_true, + const Neighborhood<N>& nbh_false); + + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename I, typename N> + inline + neighb< win::multiple_size< mln_window(N), pw::value_<I> > > + dual_neighb(const Image<I>& ima_, + const Neighborhood<N>& nbh_true_, + const Neighborhood<N>& nbh_false_) + { + trace::entering("make::dual_neighb"); + + mlc_is(mln_trait_image_kind(I), trait::image::kind::logic)::check(); + + const I& ima = exact(ima_); + const N& nbh_true = exact(nbh_true_); + const N& nbh_false = exact(nbh_false_); + mln_precondition(ima.has_data()); + + typedef win::multiple_size< mln_window(N), pw::value_<I> > W; + W win(pw::value(ima)); + win.set_window(false, nbh_false.win()); // 0 + win.set_window(true, nbh_true .win()); // 1 + + neighb<W> nbh(win); + + trace::exiting("make::dual_neighb"); + return nbh; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::make + +} // end of namespace mln + + +#endif // ! MLN_MAKE_DUAL_NEIGHB_HH Index: mln/make/double_neighb2d.hh --- mln/make/double_neighb2d.hh (revision 2504) +++ mln/make/double_neighb2d.hh (working copy) @@ -30,7 +30,9 @@ /*! \file mln/make/double_neighb2d.hh * - * \brief Routine to create a dual neighborhood. + * \brief Routine to create a double neighborhood. + * + * \todo Add overload with 'when_*' being Neighborhood<N>... */ # include <mln/convert/to.hh> Index: mln/win/multiple_size.hh --- mln/win/multiple_size.hh (revision 2504) +++ mln/win/multiple_size.hh (working copy) @@ -25,12 +25,12 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_WIN_MULTIPLE_HH -# define MLN_WIN_MULTIPLE_HH +#ifndef MLN_WIN_MULTIPLE_SIZE_HH +# define MLN_WIN_MULTIPLE_SIZE_HH -/*! \file mln/win/multiple.hh +/*! \file mln/win/multiple_size.hh * - * \brief Definition of a multiple window. + * \brief Definition of a multiple-size window. */ # include <mln/core/internal/window_base.hh> @@ -45,8 +45,8 @@ // Forward declarations. namespace win { - template <typename W, typename F> class multiple; - template <typename W, typename F> class multiple_qiter; + template <typename W, typename F> class multiple_size; + template <typename W, typename F> class multiple_size_qiter; } @@ -55,9 +55,9 @@ { template <typename W, typename F> - struct window_< win::multiple<W,F> > + struct window_< win::multiple_size<W,F> > { - typedef trait::window::size::fixed size; + typedef trait::window::size::unknown size; typedef trait::window::support::regular support; typedef trait::window::definition::n_ary definition; }; @@ -70,7 +70,14 @@ { template <typename W, typename F> - class multiple : public internal::window_base< mln_dpsite(W), multiple<W,F> > + class multiple_size + + : public internal::window_base< mln_dpsite(W), multiple_size<W,F> >, + + private metal::and_< mlc_is(mln_trait_window_size(W), + trait::window::size::fixed), + mlc_is(mln_trait_window_support(W), + trait::window::support::regular) >::check_t { public: @@ -78,17 +85,17 @@ typedef mln_psite(W) psite; typedef mln_site(W) site; - typedef multiple< window<dpsite>, F > regular; + typedef multiple_size< window<dpsite>, F > regular; - typedef multiple_qiter<W,F> fwd_qiter; - typedef multiple_qiter<W,F> bkd_qiter; - typedef multiple_qiter<W,F> qiter; + typedef multiple_size_qiter<W,F> fwd_qiter; + typedef multiple_size_qiter<W,F> bkd_qiter; + typedef multiple_size_qiter<W,F> qiter; typedef W element; - multiple(); + multiple_size(); - multiple(const F& f); + multiple_size(const F& f); bool is_empty() const; @@ -100,9 +107,7 @@ const F& function() const; - unsigned size() const; - -// unsigned size_around(const mln_psite(W)& p) const; + unsigned size_around(const mln_psite(W)& p) const; const mln_dpsite(W)& ith_dp_around(unsigned i, const mln_psite(W)& p) const; @@ -122,20 +127,18 @@ template <typename W, typename F> - class multiple_qiter - : public internal::site_relative_iterator_base< multiple<W,F>, - multiple_qiter<W,F> > + class multiple_size_qiter + : public internal::site_relative_iterator_base< multiple_size<W,F>, + multiple_size_qiter<W,F> > { - typedef multiple_qiter<W,F> self_; - typedef internal::site_relative_iterator_base< multiple<W,F>, self_ > super_; + typedef multiple_size_qiter<W,F> self_; + typedef internal::site_relative_iterator_base< multiple_size<W,F>, self_ > super_; public: - multiple_qiter(); + multiple_size_qiter(); template <typename P> - multiple_qiter(const multiple<W,F>& w, const P& c); - - void change_target(const multiple<W,F>& w); // Overridden to initialize size_. + multiple_size_qiter(const multiple_size<W,F>& w, const P& c); /// Test the iterator validity. bool is_valid_() const; @@ -154,26 +157,25 @@ private: unsigned i_; - unsigned size_; -// unsigned n_() const; + unsigned size_() const; }; # ifndef MLN_INCLUDE_ONLY - // win::multiple<W,F> + // win::multiple_size<W,F> template <typename W, typename F> inline - multiple<W,F>::multiple() + multiple_size<W,F>::multiple_size() : f_() { } template <typename W, typename F> inline - multiple<W,F>::multiple(const F& f) + multiple_size<W,F>::multiple_size(const F& f) : f_(f) { } @@ -181,7 +183,7 @@ template <typename W, typename F> inline bool - multiple<W,F>::is_empty() const + multiple_size<W,F>::is_empty() const { return win_.is_empty(); } @@ -189,18 +191,16 @@ template <typename W, typename F> inline void - multiple<W,F>::set_window(unsigned i, const W& win) + multiple_size<W,F>::set_window(unsigned i, const W& win) { mln_precondition(i == win_.nelements()); - if (i >= 1) - mln_precondition(win.size() == win_[0].size()); win_.append(win); } template <typename W, typename F> inline const W& - multiple<W,F>::window(unsigned i) const + multiple_size<W,F>::window(unsigned i) const { mln_precondition(i < win_.nelements()); return win_[i]; @@ -209,7 +209,7 @@ template <typename W, typename F> inline unsigned - multiple<W,F>::nwindows() const + multiple_size<W,F>::nwindows() const { return win_.nelements(); } @@ -217,27 +217,15 @@ template <typename W, typename F> inline const F& - multiple<W,F>::function() const + multiple_size<W,F>::function() const { return f_; } template <typename W, typename F> inline - unsigned - multiple<W,F>::size() const - { - mln_precondition(win_.nelements() >= 2); // Multiple cannot be just 1 element. - unsigned s = win_[0].size(); - for (unsigned i = 1; i < win_.nelements(); ++i) - mln_precondition(win_[i].size() == s); - return s; - } - - template <typename W, typename F> - inline bool - multiple<W,F>::is_centered() const + multiple_size<W,F>::is_centered() const { mln_precondition(win_.nelements() >= 1); for (unsigned i = 0; i < win_.nelements(); ++i) @@ -249,7 +237,7 @@ template <typename W, typename F> inline bool - multiple<W,F>::is_symmetric() const + multiple_size<W,F>::is_symmetric() const { mln_precondition(win_.nelements() >= 1); for (unsigned i = 0; i < win_.nelements(); ++i) @@ -258,11 +246,10 @@ return true; } - template <typename W, typename F> inline void - multiple<W,F>::sym() + multiple_size<W,F>::sym() { mln_precondition(win_.nelements() >= 1); for (unsigned i = 0; i < win_.nelements(); ++i) @@ -272,7 +259,7 @@ template <typename W, typename F> inline unsigned - multiple<W,F>::delta() const + multiple_size<W,F>::delta() const { mln_precondition(win_.nelements() >= 1); unsigned d = win_[0].delta(); @@ -285,74 +272,67 @@ return d; } -// template <typename W, typename F> -// inline -// unsigned -// multiple<W,F>::size_around(const mln_psite(W)& p) const -// { -// mln_precondition(f_(p) < win_.nelements()); -// return win_[f_(p)].size(); -// } + template <typename W, typename F> + inline + unsigned + multiple_size<W,F>::size_around(const mln_psite(W)& p) const + { + mln_precondition(win_.nelements() >= 2); + mln_precondition(f_(p) < win_.nelements()); + return win_[f_(p)].size(); + } template <typename W, typename F> inline const mln_dpsite(W)& - multiple<W,F>::ith_dp_around(unsigned i, const mln_psite(W)& p) const + multiple_size<W,F>::ith_dp_around(unsigned i, const mln_psite(W)& p) const { + mln_precondition(win_.nelements() >= 2); mln_precondition(f_(p) < win_.nelements()); mln_precondition(i < win_[f_(p)].size()); return win_[f_(p)].dp(i); } - // win::multiple_qiter<W,F> + // win::multiple_size_qiter<W,F> template <typename W, typename F> inline - multiple_qiter<W,F>::multiple_qiter() + multiple_size_qiter<W,F>::multiple_size_qiter() { } template <typename W, typename F> template <typename P> inline - multiple_qiter<W,F>::multiple_qiter(const multiple<W,F>& w, const P& c) + multiple_size_qiter<W,F>::multiple_size_qiter(const multiple_size<W,F>& w, const P& c) { this->center_at(c); // We have to first change the center so that 'invalidate' can // work when changing the target. - change_target(w); - } - - template <typename W, typename F> - inline - void - multiple_qiter<W,F>::change_target(const multiple<W,F>& w) - { - this->super_::change_target(w); - size_ = w.size(); + this->change_target(w); } template <typename W, typename F> inline bool - multiple_qiter<W,F>::is_valid_() const + multiple_size_qiter<W,F>::is_valid_() const { - return i_ < size_; + return i_ < size_(); } template <typename W, typename F> inline void - multiple_qiter<W,F>::invalidate_() + multiple_size_qiter<W,F>::invalidate_() { - i_ = size_; + i_ = size_(); } template <typename W, typename F> inline void - multiple_qiter<W,F>::do_start_() + multiple_size_qiter<W,F>::do_start_() { i_ = 0; } @@ -360,7 +340,7 @@ template <typename W, typename F> inline void - multiple_qiter<W,F>::do_next_() + multiple_size_qiter<W,F>::do_next_() { ++i_; } @@ -368,18 +348,18 @@ template <typename W, typename F> inline mln_psite(W) - multiple_qiter<W,F>::compute_p_() const + multiple_size_qiter<W,F>::compute_p_() const { return *this->c_ + this->s_->ith_dp_around(i_, *this->c_); } -// template <typename W, typename F> -// inline -// unsigned -// multiple_qiter<W,F>::size_() const -// { -// return this->s_->size_around(*this->c_); -// } + template <typename W, typename F> + inline + unsigned + multiple_size_qiter<W,F>::size_() const + { + return this->s_->size_around(*this->c_); + } # endif // ! MLN_INCLUDE_ONLY @@ -389,4 +369,4 @@ } // end of namespace mln -#endif // ! MLN_WIN_MULTIPLE_HH +#endif // ! MLN_WIN_MULTIPLE_SIZE_HH Index: mln/win/multiple.hh --- mln/win/multiple.hh (revision 2504) +++ mln/win/multiple.hh (working copy) @@ -31,6 +31,8 @@ /*! \file mln/win/multiple.hh * * \brief Definition of a multiple window. + * + * \todo Implementation of the bkd_qiter (see FIXME). */ # include <mln/core/internal/window_base.hh> @@ -70,7 +72,14 @@ { template <typename W, typename F> - class multiple : public internal::window_base< mln_dpsite(W), multiple<W,F> > + class multiple + + : public internal::window_base< mln_dpsite(W), multiple<W,F> >, + + private metal::and_< mlc_is(mln_trait_window_size(W), + trait::window::size::fixed), + mlc_is(mln_trait_window_support(W), + trait::window::support::regular) >::check_t { public: @@ -81,7 +90,7 @@ typedef multiple< window<dpsite>, F > regular; typedef multiple_qiter<W,F> fwd_qiter; - typedef multiple_qiter<W,F> bkd_qiter; + typedef /* FIXME: */ multiple_qiter<W,F> bkd_qiter; typedef multiple_qiter<W,F> qiter; typedef W element; @@ -102,8 +111,6 @@ unsigned size() const; -// unsigned size_around(const mln_psite(W)& p) const; - const mln_dpsite(W)& ith_dp_around(unsigned i, const mln_psite(W)& p) const; bool is_centered() const; @@ -155,7 +162,6 @@ private: unsigned i_; unsigned size_; -// unsigned n_() const; }; @@ -285,15 +291,6 @@ return d; } -// template <typename W, typename F> -// inline -// unsigned -// multiple<W,F>::size_around(const mln_psite(W)& p) const -// { -// mln_precondition(f_(p) < win_.nelements()); -// return win_[f_(p)].size(); -// } - template <typename W, typename F> inline const mln_dpsite(W)& @@ -373,14 +370,6 @@ return *this->c_ + this->s_->ith_dp_around(i_, *this->c_); } -// template <typename W, typename F> -// inline -// unsigned -// multiple_qiter<W,F>::size_() const -// { -// return this->s_->size_around(*this->c_); -// } - # endif // ! MLN_INCLUDE_ONLY Index: mln/win/all.hh --- mln/win/all.hh (revision 2504) +++ mln/win/all.hh (working copy) @@ -53,6 +53,7 @@ # include <mln/win/hline2d.hh> # include <mln/win/line.hh> # include <mln/win/multiple.hh> +# include <mln/win/multiple_size.hh> # include <mln/win/octagon2d.hh> # include <mln/win/rectangle2d.hh> # include <mln/win/segment1d.hh>
participants (1)
-
Thierry Geraud