r3340: Make leveling filter and mean accumulator clean

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox ChangeLog: 2009-02-10 Edwin Carlinet <carlinet@lrde.epita.fr> Make leveling filter and mean accumulator clean. * edwin/Makefile: Correct some errors. * edwin/accu_trait.hh: Correct some errors. * fred/leveling.cc: Main file to test leveling. * fred/leveling_filter.hh: The leveling filter. * fred/mean.hh: Accumulator to perform mean calculus. --- edwin/Makefile | 10 - edwin/accu_trait.hh | 2 fred/leveling.cc | 375 ------------------------------------------------ fred/leveling_filter.hh | 375 ++++++++++++++++++++++++++++++++++++++++++++++++ fred/mean.hh | 66 +++++--- 5 files changed, 431 insertions(+), 397 deletions(-) Index: trunk/milena/sandbox/fred/leveling_filter.hh =================================================================== --- trunk/milena/sandbox/fred/leveling_filter.hh (revision 0) +++ trunk/milena/sandbox/fred/leveling_filter.hh (revision 3340) @@ -0,0 +1,375 @@ +// Copyright (C) 2007, 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 +// 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_CANVAS_MORPHO_LEVELING_FILTER_HH +# define MLN_CANVAS_MORPHO_LEVELING_FILTER_HH + +/// \file mln/canvas/morpho/leveling_filter.hh +/// +/// Apply leveling connected filter to images. +/// + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/core/concept/accumulator.hh> + +# include <mln/data/fill.hh> +# include <mln/extension/adjust_fill.hh> + +# include <mln/level/sort_psites.hh> +# include <mln/level/sort_offsets.hh> + + + + +/*# include <mln/data/fill.hh> +# include <mln/literal/zero.hh> +# include <mln/convert/to_upper_window.hh> +# include <mln/extension/adjust_fill.hh> +# include <mln/util/pix.hh> +*/ + +namespace mln { + namespace canvas { + namespace morpho { + + // Facade Fwd Declaration + template < typename I, typename N, typename A, typename L> + mln_concrete(I) + leveling_filter(const Image<I>& input, const Neighborhood<N>& nbh, + const Accumulator<A>& a, L lambda, bool increasing); + + +# ifndef MLN_INCLUDE_ONLY + + // Implementations. + + namespace impl { + + namespace generic { + + // Generic Version + + template <typename I> + static inline + mln_psite(I) + find_root(I& parent, const mln_psite(I) & x) + { + if (parent(x) == x) + return x; + else + return parent(x) = find_root(parent, parent(x)); + } + + template < typename I, typename N, typename S, typename A, typename L> + mln_concrete(I) + leveling_filter(const Image<I>& input_, const Neighborhood<N>& nbh_, + const Site_Set<S>& s_, const Accumulator<A>& a_, L lambda) + { + trace::entering("canvas::morpho::impl::generic::leveling_filter"); + // FIXME: Test?! + + const I& input = exact(input_); + const N& nbh = exact(nbh_); + const S& s = exact(s_); + (void)a_; // To avoid warning at compilation + + mln_concrete(I) output; + initialize(output, input); + + // Local type. + typedef mln_psite(I) P; + + + // Auxiliary data. + mln_ch_value(I, bool) deja_vu; + mln_ch_value(I, bool) activity; + mln_ch_value(I, P) parent; + mln_ch_value(I, A) data; + + // Initialization. + { + initialize(deja_vu, input); + mln::data::fill(deja_vu, false); + initialize(activity, input); + mln::data::fill(activity, true); + initialize(parent, input); + initialize(data, input); + //a.init(); // init required. + } + + // First pass. + { + mln_fwd_piter(S) p(s); // s required. + mln_niter(N) n(nbh, p); + + for_all(p) + { + // Make set. + { + parent(p) = p; + data(p).take_as_init(make::pix(input, p)); + } + + for_all(n) + if (input.domain().has(n) && deja_vu(n)) + { + //do_union(n, p); + P r = find_root(parent, n); + if (r != p) + { + if (input(r) == input(p) || (activity(r) && (data(r) < lambda))) // Equiv(r, p) + // Either a flat zone or the component of r is still growing. + { + /* FIXME: Same remark as above concerning the + initialization of data(p); instead of + + data(p).take(data(r)); + + we should (or could) have + + unite_data(p, r); + + so as to keep the generic aspect of this canvas + (as long as the set of acceptable types for the + template parameter A is not bound). */ + data(p).take(data(r)); + parent(r) = p; + if (activity(r) == false) + activity(p) = false; + } + else + { + activity(p) = false; + } + } + } + deja_vu(p) = true; + } + } + + // Second pass. + { + mln_bkd_piter(S) p(s); + for_all(p) + if (parent(p) == p) // p is root. + output(p) = input(p); + else + output(p) = output(parent(p)); + } + + trace::exiting("canvas::morpho::impl::generic::leveling_filter"); + return output; + } + + } // end of namespace mln::canvas::morpho::impl::generic + + + // Fastest version. + + + template <typename I> + inline + unsigned + find_root_fastest(I& parent, unsigned x) + { + if (parent.element(x) == x) + return x; + else + return parent.element(x) = find_root_fastest(parent, parent.element(x)); + } + + template < typename I, typename N, typename A, typename L> + mln_concrete(I) + leveling_filter_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_, + const util::array<unsigned>& s, const Accumulator<A>& a_, L lambda) + { + trace::entering("canvas::morpho::impl::leveling_fastest"); + + // FIXME: Tests? + + const I& input = exact(input_); + const N& nbh = exact(nbh_); + + mln_concrete(I) output; + initialize(output, input); + + // Local type. + typedef mln_psite(I) P; + + // Auxiliary data. + mln_ch_value(I, bool) deja_vu; + mln_ch_value(I, bool) activity; + mln_ch_value(I, unsigned) parent; + mln_ch_value(I, A) data; + + // Initialization. + { + initialize(deja_vu, input); + mln::data::fill(deja_vu, false); + initialize(activity, input); + mln::data::fill(activity, true); + initialize(parent, input); + mln::data::fill(parent, 0); + initialize(data, input); + } + + util::array<int> dp = offsets_wrt(input, nbh); + const unsigned n_nbhs = dp.nelements(); + const unsigned n_points = s.nelements(); + + // First pass. + { + + for (unsigned i = 0; i < n_points; ++i) + { + unsigned p = s[i]; // An offset. + + // Make set. + parent.element(p) = p; + data.element(p).take_as_init(input.element(p)); + + for (unsigned j = 0; j < n_nbhs; ++j) + { + unsigned n = p + dp[j]; + if (!deja_vu.element(n)) + continue; + + unsigned r = find_root_fastest(parent, n); + if (r != p) + { + if (input.element(r) == input.element(p) + || (activity.element(r) + && (data.element(r) < lambda))) + { + data.element(p).take(data.element(r)); + parent.element(r) = p; + if (activity.element(r) == false) + activity.element(p) = false; + } + else + activity.element(p) = false; + } + } + + deja_vu.element(p) = true; + } + + } + + // Second pass. + { + for (int i = n_points - 1; i >= 0 ; --i) + { + unsigned p = s[i]; + if (parent.element(p) == p) // p is root. + output.element(p) = input.element(p); + else + output.element(p) = output.element(parent.element(p)); + } + } + + trace::exiting("canvas::morpho::impl::leveling_fastest"); + return output; + } + + } // end of namespace mln::canvas::morpho::impl + + // Dispatch. + namespace internal + { + + // Leveling + template < typename I, typename N, typename A, typename L> + mln_concrete(I) + leveling_filter_dispatch(metal::false_, + const Image<I>& input, const Neighborhood<N>& nbh, + const Accumulator<A>& a, L lambda, bool increasing) + { + p_array < mln_psite(I) > s = + increasing ? + level::sort_psites_increasing(input) : + level::sort_psites_decreasing(input); + return impl::generic::leveling_filter(input, nbh, s, a, lambda); + } + + template < typename I, typename N, typename A, typename L> + mln_concrete(I) + leveling_filter_dispatch(metal::true_, + const Image<I>& input, const Neighborhood<N>& nbh, + const Accumulator<A>& a, L lambda, bool increasing) + { + util::array<unsigned> s = + increasing ? + level::sort_offsets_increasing(input) : + level::sort_offsets_decreasing(input); + return impl::leveling_filter_fastest(input, nbh, s, a, lambda); + } + + template < typename I, typename N, typename A, typename L> + inline + mln_concrete(I) + leveling_filter_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, + const Accumulator<A>& a, L lambda, bool increasing) + { + enum + { + test = mlc_equal(mln_trait_image_speed(I), + trait::image::speed::fastest)::value + && mlc_equal(mln_trait_accumulator_when_pix(A), + trait::accumulator::when_pix::use_v)::value + && mln_is_simple_neighborhood(N)::value + }; + return leveling_filter_dispatch(metal::bool_<test>(), + input, nbh, a, lambda, increasing); + } + + } // end of namespace mln::canvas::morpho::internal + + +# endif // ! MLN_INCLUDE_ONLY + + + // Facade. + + template < typename I, typename N, typename A, typename L> + inline + mln_concrete(I) + leveling_filter(const Image<I>& input, const Neighborhood<N>& nbh, + const Accumulator<A>& a, L lambda, bool increasing) + { + //FIXME: Do we need to check input validity ? + return internal::leveling_filter_dispatch(input, nbh, a, lambda, increasing); + } + + } // end of namespace mln::canvas::morpho + } // end of namespace mln::canvas +} // end of namespace mln + + +#endif // ! MLN_CANVAS_MORPHO_LEVELING_FILTER_HH Index: trunk/milena/sandbox/fred/leveling.cc =================================================================== --- trunk/milena/sandbox/fred/leveling.cc (revision 3339) +++ trunk/milena/sandbox/fred/leveling.cc (revision 3340) @@ -1,372 +1,11 @@ -// Copyright (C) 2007, 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 -// 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_CANVAS_LEVELING_HH -# define MLN_CANVAS_LEVELING_HH - -/// \file mln/canvas/leveling.hh -/// -/// Apply leveling connected filter to images. -/// -/// \todo Debug, add input validity check. - -# include <mln/core/concept/image.hh> -# include <mln/data/fill.hh> -# include <mln/literal/zero.hh> -# include <mln/convert/to_upper_window.hh> -# include <mln/extension/adjust_fill.hh> -# include <mln/level/sort_psites.hh> -# include <mln/level/sort_offsets.hh> -# include <mln/core/alias/neighb2d.hh> -# include <mln/util/pix.hh> - -# include "accu_trait.hh" -# include "mean.hh" - -namespace mln -{ - - namespace canvas - { - - template < typename I, typename N, typename A, typename L> - mln_concrete(I) - leveling(const Image<I>& input, const Neighborhood<N>& nbh, - const Accumulator<A>& a, L lambda, bool increasing); - -# ifndef MLN_INCLUDE_ONLY - - // Implementations. - - namespace impl - { - - namespace generic - { - - template <typename I> - static inline - mln_psite(I) - find_root(I& parent, const mln_psite(I) & x) - { - if (parent(x) == x) - return x; - else - return parent(x) = find_root(parent, parent(x)); - } - - template < typename I, typename N, typename S, typename A, typename L> - mln_concrete(I) - leveling(const Image<I>& input_, const Neighborhood<N>& nbh_, - const Site_Set<S>& s_, const Accumulator<A>& a_, L lambda) - { - trace::entering("canvas::impl::generic::leveling"); - - // FIXME: Test?! - - const I& input = exact(input_); - const N& nbh = exact(nbh_); - const S& s = exact(s_); - //const A& a = exact(a_); - (void)a_; - // Local type. - typedef mln_psite(I) P; - - mln_concrete(I) output; - initialize(output, input); - - // Auxiliary data. - mln_ch_value(I, bool) deja_vu; - mln_ch_value(I, bool) activity; - mln_ch_value(I, P) parent; - mln_ch_value(I, A) data; - - // Initialization. - { - initialize(deja_vu, input); - mln::data::fill(deja_vu, false); - initialize(activity, input); - mln::data::fill(activity, true); - initialize(parent, input); - initialize(data, input); -// a.init(); // init required. - } - - // First pass. - { - mln_fwd_piter(S) p(s); // s required. - mln_niter(N) n(nbh, p); - - for_all(p) - { - // Make set. - { - parent(p) = p; - data(p).take_as_init(make::pix(input, p)); - } - - for_all(n) - if (input.domain().has(n) && deja_vu(n)) - { - //do_union(n, p); - P r = find_root(parent, n); - if (r != p) - { - if (input(r) == input(p) || (activity(r) && (data(r) < lambda))) // Equiv(r, p) - // Either a flat zone or the component of r is still growing. - { - /* FIXME: Same remark as above concerning the - initialization of data(p); instead of - - data(p).take(data(r)); - - we should (or could) have - - unite_data(p, r); - - so as to keep the generic aspect of this canvas - (as long as the set of acceptable types for the - template parameter A is not bound). */ - data(p).take(data(r)); - parent(r) = p; - if (activity(r) == false) - activity(p) = false; - } - else - { - activity(p) = false; - } - } - } - deja_vu(p) = true; - } - } - - // Second pass. - { - mln_bkd_piter(S) p(s); - for_all(p) - if (parent(p) == p) // p is root. - output(p) = input(p); - else - output(p) = output(parent(p)); - } - - trace::exiting("canvas::morpho::impl::generic::leveling"); - return output; - } - - } // end of namespace mln::canvas::impl::generic - - // Fastest version. - template <typename I> - inline - unsigned - find_root_fastest(I& parent, unsigned x) - { - if (parent.element(x) == x) - return x; - else - return parent.element(x) = find_root_fastest(parent, parent.element(x)); - } - - template < typename I, typename N, typename A, typename L> - mln_concrete(I) - leveling_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_, - const util::array<unsigned>& s, const Accumulator<A>& a_, L lambda) - { - trace::entering("canvas::impl::leveling_fastest"); - - // FIXME: Tests? - const I& input = exact(input_); - const N& nbh = exact(nbh_); - - mln_concrete(I) output; - initialize(output, input); - - // Local type. - typedef mln_psite(I) P; - - // Auxiliary data. - mln_ch_value(I, bool) deja_vu; - mln_ch_value(I, bool) activity; - mln_ch_value(I, unsigned) parent; - mln_ch_value(I, A) data; - - // Initialization. - { - initialize(deja_vu, input); - mln::data::fill(deja_vu, false); - initialize(activity, input); - mln::data::fill(activity, true); - initialize(parent, input); - mln::data::fill(parent, 0); - initialize(data, input); - } - - util::array<int> dp = offsets_wrt(input, nbh); - const unsigned n_nbhs = dp.nelements(); - const unsigned n_points = s.nelements(); - - // First pass. - { - - for (unsigned i = 0; i < n_points; ++i) - { - unsigned p = s[i]; // An offset. - - // Make set. - parent.element(p) = p; - data.element(p).take_as_init(input.element(p)); - - for (unsigned j = 0; j < n_nbhs; ++j) - { - unsigned n = p + dp[j]; - if (!deja_vu.element(n)) - continue; - - unsigned r = find_root_fastest(parent, n); - if (r != p) - { - if (input.element(r) == input.element(p) - || (activity.element(r) - && (data.element(r) < lambda))) - { - data.element(p).take(data.element(r)); - parent.element(r) = p; - if (activity.element(r) == false) - activity.element(p) = false; - } - else - activity.element(p) = false; - } - } - - deja_vu.element(p) = true; - } - - } - - // Second pass. - { - for (int i = n_points - 1; i >= 0 ; --i) - { - unsigned p = s[i]; - if (parent.element(p) == p) // p is root. - output.element(p) = input.element(p); - else - output.element(p) = output.element(parent.element(p)); - } - } - - trace::exiting("canvas::impl::leveling_fastest"); - return output; - } - - } // end of namespace mln::canvas::impl - - // Dispatch. - namespace internal - { - - // Leveling - template < typename I, typename N, typename A, typename L> - mln_concrete(I) - leveling_dispatch(metal::false_, - const Image<I>& input, const Neighborhood<N>& nbh, - const Accumulator<A>& a, L lambda, bool increasing) - { - p_array < mln_psite(I) > s = - increasing ? - level::sort_psites_increasing(input) : - level::sort_psites_decreasing(input); - return impl::generic::leveling(input, nbh, s, a, lambda); - } - - template < typename I, typename N, typename A, typename L> - mln_concrete(I) - leveling_dispatch(metal::true_, - const Image<I>& input, const Neighborhood<N>& nbh, - const Accumulator<A>& a, L lambda, bool increasing) - { - util::array<unsigned> s = - increasing ? - level::sort_offsets_increasing(input) : - level::sort_offsets_decreasing(input); - return impl::leveling_fastest(input, nbh, s, a, lambda); - } - - template < typename I, typename N, typename A, typename L> - inline - mln_concrete(I) - leveling_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, - const Accumulator<A>& a, L lambda, bool increasing) - { - enum - { - test = mlc_equal(mln_trait_image_speed(I), - trait::image::speed::fastest)::value - && mlc_equal(mln_trait_accu_when_pix(A), - trait::accu::when_pix::use_only_v)::value - && mln_is_simple_neighborhood(N)::value - }; - return leveling_dispatch(metal::bool_<test>(), - input, nbh, a, lambda, increasing); - } - - - } // end of namespace mln::canvas::internal - - // Facades. - template < typename I, typename N, typename A, typename L> - inline - mln_concrete(I) - leveling(const Image<I>& input, const Neighborhood<N>& nbh, - const Accumulator<A>& a, L lambda, bool increasing) - { -// FIXME: Do we need to check input validity ? - return internal::leveling_dispatch(input, nbh, a, lambda, increasing); - } - -# endif // ! MLN_INCLUDE_ONLY - - } // end of namespace mln::canvas - -} // end of namespace mln - - -#endif // ! MLN_CANVAS_LEVELING_HH #include <mln/core/image/image2d.hh> #include <mln/io/pgm/all.hh> #include <mln/util/timer.hh> -#include "../edwin/card.hh" +#include <mln/core/alias/neighb2d.hh> +#include "mean.hh" +#include "leveling_filter.hh" int main(int argc, char** argv) { @@ -380,27 +19,27 @@ float elapsed; mln::util::timer chrono; - mln::morpho::accu::mean<I> c; + mln::morpho::attribute::mean<I> c; int lambda = atoi(argv[1]); mln::io::pgm::load(lena, "../../img/lena.pgm"); I out; chrono.start(); - out = mln::canvas::leveling(lena, c4(), c, lambda, true); + out = mln::canvas::morpho::leveling_filter(lena, c4(), c, lambda, true); elapsed = chrono.stop(); std::cout << "(auto) " << elapsed << "s" << std::endl; mln::io::pgm::save(out, "auto.pgm"); chrono.start(); - out = mln::canvas::internal::leveling_dispatch(mln::metal::true_(), lena, c4(), c, lambda, true); + out = mln::canvas::morpho::internal::leveling_filter_dispatch(mln::metal::true_(), lena, c4(), c, lambda, true); elapsed = chrono.stop(); std::cout << "(fast) " << elapsed << "s" << std::endl; mln::io::pgm::save(out, "fast.pgm"); chrono.start(); - out = mln::canvas::internal::leveling_dispatch(mln::metal::false_(), lena, c4(), c, lambda, true); + out = mln::canvas::morpho::internal::leveling_filter_dispatch(mln::metal::false_(), lena, c4(), c, lambda, true); elapsed = chrono.stop(); std::cout << "(slow) " << elapsed << "s" << std::endl; Index: trunk/milena/sandbox/fred/mean.hh =================================================================== --- trunk/milena/sandbox/fred/mean.hh (revision 3339) +++ trunk/milena/sandbox/fred/mean.hh (revision 3340) @@ -26,32 +26,51 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_MORPHO_ACCU_MEAN_HH -# define MLN_MORPHO_ACCU_MEAN_HH +#ifndef MLN_MORPHO_ATTRIBUTE_MEAN_HH +# define MLN_MORPHO_ATTRIBUTE_MEAN_HH -/// \file mln/morpho/accu/mean.hh +/// \file mln/morpho/attribute/mean.hh /// -/// Mean leveling accumulator. +/// Define an accumulator that computes the mean of a +/// component. /// -/// \todo Debug. -# include <mln/core/macros.hh> -# include <mln/core/concept/accumulator.hh> -# include <mln/util/pix.hh> +# include <mln/accu/internal/base.hh> # include <mln/accu/mean.hh> - -# include "accu_trait.hh" +# include <mln/util/pix.hh> namespace mln { + // Forward declaration. + namespace morpho { + namespace attribute { + template <typename I> class mean; + } + } - namespace accu { + // Traits + namespace trait { template <typename I> + struct accumulator_< morpho::attribute::mean<I> > + { + typedef accumulator::has_untake::no has_untake; + typedef accumulator::has_set_value::no has_set_value; + typedef accumulator::has_stop::no has_stop; + typedef accumulator::when_pix::use_v when_pix; + }; + } + + + namespace morpho { + + namespace attribute { + /// Morphological (i.e. for pixel and pixel values) accumulator calculating mean. /// Valid for leveling algorithm. /// FIXME: is inclusion polyphormism really appliable ? + template <typename I> class mean: public mln::accu::internal::base<typename mln::accu::mean<mln_value(I)>::result, mean<I> > { public: @@ -61,20 +80,29 @@ mean(); + + /// Manipulators. + /// \{ void init(); void take(const mln_value(I)& v); void take(const argument& t); void take(const mean<I>& m); + /// \} + /// Get the value of the accumulator. result to_result() const; + /// Check whether this accu is able to return a result. bool is_valid() const; - private: + protected: + /// The mean mln::accu::mean<mln_value(I)> accu_; }; + + # ifndef MLN_INCLUDE_ONLY template <typename I> @@ -135,21 +163,10 @@ # endif // ! MLN_INCLUDE_ONLY - } // end of namespace mln::morpho::accu + } // end of namespace mln::morpho::attribute } // end of namespace mln::morpho - namespace trait { - - template <typename I> - struct accu_< morpho::accu::mean<I> > : - public undefined_accu_ < morpho::accu::mean<I> > - { - typedef accu::when_pix::use_only_v when_pix; - }; - - } // end of namespace mln::trait - } // end of namespace mln -#endif /* ! MLN_MORPHO_ACCU_MEAN_HH */ \ No newline at end of file +#endif /* ! MLN_MORPHO_ATTRIBUTE_MEAN_HH */ Index: trunk/milena/sandbox/edwin/accu_trait.hh =================================================================== --- trunk/milena/sandbox/edwin/accu_trait.hh (revision 3339) +++ trunk/milena/sandbox/edwin/accu_trait.hh (revision 3340) @@ -23,7 +23,7 @@ namespace morpho { namespace accu { - template <typename T> + template <typename I> struct card; } } Index: trunk/milena/sandbox/edwin/Makefile =================================================================== --- trunk/milena/sandbox/edwin/Makefile (revision 3339) +++ trunk/milena/sandbox/edwin/Makefile (revision 3340) @@ -1,10 +1,11 @@ -TARGET=accu -OBJS=accu.o +TARGET=algebraic +SRC=algebraic.cc +OBJS=${SRC:.cc=.o} OLENADIR=../../.. MILENADIR=$(OLENADIR)/milena -CXXFLAGS=-I$(MILENADIR) -I./ -DNDEBUG -O2 -ffast-math +CXXFLAGS=-I$(MILENADIR) -I./ -DNDEBUG -O3 -ffast-math CXX=g++ LD=g++ LDFLAGS= @@ -14,3 +15,6 @@ %.o: %.cc $(CXX) $(CXXFLAGS) -c $< + +%.o: %.hh + $(CXX) $(CXXFLAGS) -c $<
participants (1)
-
Edwin Carlinet