* 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(a)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(a)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