
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2009-03-08 Frederic Bour <bour@lrde.epita.fr> Add work on meta functions and thru morpher. * sandbox/fred/fun/abs.hh: New. * sandbox/fred/fun/cos.hh: New. * sandbox/fred/fun/fun.cc: New. Some tests don't pass, see FIXMEs (operator==(rgb::red_t,int) ?) * sandbox/fred/fun/inc.hh: New. * sandbox/fred/fun/meta_function.hh: New. * sandbox/fred/fun/norm.hh: New. * sandbox/fred/fun/red.hh: New. * sandbox/fred/fun/thru.cc: New. * sandbox/fred/fun/thru_morpher.hh: New. Constness of thru_image has to be corrected. * sandbox/fred/fun/unary.hh: New. * sandbox/fred/fun: New. --- abs.hh | 40 ++++++++ cos.hh | 46 ++++++++++ fun.cc | 103 ++++++++++++++++++++++ inc.hh | 43 +++++++++ meta_function.hh | 132 +++++++++++++++++++++++++++++ norm.hh | 96 +++++++++++++++++++++ red.hh | 44 +++++++++ thru.cc | 30 ++++++ thru_morpher.hh | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ unary.hh | 115 +++++++++++++++++++++++++ 10 files changed, 898 insertions(+) Index: trunk/milena/sandbox/fred/fun/cos.hh =================================================================== --- trunk/milena/sandbox/fred/fun/cos.hh (revision 0) +++ trunk/milena/sandbox/fred/fun/cos.hh (revision 3498) @@ -0,0 +1,46 @@ +#ifndef COS_HH +# define COS_HH + +# include "unary.hh" +# include <mln/value/concept/floating.hh> +# include <mln/math/acos.hh> +# include <mln/math/cos.hh> + +namespace mln +{ + // COS, bijective + namespace fun + { + template <typename T> + struct cos : unary<cos, T> {}; + } + + namespace trait + { + template <typename T> + struct set_unary_<fun::cos, mln::value::Floating, T> + { + typedef set_unary_ ret; + typedef T result; + typedef T argument; + typedef T& lvalue; + + static result read(const argument& x) + { + return math::cos(x); + } + + static void write(lvalue l, const result& x) + { + l = math::acos(x); + } + }; + } + + namespace meta + { + typedef unary<fun::cos> cos; + } +} + +#endif /* ! COS_HH */ \ No newline at end of file Index: trunk/milena/sandbox/fred/fun/abs.hh =================================================================== --- trunk/milena/sandbox/fred/fun/abs.hh (revision 0) +++ trunk/milena/sandbox/fred/fun/abs.hh (revision 3498) @@ -0,0 +1,40 @@ +#ifndef ABS_HH +# define ABS_HH + +# include "unary.hh" +# include <mln/value/concept/scalar.hh> +# include <mln/math/abs.hh> + +namespace mln +{ + // ABS, pure + namespace fun + { + template <typename T> + struct abs : unary<abs, T> {}; + } + + namespace trait + { + template <typename T> + struct set_unary_<fun::abs, mln::value::Scalar, T> + { + typedef set_unary_ ret; + typedef T result; + typedef T argument; + typedef T& lvalue; + + static result read(const argument& x) + { + return math::abs(x); + } + }; + } + + namespace meta + { + typedef unary<fun::abs> abs; + } +} + +#endif /* ! ABS_HH */ \ No newline at end of file Index: trunk/milena/sandbox/fred/fun/thru.cc =================================================================== --- trunk/milena/sandbox/fred/fun/thru.cc (revision 0) +++ trunk/milena/sandbox/fred/fun/thru.cc (revision 3498) @@ -0,0 +1,30 @@ +// Meta functions test +#include "cos.hh" +#include "thru_morpher.hh" + +#include <mln/core/image/image2d.hh> +#include <mln/value/int_u8.hh> +#include <mln/debug/all.hh> +#include <iostream> + +#define dbg_print(val) std::cout << #val << "\n\t -> \t" << (val) << std::endl +int main() +{ + using namespace mln; + + meta::cos cos; + typedef image2d<float> I; + I ima(5, 5); + + image2d<value::int_u8> tmp(5, 5); + debug::iota(tmp); + data::fill_with_image(ima, tmp); + + debug::println(ima); + debug::println(thru(meta::cos(), ima)); + + thru_image<I, mln::fun::cos<float> > ima2 = thru(meta::cos(), ima); + data::fill_with_image(ima2, (pw::value(tmp) - pw::cst(13.0f)) / pw::cst(12.0f) | tmp.domain()); + + debug::println(ima); +} \ No newline at end of file Index: trunk/milena/sandbox/fred/fun/inc.hh =================================================================== --- trunk/milena/sandbox/fred/fun/inc.hh (revision 0) +++ trunk/milena/sandbox/fred/fun/inc.hh (revision 3498) @@ -0,0 +1,43 @@ +#ifndef INC_HH +# define INC_HH + +# include "unary.hh" + +namespace mln +{ + // INC, bijective + namespace fun + { + template <typename T> + struct inc : unary<inc, T> {}; + } + + namespace trait + { + template <typename T> + struct set_unary_<fun::inc, mln::value::Scalar, T> + { + typedef set_unary_ ret; + typedef T result; + typedef T argument; + typedef T& lvalue; + + static result read(const argument& x) + { + return x + 1; + } + + static void write(lvalue l, const result& r) + { + l = r - 1; + } + }; + } + + namespace meta + { + typedef unary<fun::inc> inc; + } +} + +#endif /* ! INC_HH */ \ No newline at end of file Index: trunk/milena/sandbox/fred/fun/red.hh =================================================================== --- trunk/milena/sandbox/fred/fun/red.hh (revision 0) +++ trunk/milena/sandbox/fred/fun/red.hh (revision 3498) @@ -0,0 +1,44 @@ +#ifndef RED_HH +# define RED_HH + +# include "unary.hh" +# include <mln/value/rgb.hh> + +namespace mln +{ + // RED, assignable + namespace fun + { + template <typename T> + struct red : unary<red, T> {}; + } + + namespace trait + { + template <unsigned n> + struct set_precise_unary_<fun::red, mln::value::rgb<n> > + { + typedef set_precise_unary_ ret; + typedef mln::value::rgb<n> argument; + typedef typename argument::red_t result; + typedef argument& lvalue; + + static result read(const argument& x) + { + return x.red(); + } + + static void write(lvalue l, const result& r) + { + l.red() = r; + } + }; + } + + namespace meta + { + typedef unary<fun::red> red; + } +} + +#endif /* ! RED_HH */ \ No newline at end of file Index: trunk/milena/sandbox/fred/fun/meta_function.hh =================================================================== --- trunk/milena/sandbox/fred/fun/meta_function.hh (revision 0) +++ trunk/milena/sandbox/fred/fun/meta_function.hh (revision 3498) @@ -0,0 +1,132 @@ +// Copyright (C) 2007, 2008 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 F 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_CORE_CONCEPT_META_FUNCTION_HH +# define MLN_CORE_CONCEPT_META_FUNCTION_HH + +/// \file mln/core/concept/meta_function.hh +/// +/// Definition of the concept of mln::Meta_Function. + +# include <mln/core/concept/object.hh> +# include <mln/core/concept/function.hh> + + +# define mln_fun_with(F, T) \ +typename F::template with< T >::ret + +# define mln_fun_with_(F, T) \ +F::with< T >::ret + + +# define mln_fun_result(F, T) \ +typename F::template with< T >::ret::result + + +# define mln_fun_result_(F, T) \ +F::with< T >::ret::result + + + +namespace mln +{ + + // Fwd decl. + template <typename E> struct Meta_Function; + + // Meta_Function category flag type. + template <> + struct Meta_Function<void> + { + typedef Object<void> super; + }; + + + /*! \brief Base class for implementation of meta functions. + * + * The parameter \a E is the exact type. + * + * \see mln::doc::Meta_Function for a complete documentation of + * this class contents. + */ + template <typename E> + struct Meta_Function : public Object<E> + { + typedef Meta_Function<void> category; + protected: + Meta_Function(); + }; + + + namespace fun + { + + // To be specialized when some state (attributes) have to be transfered + // from the meta-function to the function. + // Warning: the first argument has to be an object with the exact type. + template <typename M, typename T> + mln_fun_with(M, T) + unmeta(const M&, T); + + template <typename M, typename T> + void + unmeta(const Meta_Function<M>&, T); // Safety. + + } // end of namespace mln::fun + + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + inline + Meta_Function<E>::Meta_Function() + { + // FIXME: Check "with" on E. + } + + namespace fun + { + + template <typename M, typename T> + inline + mln_fun_with(M, T) + unmeta(const M&, T) + { + mlc_is_a(M, Meta_Function)::check(); + mln_fun_with(M, T) a; + return a; + } + + } // end of namespace mln::fun + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_META_FUNCTION_HH Index: trunk/milena/sandbox/fred/fun/norm.hh =================================================================== --- trunk/milena/sandbox/fred/fun/norm.hh (revision 0) +++ trunk/milena/sandbox/fred/fun/norm.hh (revision 3498) @@ -0,0 +1,96 @@ +#ifndef NORM_HH +# define NORM_HH + +# include "unary.hh" +# include <mln/norm/all.hh> + +namespace mln +{ + // NORMS, reversible + namespace fun + { + namespace norm + { + template <typename T> + struct l1 : unary<l1, T> {}; + + template <typename T> + struct l2 : unary<l2, T> {}; + + template <typename T> + struct linfty : unary<linfty, T> {}; + } + } + + namespace trait + { + template <unsigned n, typename T> + struct set_precise_unary_<fun::norm::l1, mln::algebra::vec<n, T> > + { + typedef set_precise_unary_ ret; + typedef mln::algebra::vec<n, T> argument; + typedef argument& lvalue; + typedef mln_sum_product(argument,argument) result; + + static result read(const argument& x) + { + return mln::norm::l1(x); + } + + static void write(lvalue l, const result& x) + { + l = l / read(l) * x; + } + }; + + template <unsigned n, typename T> + struct set_precise_unary_<fun::norm::l2, mln::algebra::vec<n, T> > + { + typedef set_precise_unary_ ret; + typedef mln::algebra::vec<n, T> argument; + typedef argument& lvalue; + typedef mln_sum_product(argument,argument) result; + + static result read(const argument& x) + { + return mln::norm::l2(x); + } + + static void write(lvalue l, const result& x) + { + l = l / read(l) * x; + } + }; + + template <unsigned n, typename T> + struct set_precise_unary_<fun::norm::linfty, mln::algebra::vec<n, T> > + { + typedef set_precise_unary_ ret; + typedef mln::algebra::vec<n, T> argument; + typedef argument& lvalue; + typedef mln_sum_product(argument,argument) result; + + static result read(const argument& x) + { + return mln::norm::linfty(x); + } + + static void write(lvalue l, const result& x) + { + l = l / read(l) * x; + } + }; + } + + namespace meta + { + namespace norm + { + typedef unary<fun::norm::l1> l1; + typedef unary<fun::norm::l2> l2; + typedef unary<fun::norm::linfty> linfty; + } + } +} + +#endif /* ! NORM_HH */ \ No newline at end of file Index: trunk/milena/sandbox/fred/fun/fun.cc =================================================================== --- trunk/milena/sandbox/fred/fun/fun.cc (revision 0) +++ trunk/milena/sandbox/fred/fun/fun.cc (revision 3498) @@ -0,0 +1,103 @@ +// Meta functions test +#include "abs.hh" +#include "cos.hh" +#include "inc.hh" +#include "norm.hh" +#include "red.hh" + +#include <iostream> + +#define dbg_print(val) std::cout << #val << "\n\t -> \t" << (val) << std::endl +int main() +{ + mln::meta::abs abs; + mln::meta::cos cos; + mln::meta::inc inc; + mln::meta::red red; + + mln::meta::norm::l1 l1; + mln::meta::norm::l2 l2; + mln::meta::norm::linfty linfty; + + std::cout << "Read only tests." << std::endl; + std::cout << "----------------" << std::endl; + + // ABS + mln_invariant(abs(-1) == 1); + dbg_print(abs(-1)); + dbg_print(abs(-3.1415926535)); + + // INC + mln_invariant(inc(-1) == 0); + dbg_print(inc(-1)); + dbg_print(inc(-3.1415926535)); + + // COS + mln_invariant(cos(0.) == 1.); + dbg_print(cos(0.)); + dbg_print(cos(mln::math::acos(0.5))); + + // RED + mln_invariant(red(mln::value::rgb8(8,13,21)) == 8); + dbg_print(red(mln::value::rgb8(8,13,21))); + + // NORM + mln::algebra::vec<3, double> v; + v[0] = 1; + v[1] = -1; + v[2] = 0; + dbg_print(v); + dbg_print(l1(v)); + dbg_print(l2(v)); + dbg_print(linfty(v)); + + std::cout << "Read/Write tests." << std::endl; + std::cout << "-----------------" << std::endl; + + // INC + { + int x; + dbg_print(inc(x) = 1); + mln_invariant(inc(x) == 1); + dbg_print(inc(x)); + dbg_print(x); + } + + // COS + { + double x; + dbg_print(cos(x) = 1.); + mln_invariant(cos(x) == 1.); + dbg_print(x); + } + + // RED + { + mln::value::rgb8 rgb(8,13,21); + dbg_print(rgb); + dbg_print(red(rgb) = 0); +// FIXME: Doesn't compile! mln_invariant(red(rgb) == 0); + dbg_print(rgb); + } + + // NORM + { + dbg_print(v); + dbg_print(l1(v) = 1.0); + dbg_print(l1(v)); + dbg_print(v); +// mln_invariant(l1(v) == 1.0); FIXME: check with epsilon + + dbg_print(l2(v) = 1.0); + dbg_print(l2(v)); + dbg_print(v); +// mln_invariant(l2(v) == 1.0); + + dbg_print(linfty(v) = 1.0); + dbg_print(linfty(v)); + dbg_print(v); +// mln_invariant(linfty(v) == 1.0); + } + + std::cout << "All invariants passed." << std::endl; +} \ No newline at end of file Index: trunk/milena/sandbox/fred/fun/thru_morpher.hh =================================================================== --- trunk/milena/sandbox/fred/fun/thru_morpher.hh (revision 0) +++ trunk/milena/sandbox/fred/fun/thru_morpher.hh (revision 3498) @@ -0,0 +1,249 @@ +// Copyright (C) 2007, 2008 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 THRU_HH +# define THRU_HH + +# include <mln/core/internal/image_value_morpher.hh> +# include "meta_function.hh" + +// FIXME: constness of thru_image + +namespace mln +{ + + // Forward declaration. + template <typename I, typename F> struct thru_image; + + + namespace internal + { + + /// Data structure for \c mln::thru_image<I>. + template <typename I, typename F> + struct data< thru_image<I, F> > + { + data(I& ima, const F& f); + + I ima_; + // FIXME: value or pointer or whatever ? + F f_; + }; + + } // end of namespace mln::internal + + + namespace trait + { + + template <typename I, typename F> + struct image_< thru_image<I, F> > : image_< I > // Same as I except... + { + // ...these changes. + typedef trait::image::category::value_morpher category; + typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest. + typedef trait::image::value_access::computed value_access; + }; + + } // end of namespace mln::trait + + + + // FIXME: Doc! + + template <typename I, typename F> + class thru_image : public internal::image_value_morpher< I, typename F::result, thru_image<I,F> > + { + public: + + /// Skeleton. + typedef thru_image<tag::image_<I>, F> skeleton; + + /// Point_Site associated type. + typedef mln_psite(I) psite; + + /// Value associated type. + typedef typename F::result value; + + /// Type returned by the read-write pixel value operator. + typedef typename F::lresult lvalue; + + /// Return type of read-only access. + typedef typename F::result rvalue; + + thru_image(); + thru_image(I& ima); + thru_image(I& ima, const F& f); + + // Initialize an empty image. + void init_(I& ima, const F& f); + + rvalue operator()(const mln_psite(I)& p) const; + + lvalue operator()(const mln_psite(I)& p); + + /// Const promotion via conversion. + operator thru_image<const I, F>() const; + }; + + template <typename I, typename F> + thru_image<I, F> thru(const mln::Function<F>& f, + Image<I>& ima); + + template <typename I, typename F> + thru_image<const I, F> thru(const mln::Function<F>& f, + const Image<I>& ima); + + template <typename I, typename M> + thru_image<I, mln_fun_with(M, mln_value(I))> + thru(const mln::Meta_Function<M>& f, Image<I>& ima); + + template <typename I, typename M> + thru_image<const I, mln_fun_with(M, mln_value(I))> + thru(const mln::Meta_Function<M>& f, const Image<I>& ima); + +# ifndef MLN_INCLUDE_ONLY + + // internal::data< thru_image<I,S> > + + namespace internal + { + + template <typename I, typename F> + inline + data< thru_image<I, F> >::data(I& ima, const F& f) + : ima_(ima), + f_(f) + { + } + + } // end of namespace mln::internal + + // thru_image<I> + + template <typename I, typename F> + inline + thru_image<I, F>::thru_image() + { + } + + template <typename I, typename F> + inline + thru_image<I, F>::thru_image(I& ima, const F& f) + { + mln_precondition(ima.is_valid()); + init_(ima, f); + } + + template <typename I, typename F> + inline + thru_image<I, F>::thru_image(I& ima) + { + mln_precondition(ima.is_valid()); + init_(ima, mln_value(I)()); + } + + template <typename I, typename F> + inline + void + thru_image<I, F>::init_(I& ima, const F& f) + { + mln_precondition(! this->is_valid()); + mln_precondition(ima.is_valid()); + this->data_ = new internal::data< thru_image<I, F> >(ima, f); + } + + template <typename I, typename F> + inline + typename thru_image<I, F>::rvalue + thru_image<I, F>::operator()(const mln_psite(I)& p) const + { + mln_precondition(this->is_valid()); + return this->data_->f_(this->data_->ima_(p)); + } + + template <typename I, typename F> + inline + typename thru_image<I, F>::lvalue + thru_image<I, F>::operator()(const mln_psite(I)& p) + { + mln_precondition(this->is_valid()); + return this->data_->f_(this->data_->ima_(p)); + } + + template <typename I, typename F> + inline + thru_image<I, F>::operator thru_image<const I, F>() const + { + thru_image<const I, F> tmp(this->data_->ima_, this->data_->default_value_); + return tmp; + } + + // thru + template <typename I, typename F> + thru_image<I, F> thru(const mln::Function<F>& f, + Image<I>& ima) + { + thru_image<I, F> tmp(exact(ima), exact(f)); + return tmp; + } + + template <typename I, typename F> + thru_image<const I, F> thru(const mln::Function<F>& f, + const Image<I>& ima) + { + thru_image<const I, F> tmp(exact(ima), exact(f)); + return tmp; + } + + template <typename I, typename M> + thru_image<I, mln_fun_with(M, mln_value(I))> + thru(const mln::Meta_Function<M>& f, Image<I>& ima) + { + typedef mln_fun_with(M, mln_value(I)) F; + thru_image<I, F> tmp(exact(ima), F()); + + return tmp; + } + + template <typename I, typename M> + thru_image<const I, mln_fun_with(M, mln_value(I))> + thru(const mln::Meta_Function<M>& f, const Image<I>& ima) + { + typedef mln_fun_with(M, mln_value(I)) F; + thru_image<const I, F> tmp(exact(ima), F()); + + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! THRU_HH Index: trunk/milena/sandbox/fred/fun/unary.hh =================================================================== --- trunk/milena/sandbox/fred/fun/unary.hh (revision 0) +++ trunk/milena/sandbox/fred/fun/unary.hh (revision 3498) @@ -0,0 +1,115 @@ +#ifndef UNARY_HH +# define UNARY_HH + +# include <mln/trait/solve.hh> +# include <mln/fun/essential.hh> +# include <mln/fun/internal/resolve.hh> +# include "meta_function.hh" + +namespace mln +{ + // UNARY + namespace fun + { + namespace internal + { + template <typename Impl> + struct unary_modifier + { + typedef typename Impl::result result; + typedef typename Impl::argument argument; + typedef typename Impl::lvalue lvalue; + typedef unary_modifier lresult; + + // FIXME: argument or lvalue? ~~~ + unary_modifier(argument& x) + : x_(&x) + { + } + + result to_result() const + { + return Impl::read(*x_); + }; + + operator result() const + { + return to_result(); + }; + + const result& operator = (const result& r) const + { + Impl::write(*x_, r); + return r; + } + + private: + argument *x_; + }; + } + + template <template <class> class Fun, typename T> + struct unary : mln::Function_v2v< Fun<T> > + { + // FIXME: mln_fun_internal_resolve? Fun<T> is not defined at this point... + // so mln_is_a(Fun<T>, Function) won't work. + typedef typename mln::trait::solve_unary< Fun, T >::ret impl; + + typedef typename impl::result result; + typedef typename impl::argument argument; + typedef typename impl::lvalue lvalue; + typedef internal::unary_modifier<impl> lresult; + + result operator () (const argument& value) const + { + return impl::read(value); + } + + lresult operator () (argument& value) const + { + return lresult(value); + } + + void set(lvalue l, const result& r) const + { + impl::write(l, r); + } + }; + } + + namespace meta + { + template <template <class> class F> + struct unary : mln::Meta_Function< unary<F> > + { + template <typename T> + typename F<T>::result operator()(const T& v) const + { + F<T> tmp; + return tmp(v); + } + + template <typename T> + typename F<T>::lresult operator()(T& v) const + { + F<T> tmp; + return tmp(v); + } + + template <typename T> + struct with + { + typedef F<T> ret; + }; + }; + } + +} + +template <typename Impl> +std::ostream& operator << (std::ostream& o, const mln::fun::internal::unary_modifier<Impl>& m) +{ + return o << m.to_result(); +} + +#endif /* ! UNARY_HH */ \ No newline at end of file