
* mln/accu/stat/median_few.hh, * mln/accu/stat/median_h_interval.hh, * mln/trait/routine/mean.hh, * tests/accu/stat/median_few.cc, * tests/accu/stat/median_h_interval.cc: New. * mln/value/int_u.hh, * mln/value/intsub.hh: Specialize traits. * tests/accu/stat/Makefile.am: New targets. * mln/accu/stat/median_interval.hh, * tests/accu/stat/median_interval.cc: Remove. --- milena/ChangeLog | 18 + milena/mln/accu/stat/median_few.hh | 147 ++++++++ milena/mln/accu/stat/median_h_interval.hh | 157 +++++++++ milena/mln/accu/stat/median_interval.hh | 354 -------------------- .../concept/interval.hh => trait/routine/mean.hh} | 54 ++-- milena/mln/value/int_u.hh | 15 +- milena/mln/value/intsub.hh | 13 + milena/tests/accu/stat/Makefile.am | 6 +- .../k1/immerse_with.cc => accu/stat/median_few.cc} | 80 +++-- .../stat/median_h_interval.cc} | 92 +++--- milena/tests/accu/stat/median_interval.cc | 303 ----------------- 11 files changed, 479 insertions(+), 760 deletions(-) create mode 100644 milena/mln/accu/stat/median_few.hh create mode 100644 milena/mln/accu/stat/median_h_interval.hh delete mode 100644 milena/mln/accu/stat/median_interval.hh copy milena/mln/{value/concept/interval.hh => trait/routine/mean.hh} (65%) copy milena/tests/{world/k1/immerse_with.cc => accu/stat/median_few.cc} (63%) copy milena/tests/{world/k1/fill_1_from_2_faces.cc => accu/stat/median_h_interval.cc} (56%) delete mode 100644 milena/tests/accu/stat/median_interval.cc diff --git a/milena/ChangeLog b/milena/ChangeLog index 9b113d5..fe731b3 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,21 @@ +2012-10-23 Guillaume Lazzara <z@lrde.epita.fr> + + Add new median accumulators. + + * mln/accu/stat/median_few.hh, + * mln/accu/stat/median_h_interval.hh, + * mln/trait/routine/mean.hh, + * tests/accu/stat/median_few.cc, + * tests/accu/stat/median_h_interval.cc: New. + + * mln/value/int_u.hh, + * mln/value/intsub.hh: Specialize traits. + + * tests/accu/stat/Makefile.am: New targets. + + * mln/accu/stat/median_interval.hh, + * tests/accu/stat/median_interval.cc: Remove. + 2012-10-22 Guillaume Lazzara <z@lrde.epita.fr> Move util::level to world::kn and add new operators. diff --git a/milena/mln/accu/stat/median_few.hh b/milena/mln/accu/stat/median_few.hh new file mode 100644 index 0000000..dd3c16f --- /dev/null +++ b/milena/mln/accu/stat/median_few.hh @@ -0,0 +1,147 @@ +// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_ACCU_STAT_MEDIAN_FEW_HH +# define MLN_ACCU_STAT_MEDIAN_FEW_HH + +/// \file +/// +/// \brief Define a median accumulator class to be used with few +/// values. + +# include <iostream> +# include <vector> +# include <algorithm> + +# include <mln/trait/routine/mean.hh> +# include <mln/accu/internal/base.hh> + + +namespace mln +{ + + namespace accu + { + + namespace stat + { + + /// \brief Define a median accumulator class to be used with few + /// values. + template <typename T, + typename R = mln_trait_routine_mean(2,T) > + struct median_few + : public mln::accu::internal::base< R, median_few<T,R> > + { + typedef T argument; + typedef R result; + + median_few(); + + void reserve(unsigned n); + void init(); + + void take(const argument& v); + void take(const median_few<T,R>& other); + // nota bene: no possible untake with this accumulator + + result to_result() const; + + bool is_valid() const; + + protected: + + mutable std::vector<argument> v_; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename T, typename R> + median_few<T,R>::median_few() + { + init(); + } + + template <typename T, typename R> + void + median_few<T,R>::reserve(unsigned n) + { + v_.reserve(n); + } + + template <typename T, typename R> + void + median_few<T,R>::init() + { + v_.clear(); + } + + template <typename T, typename R> + void + median_few<T,R>::take(const argument& v) + { + v_.push_back(v); + } + + template <typename T, typename R> + void + median_few<T,R>::take(const median_few<T,R>& other) + { + v_.insert(v_.end(), other.v_.begin(), other.v_.end()); + } + + + template <typename T, typename R> + typename median_few<T,R>::result + median_few<T,R>::to_result() const + { + mln_precondition(is_valid()); + std::sort(v_.begin(), v_.end()); + // indices 0 1 2 => size = 3 => mid = 1 + // 0 1 => size = 2 => mid = 0 + unsigned mid = (v_.size() - 1) / 2; + if (v_.size() % 2) + return v_[mid]; + else + return (R(v_[mid]) + R(v_[mid + 1])) / 2; + } + + template <typename T, typename R> + bool + median_few<T,R>::is_valid() const + { + return v_.size() != 0; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::accu::stat + + } // end of namespace mln::accu + +} // end of namespace mln + +#endif // ! MLN_ACCU_STAT_MEDIAN_FEW_HH diff --git a/milena/mln/accu/stat/median_h_interval.hh b/milena/mln/accu/stat/median_h_interval.hh new file mode 100644 index 0000000..86c72a7 --- /dev/null +++ b/milena/mln/accu/stat/median_h_interval.hh @@ -0,0 +1,157 @@ +// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_ACCU_STAT_MEDIAN_H_INTERVAL_HH +# define MLN_ACCU_STAT_MEDIAN_H_INTERVAL_HH + +/// \file +/// +/// \brief Define a median accumulator class based on a histogram and +/// working on a specific interval. + +# include <vector> +# include <mln/value/interval.hh> +# include <mln/trait/routine/mean.hh> + + + +namespace mln +{ + + namespace accu + { + + namespace stat + { + + /// \brief Define a median accumulator class based on a histogram and + /// working on a specific interval. + template <typename T, + typename R = mln_trait_routine_mean(2,T) > + struct median_h_interval + { + typedef T argument; + typedef R result; + + median_h_interval(const value::interval<argument>& inter); + median_h_interval(const argument& first, const argument& last); + + void init(); + + void take(const argument& v); + + // nota bene: no untake with this accumulator + + result to_result() const; + + bool is_valid() const; + + protected: + + value::interval<argument> inter_; + std::vector<unsigned> h_; + unsigned nitems_; + }; + +# ifndef MLN_INCLUDE_ONLY + + template <typename T, typename R> + median_h_interval<T,R>::median_h_interval(const value::interval<argument>& inter) + : inter_(inter) + { + h_.resize(inter_.nelements()); + init(); + } + + template <typename T, typename R> + median_h_interval<T,R>::median_h_interval(const argument& first, + const argument& last) + : inter_(first, last) + { + h_.resize(inter_.nelements()); + init(); + } + + template <typename T, typename R> + void + median_h_interval<T,R>::init() + { + std::fill(h_.begin(), h_.end(), 0u); + nitems_ = 0; + } + + template <typename T, typename R> + void + median_h_interval<T,R>::take(const argument& v) + { + h_[inter_.index_of(v)] += 1; + nitems_ += 1; + } + + template <typename T, typename R> + typename median_h_interval<T,R>::result + median_h_interval<T,R>::to_result() const + { + mln_precondition(is_valid()); + unsigned i = 0, n = h_.size(); + unsigned sum = h_[0], mid = (nitems_ + 1) / 2; + while (i < n && sum < mid) + { + ++i; + sum += h_[i]; + } + if (nitems_ % 2) // nitems_ is odd. + return inter_.ith_element(i); + + // nitems_ is even. + if (sum > mid) + return inter_.ith_element(i); + // looking for next non null value + unsigned i_memo = i; + do + ++i; + while (h_[i] == 0); + return (result(inter_.ith_element(i_memo)) + + result(inter_.ith_element(i))) / 2; + } + + template <typename T, typename R> + bool + median_h_interval<T,R>::is_valid() const + { + return nitems_ != 0; + } + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::accu::stat + + } // end of namespace mln::accu + +} // end of namespace mln + + +#endif // ! MLN_ACCU_STAT_MEDIAN_H_INTERVAL_HH diff --git a/milena/mln/accu/stat/median_interval.hh b/milena/mln/accu/stat/median_interval.hh deleted file mode 100644 index 6315f61..0000000 --- a/milena/mln/accu/stat/median_interval.hh +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE) -// -// This file is part of Olena. -// -// Olena is free software: you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation, version 2 of the License. -// -// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. -// -// As a special exception, you may use this file as part of a free -// software project 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_ACCU_STAT_MEDIAN_ALT_HH -# define MLN_ACCU_STAT_MEDIAN_INTERVAL_HH - -/// \file -/// -/// Define a median accumulator class accepting values restricted to a -/// specific interval of values. - -# include <mln/accu/internal/base.hh> -# include <mln/value/interval.hh> -# include <mln/value/intsub.hh> -# include <mln/util/array.hh> -# include <mln/value/dec.hh> -# include <mln/value/inc.hh> -# include <mln/value/prev.hh> -# include <mln/value/succ.hh> - -namespace mln -{ - - namespace accu - { - - namespace stat - { - - - /// \brief Generic median_interval function based on histogram over a - /// value set with type \c S. - /// - /// \ingroup modaccuvalues - // - template <unsigned n, unsigned m=2*n> - struct median_interval - : public mln::accu::internal::base< const value::intsub<2*n>&, median_interval<n> > - { - typedef value::intsub<n> argument; - typedef value::intsub<1> index_t; - - median_interval(const value::interval<argument>& inter); - median_interval(const argument& first, const argument& last); - - /// Manipulators. - /// \{ - void take(const argument& t); - void take(const median_interval& other); - void untake(const argument& t); - void init(); - /// \} - - /// Get the value of the accumulator. - const value::intsub<2*n>& to_result() const; - - /// Check whether this accu is able to return a result. - /// Always true here. - bool is_valid() const; - - protected: - - mutable util::array<unsigned> h_; - unsigned sum_; - - mutable unsigned sum_minus_, sum_plus_; - - mutable bool result_ready; - - /// the median value - mutable value::intsub<2*n> t_; - - /// The median index. - mutable index_t n_; - - value::interval<argument > inter_; - - // Auxiliary methods - void go_minus_() const; - void go_plus_() const; - void update_() const; - - index_t find_n1_() const; - - }; - - } // end of mln::accu::stat - - -# ifndef MLN_INCLUDE_ONLY - - namespace stat - { - - template <unsigned n, unsigned m> - median_interval<n,m>::median_interval(const value::interval<argument >& inter) - : inter_(inter) - { - init(); - } - - template <unsigned n, unsigned m> - median_interval<n,m>::median_interval(const argument& first, const argument& last) - : inter_(first, last) - { - init(); - } - - template <unsigned n, unsigned m> - void - median_interval<n,m>::take(const argument& t) - { - mln_precondition(inter_.has(t)); - - unsigned index = inter_.index_of(t); - - // update h_ - ++h_[index]; - ++sum_; - - if (index < n_) - ++sum_minus_; - else if (index > n_) - ++sum_plus_; - - if (result_ready) - result_ready = false; - } - - template <unsigned n, unsigned m> - inline - void - median_interval<n,m>::take(const median_interval<n,m>& other) - { - mln_precondition(inter_ == other.inter_); - - for (unsigned i = 0; i < h_.size(); ++i) - h_[i] += other.h_[i]; - - // sum_minus_ - for (unsigned i = 0; i < n_; ++i) - sum_minus_ += other.h_[i]; - - // sum_plus_ - for (unsigned i = n_ + 1; i < h_.nelements(); ++i) - sum_plus_ += other.h_[i]; - - if (result_ready) - result_ready = false; - } - - template <unsigned n, unsigned m> - void - median_interval<n,m>::untake(const argument& t) - { - mln_precondition(inter_.has(t)); - mln_precondition(h_[inter_.index_of(t)] != 0); - - unsigned index = inter_.index_of(t); - - // update h_ - --h_[index]; - --sum_; - - if (index < n_) - --sum_minus_; - else if (index > n_) - --sum_plus_; - - if (result_ready) - result_ready = false; - } - - template <unsigned n, unsigned m> - void - median_interval<n,m>::init() - { - h_.resize(inter_.nvalues(), 0); - h_.fill(0); - sum_minus_ = 0; - sum_plus_ = 0; - sum_ = 0; - n_ = int(inter_.nvalues() / 2); - t_ = inter_.ith_element(n_); - result_ready = true; - } - - template <unsigned n, unsigned m> - const value::intsub<2*n>& - median_interval<n,m>::to_result() const - { - mln_precondition(is_valid()); - - if (! result_ready) - update_(); - return t_; - } - - template <unsigned n, unsigned m> - bool - median_interval<n,m>::is_valid() const - { - return sum_ > 1; - } - - template <unsigned n, unsigned m> - inline - void - median_interval<n,m>::update_() const - { - result_ready = true; - - if (sum_ < 1) - return; - - if (2 * sum_minus_ >= sum_) - go_minus_(); - else - if (2 * sum_plus_ >= sum_) - go_plus_(); - else // Both sides are balanced - if (h_[n_] == 0 || sum_ == 2) - go_minus_(); - } - - template <unsigned n, unsigned m> - void - median_interval<n,m>::go_minus_() const - { - do - { - sum_plus_ += h_[n_]; - do - dec(n_); - while (h_[n_] == 0); - sum_minus_ -= h_[n_]; - } - while (2 * sum_minus_ > sum_); - - // The number of values is odd, the current index corresponds - // to the exact median. - // OR - // We need to take the mean of the (n/2)-th and (n/2+1)-th value, so - // if this is the same value, we just return it. - if (sum_ % 2 || (sum_minus_ + h_[n_] > sum_ / 2)) - { - t_ = inter_.ith_element(n_); - return; - } - - // The number of values is even, we need to effectively take - // the mean of the (n/2)-th and (n/2+1)-th values which are - // different. - index_t n1 = find_n1_(); - if (n1 == h_.nelements()) - n1 = n_; - - value::intsub<2> index = mean(n_, n1); - - t_ = inter_.ith_element(index) - + (index.is_integer() ? literal::zero - : value::iota<value::intsub<2*n> >::value()); - } - - template <unsigned n, unsigned m> - void - median_interval<n,m>::go_plus_() const - { - do - { - sum_minus_ += h_[n_]; - do - inc(n_); - while (h_[n_] == 0); - sum_plus_ -= h_[n_]; - } - while (2 * sum_plus_ > sum_); - - - // The number of values is odd, the current index corresponds - // to the exact median. - // OR - // We need to take the mean of the (n/2)-th and (n/2+1)-th value, so - // if this is the same value, we just return it. - if (sum_ % 2 || (sum_minus_ + h_[n_] > sum_ / 2)) - { - t_ = inter_.ith_element(n_); - return; - } - - // The number of values is even, we need to effectively take - // the mean of the (n/2)-th and (n/2+1)-th values which are - // different. - index_t n1 = find_n1_(); - if (n1 == -1) - n1 = n_; - - value::intsub<2> index = mean(n_, n1); - - t_ = inter_.ith_element(index) - + (index.is_integer() ? literal::zero - : value::iota<value::intsub<2*n> >::value()); - } - - template <unsigned n, unsigned m> - typename median_interval<n,m>::index_t - median_interval<n,m>::find_n1_() const - { - index_t id = value::succ(n_); - while (id < h_.nelements() && h_[id] == 0) - inc(id); - - return id; - } - - - template <unsigned n, unsigned m> - std::ostream& operator<<(std::ostream& ostr, const median_interval<n,m>& med) - { - return ostr << med.to_result(); - } - - } // end of namespace mln::accu::stat - -# endif // ! MLN_INCLUDE_ONLY - - } // end of namespace mln::accu - -} // end of namespace mln - - -#endif // ! MLN_ACCU_STAT_MEDIAN_INTERVAL_HH diff --git a/milena/mln/value/concept/interval.hh b/milena/mln/trait/routine/mean.hh similarity index 65% copy from milena/mln/value/concept/interval.hh copy to milena/mln/trait/routine/mean.hh index 57b1916..6d96344 100644 --- a/milena/mln/value/concept/interval.hh +++ b/milena/mln/trait/routine/mean.hh @@ -23,51 +23,45 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -#ifndef MLN_VALUE_CONCEPT_INTERVAL_HH -# define MLN_VALUE_CONCEPT_INTERVAL_HH - -/*! \file - * - * \brief Define a generic class for interval of values. - */ - -# include <mln/core/concept/value.hh> +#ifndef MLN_TRAIT_ROUTINE_MEAN_HH +# define MLN_TRAIT_ROUTINE_MEAN_HH +# define mln_trait_routine_mean(n,T) typename mln::trait::routine::mean<n,T>::ret +# define mln_trait_routine_mean_(n,T) mln::trait::routine::mean<n,T>::ret namespace mln { - // Fwd decl. - namespace value { template <typename E> struct Interval; } - + // Forward Declaration + namespace value { template <unsigned n> class intsub; } namespace trait { - // FIXME... + namespace routine + { - } // end of namespace mln::trait + // mean + template <unsigned nvalues, typename T> + struct mean + { + // undef + }; - namespace value - { - // Category flag type. - template <> - struct Interval<void> - { - typedef Value<void> super; - }; + // specializations - template <typename E> - struct Interval : public Value<E> - { - typedef Interval<void> category; - }; + template <unsigned nvalues> + struct mean< nvalues, int > + { + typedef mln::value::intsub<nvalues> ret; + }; - } // end of namespace mln::value + } // end of namespace mln::trait::routine -} // end of namespace mln + } // end of namespace mln::routine +} // end of namespace mln -#endif // ! MLN_VALUE_CONCEPT_INTERVAL_HH +#endif // ! MLN_TRAIT_ROUTINE_MEAN_HH diff --git a/milena/mln/value/int_u.hh b/milena/mln/value/int_u.hh index 7fa217d..1a29f5f 100644 --- a/milena/mln/value/int_u.hh +++ b/milena/mln/value/int_u.hh @@ -38,6 +38,7 @@ # include <mln/value/internal/encoding.hh> # include <mln/value/concept/integer.hh> # include <mln/trait/value_.hh> +# include <mln/trait/routine/mean.hh> # include <mln/debug/format.hh> # include <mln/value/iota.hh> @@ -54,6 +55,7 @@ namespace mln } template <unsigned n> struct int_u; template <unsigned n> struct rgb; + template <unsigned n> class intsub; } namespace literal @@ -72,7 +74,6 @@ namespace mln typedef int ret; }; - template <unsigned n> struct value_< mln::value::int_u<n> > { @@ -108,6 +109,18 @@ namespace mln }; + + namespace routine + { + + template <unsigned nvalues, unsigned n> + struct mean< nvalues, mln::value::int_u<n> > + { + typedef mln::value::intsub<nvalues> ret; + }; + + } // end of namespace mln::trait::routine + } // end of namespace mln::trait diff --git a/milena/mln/value/intsub.hh b/milena/mln/value/intsub.hh index 609bd12..eaff527 100644 --- a/milena/mln/value/intsub.hh +++ b/milena/mln/value/intsub.hh @@ -36,6 +36,7 @@ # include <vector> # include <algorithm> # include <mln/core/routine/ops.hh> +# include <mln/trait/routine/mean.hh> # include <mln/value/ops.hh> # include <mln/value/builtin/ops.hh> # include <mln/value/internal/value_like.hh> @@ -98,6 +99,18 @@ namespace mln }; + + namespace routine + { + + template <unsigned nvalues, unsigned n> + struct mean< nvalues, mln::value::intsub<n> > + { + typedef mln::value::intsub<nvalues * n> ret; + }; + + } // end of namespace mln::trait::routine + } // end of namespace mln::trait diff --git a/milena/tests/accu/stat/Makefile.am b/milena/tests/accu/stat/Makefile.am index 77bcf65..f86dd88 100644 --- a/milena/tests/accu/stat/Makefile.am +++ b/milena/tests/accu/stat/Makefile.am @@ -25,8 +25,9 @@ check_PROGRAMS = \ min_max \ max \ max_h \ + median_few \ median_h \ - median_interval \ + median_h_interval \ mean \ rank @@ -34,7 +35,8 @@ deviation_SOURCES = deviation.cc var_SOURCES = var.cc mean_SOURCES = mean.cc median_h_SOURCES = median_h.cc -median_interval_SOURCES = median_interval.cc +median_few_SOURCES = median_few.cc +median_h_interval_SOURCES = median_h_interval.cc min_SOURCES = min.cc min_h_SOURCES = min_h.cc max_SOURCES = max.cc diff --git a/milena/tests/world/k1/immerse_with.cc b/milena/tests/accu/stat/median_few.cc similarity index 63% copy from milena/tests/world/k1/immerse_with.cc copy to milena/tests/accu/stat/median_few.cc index 3b7e8fc..ac10a52 100644 --- a/milena/tests/world/k1/immerse_with.cc +++ b/milena/tests/accu/stat/median_few.cc @@ -23,41 +23,63 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -/// \file +#include <mln/value/intsub.hh> +#include <mln/accu/stat/median_few.hh> -#include <mln/core/image/image2d.hh> -#include <mln/world/k1/immerse_with.hh> -#include <mln/data/compare.hh> -#include <mln/border/fill.hh> -#include <mln/fun/vv2v/max.hh> -#include <mln/fun/vvvv2v/max.hh> -int main() +template <typename T> +void doit() { - using namespace mln; + typedef mln::accu::stat::median_few<T> M; + + { + M m; + m.init(); + m.take(6); + mln_postcondition(m.to_result() == 6); + } - int ivals[][2] = { - {1, 2}, - {3, 4} - }; - image2d<int> ima = make::image(ivals); - border::fill(ima, 0); // Make sure there is not border effect. - - int fvals[][5] = { - {1, 1, 2, 2, 2}, - {1, 1, 2, 2, 2}, - {3, 3, 4, 4, 4}, - {3, 3, 4, 4, 4}, - {3, 3, 4, 4, 4} - }; - image2d<int> ref = make::image(fvals, point2d(-1,-1)); + { + M m; + m.init(); + m.take(6); + m.take(6); + mln_postcondition(m.to_result() == 6); + } + + { + M m; + m.init(); + m.take(6); + m.take(6); + m.take(0); + mln_postcondition(m.to_result() == 6); + } { - image2d<long> - immersed = world::k1::immerse_with(ima, long(), - fun::vv2v::max<long>(), - fun::vvvv2v::max<long>()); - mln_assertion(immersed == ref); + M m; + m.init(); + m.take(12); + m.take(0); + m.take(0); + m.take(24); + mln_postcondition(m.to_result() == 6); } + { + M m; + m.init(); + m.take(1); + m.take(0); + mln_postcondition(m.to_result() == 0.5); + } +} + + +int main() +{ + using namespace mln; + + doit<int>(); + doit< value::intsub<2> >(); } diff --git a/milena/tests/world/k1/fill_1_from_2_faces.cc b/milena/tests/accu/stat/median_h_interval.cc similarity index 56% copy from milena/tests/world/k1/fill_1_from_2_faces.cc copy to milena/tests/accu/stat/median_h_interval.cc index 4045674..b20489d 100644 --- a/milena/tests/world/k1/fill_1_from_2_faces.cc +++ b/milena/tests/accu/stat/median_h_interval.cc @@ -23,64 +23,74 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -/// \file +#include <mln/value/interval.hh> +#include <mln/value/intsub.hh> +#include <mln/accu/stat/median_h_interval.hh> -#include <mln/core/image/image2d.hh> -#include <mln/make/box2d.hh> -#include <mln/data/compare.hh> -#include <mln/accu/math/sum.hh> -#include <mln/world/k1/fill_1_from_2_faces.hh> -#include <mln/border/fill.hh> - -namespace mln +template <typename T> +void doit(const mln::value::interval<T>& inter) { + typedef mln::accu::stat::median_h_interval<T> M; - struct sum_t : Function_vv2v<sum_t> { - typedef int result; + M m(inter); + m.init(); + m.take(6); + mln_postcondition(m.to_result() == 6); + } - int operator()(const int& v1, const int& v2) const - { - return v1 + v2; - } + { + M m(inter); + m.init(); + m.take(6); + m.take(6); + mln_postcondition(m.to_result() == 6); + } - }; + { + M m(inter); + m.init(); + m.take(6); + m.take(6); + m.take(0); + mln_postcondition(m.to_result() == 6); + } -} + { + M m(inter); + m.init(); + m.take(12); + m.take(0); + m.take(0); + m.take(24); + mln_postcondition(m.to_result() == 6); + } + { + M m(inter); + m.init(); + m.take(1); + m.take(0); + mln_postcondition(m.to_result() == 0.5); + } +} int main() { using namespace mln; - int refvals[5][5] = { - {1, 3, 1, 3, 1}, - {3, 3, 6, 3, 3}, - {1, 6, 1, 6, 1}, - {3, 3, 6, 3, 3}, - {1, 3, 1, 3, 1} - }; - image2d<int> ref = make::image(refvals, point2d(-1, -1)); - - int vals[5][5] = { - {1, 0, 1, 0, 1 }, - {0, 3, 0, 3, 0 }, - {1, 0, 1, 0, 1 }, - {0, 3, 0, 3, 0 }, - {1, 0, 1, 0, 1 } - }; - image2d<int> imakn = make::image(vals, point2d(-1, -1)); - - /// Make sure the border is set to 0 to get deterministic results. - border::fill(imakn, 0); + { + typedef int T; + value::interval<T> inter(0, 30); + doit(inter); + } - // Overload with function { - sum_t f; - world::k1::fill_1_from_2_faces(imakn, f); - mln_assertion(ref == imakn); + typedef value::intsub<2> T; + value::interval<T> inter(0, 30); + doit(inter); } } diff --git a/milena/tests/accu/stat/median_interval.cc b/milena/tests/accu/stat/median_interval.cc deleted file mode 100644 index c0af4a1..0000000 --- a/milena/tests/accu/stat/median_interval.cc +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE) -// -// This file is part of Olena. -// -// Olena is free software: you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation, version 2 of the License. -// -// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. -// -// As a special exception, you may use this file as part of a free -// software project 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. - -#include <mln/accu/stat/median_interval.hh> - - -int main() -{ - using namespace mln; - - // Empty - { - // FIXME: How should it behave ? - accu::stat::median_interval<1> med(1, 4); - mln_assertion(!med.is_valid()); - } - - // Single value - { - // FIXME: How should it behave ? - accu::stat::median_interval<1> med(1, 4); - med.take(1); - mln_assertion(!med.is_valid()); - } - - // Same value several times (odd count) - { - accu::stat::median_interval<1> med(1, 4); - med.take(1); - med.take(1); - med.take(1); - mln_assertion(med.to_result() == 1); - } - - // Same value several times (even count) - { - accu::stat::median_interval<1> med(1, 4); - med.take(1); - med.take(1); - med.take(1); - med.take(1); - mln_assertion(med.to_result() == 1); - } - - // Same value several times + one different higher value. - { - accu::stat::median_interval<1> med(0, 4); - med.take(0); - med.take(1); - med.take(1); - med.take(2); - mln_assertion(med.to_result() == 1); - } - - - // Various values - { - accu::stat::median_interval<1> med(0, 4); - med.take(0); - med.take(1); - med.take(1); - med.take(3); - med.take(3); - med.take(4); - mln_assertion(med.to_result() == 2); - } - - - // Various values - { - accu::stat::median_interval<1> med(0, 4); - med.take(0); - med.take(1); - med.take(1); - med.take(2); - med.take(2); - med.take(3); - med.take(3); - med.take(4); - mln_assertion(med.to_result() == 2); - } - - // Various values - { - accu::stat::median_interval<1> med(0, 4); - med.take(0); - med.take(1); - med.take(1); - med.take(2); - med.take(3); - med.take(3); - med.take(4); - mln_assertion(med.to_result() == 2); - } - - // Same value several times + one different higher value. - { - accu::stat::median_interval<1> med(1, 4); - med.take(1); - med.take(1); - med.take(1); - med.take(2); - mln_assertion(med.to_result() == 1); - } - - // Same value several times + one different lower value. - { - accu::stat::median_interval<1> med(1, 4); - med.take(1); - med.take(2); - med.take(2); - med.take(2); - mln_assertion(med.to_result() == 2); - } - - // Same value several times + one different higher value with - // subdivided interval. - { - accu::stat::median_interval<2> med(1, 4); - med.take(1); - med.take(1); - med.take(1); - med.take(2); - mln_assertion(med.to_result() == 1); - } - - // Same value several times + one different lower value with - // subdivided interval. - { - accu::stat::median_interval<2> med(1, 4); - med.take(1); - med.take(2); - med.take(2); - med.take(2); - mln_assertion(med.to_result() == 2); - } - - // Odd number of values - { - accu::stat::median_interval<1> med(1, 8); - med.take(1); - med.take(5); - med.take(2); - med.take(8); - med.take(7); - mln_assertion(med.to_result() == 5); - } - - // Even number of values - { - accu::stat::median_interval<1> med(1, 8); - med.take(1); - med.take(6); - med.take(2); - med.take(8); - med.take(7); - med.take(2); - mln_assertion(med.to_result() == 4); - } - - // Based on a subdivided interval - { - accu::stat::median_interval<2> med(3.5, 6.5); - - med.take(4.5); - med.take(6); - med.take(4.5); - med.take(6); - - mln_assertion(med.to_result() == 5.25); - } - - // Using 0 as value. - { - accu::stat::median_interval<2> med(0, 4); - - med.take(0); - med.take(1); - med.take(2); - med.take(3); - med.take(4); - - mln_assertion(med.to_result() == 2); - } - - // Using 0 as value. - { - accu::stat::median_interval<2> med(0, 5); - - med.take(0); - med.take(1); - med.take(2); - med.take(3); - med.take(4); - med.take(5); - - mln_assertion(med.to_result() == 2.5); - } - - // Integer Interval with negative values. - { - accu::stat::median_interval<1> med(-2, 3); - - med.take(-1); - med.take(-2); - med.take(2); - med.take(3); - - mln_assertion(med.to_result() == 0.5); - } - - // Subdivided Interval with negative values. - { - accu::stat::median_interval<2> med(-2, 3); - - med.take(-1); - med.take(-2); - med.take(2); - med.take(3); - - mln_assertion(med.to_result() == 0.5); - } - - // Subdivided Interval with negative values. - { - accu::stat::median_interval<1> med(-2, 3); - - med.take(-1); - med.take(-2); - med.take(2); - med.take(3); - mln_assertion(med.to_result() == 0.5); - } - - - { - accu::stat::median_interval<1> med(0, 255); - - med.take(126); - med.take(128); - mln_assertion(med.to_result() == 127); - } - - - { - accu::stat::median_interval<1> med(0, 255); - - med.take(126); - med.take(128); - med.take(128); - med.take(128); - med.take(128); - med.take(130); - mln_assertion(med.to_result() == 128); - } - - { - accu::stat::median_interval<1> med(0, 255); - - med.take(126); - med.take(128); - med.take(129); - med.take(130); - med.take(130); - med.take(130); - mln_assertion(med.to_result() == 129.5); - } - - // One value... - { - accu::stat::median_interval<1> med(0, 255); - - med.take(128); - med.take(128); - med.take(124); - med.take(124); - std::cout << med.to_result() << std::endl; - mln_assertion(med.to_result() == 126); - } - -} -- 1.7.2.5