* mln/accu/stat/median_interval.hh,
* tests/accu/stat/median_interval.cc: New.
* tests/accu/stat/Makefile.am: New target.
---
milena/ChangeLog | 9 +
.../accu/stat/{median_h.hh => median_interval.hh} | 263 +++++++++-----------
milena/tests/accu/stat/Makefile.am | 6 +-
.../stat/median_interval.cc} | 25 ++-
4 files changed, 151 insertions(+), 152 deletions(-)
copy milena/mln/accu/stat/{median_h.hh => median_interval.hh} (50%)
copy milena/tests/{world/k1/is_primary_face.cc => accu/stat/median_interval.cc} (78%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 0e6b384..596063a 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2012-10-04 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add an accumulator median based on intervals.
+
+ * mln/accu/stat/median_interval.hh,
+ * tests/accu/stat/median_interval.cc: New.
+
+ * tests/accu/stat/Makefile.am: New target.
+
+2012-10-04 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Rename interval::nelements() to interval::nvalues().
* mln/value/interval.hh,
diff --git a/milena/mln/accu/stat/median_h.hh b/milena/mln/accu/stat/median_interval.hh
similarity index 50%
copy from milena/mln/accu/stat/median_h.hh
copy to milena/mln/accu/stat/median_interval.hh
index b38955d..a042bfa 100644
--- a/milena/mln/accu/stat/median_h.hh
+++ b/milena/mln/accu/stat/median_interval.hh
@@ -1,5 +1,4 @@
-// Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development
-// Laboratory (LRDE)
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -24,16 +23,18 @@
// 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_HH
-# define MLN_ACCU_STAT_MEDIAN_H_HH
+#ifndef MLN_ACCU_STAT_MEDIAN_ALT_HH
+# define MLN_ACCU_STAT_MEDIAN_INTERVAL_HH
/// \file
///
-/// Define a generic median accumulator class.
+/// Define a median accumulator class accepting values restricted to a
+/// specific interval of values.
# include <mln/accu/internal/base.hh>
-# include <mln/accu/histo.hh>
-# include <mln/value/set.hh>
+# include <mln/value/interval.hh>
+# include <mln/value/intsub.hh>
+# include <mln/util/array.hh>
namespace mln
@@ -45,61 +46,31 @@ namespace mln
namespace stat
{
- // Forward declaration.
- template <typename V>
- struct median_h;
- } // end of namespace mln::accu::stat
-
- namespace meta
- {
-
- namespace stat
- {
-
- /// Meta accumulator for median_h.
- struct median_h : public Meta_Accumulator< median_h >
- {
- template <typename V>
- struct with
- {
- typedef accu::stat::median_h<V> ret;
- };
- };
-
- } // end of namespace mln::accu::meta::stat
-
- } // end of namespace mln::accu::meta
-
- namespace stat
- {
-
- /// \brief Generic median function based on histogram over a value
- /// set with type \c V.
+ /// \brief Generic median_interval function based on histogram over a
+ /// value set with type \c S.
///
/// \ingroup modaccuvalues
- template <typename V>
- struct median_h : public mln::accu::internal::base< const V&,
median_h<V> >
+ //
+ template <unsigned n>
+ struct median_interval
+ : public mln::accu::internal::base< const value::intsub<n>&,
median_interval<n> >
{
- typedef V argument;
+ typedef value::intsub<n> argument;
- median_h();
- median_h& operator=(const median_h& rhs);
+ median_interval(const value::interval<value::intsub<n> >& inter);
+ median_interval(const value::intsub<n>& first, const
value::intsub<n>& last);
/// Manipulators.
/// \{
- void init();
void take(const argument& t);
- void take(const median_h<V>& other);
+ void take(const median_interval& other);
void untake(const argument& t);
+ void init();
/// \}
- unsigned card() const { return h_.sum(); }
-
/// Get the value of the accumulator.
- const argument& to_result() const;
-
- const accu::histo<V>& histo() const;
+ const value::intsub<n>& to_result() const;
/// Check whether this accu is able to return a result.
/// Always true here.
@@ -107,114 +78,153 @@ namespace mln
protected:
- mutable accu::histo<V> h_;
- const value::set<V>& s_; // derived from h_
+ mutable util::array<unsigned> h_;
+ unsigned sum_;
mutable unsigned sum_minus_, sum_plus_;
mutable bool valid_;
- mutable unsigned i_; // the median_h index
- mutable argument t_; // the median_h value
+
+ /// the median index
+ mutable unsigned i_;
+ /// the median argument
+ mutable value::intsub<n> t_;
+
+ value::interval<value::intsub<n> > inter_;
// Auxiliary methods
- void update_() const;
void go_minus_() const;
void go_plus_() const;
+ void update_() const;
};
+ } // end of mln::accu::stat
+
+
# ifndef MLN_INCLUDE_ONLY
- template <typename V>
- inline
- median_h<V>::median_h()
- : h_(),
- s_(h_.vset())
+ namespace stat
+ {
+
+ template <unsigned n>
+ median_interval<n>::median_interval(const
value::interval<value::intsub<n> >& inter)
+ : inter_(inter)
{
init();
}
- template <typename V>
- inline
- median_h<V>&
- median_h<V>::operator=(const median_h<V>& rhs)
+ template <unsigned n>
+ median_interval<n>::median_interval(const value::intsub<n>& first,
const value::intsub<n>& last)
+ : inter_(first, last)
{
- h_ = rhs.h_;
- sum_minus_ = rhs.sum_minus_;
- sum_plus_ = rhs.sum_plus_;
- valid_ = rhs.valid_;
- i_ = rhs.i_;
- t_ = rhs.t_;
-
- return *this;
+ init();
}
- template <typename V>
- inline
+ template <unsigned n>
void
- median_h<V>::take(const argument& t)
+ median_interval<n>::take(const argument& t)
{
- h_.take(t);
+ mln_precondition(inter_.has(t));
+
+ unsigned index = inter_.index_of(t);
- if (t < t_)
+ // update h_
+ ++h_[index];
+ ++sum_;
+
+ if (index < i_)
++sum_minus_;
- else if (t > t_)
+ else if (index > i_)
++sum_plus_;
if (valid_)
valid_ = false;
}
- template <typename V>
+ template <unsigned n>
inline
void
- median_h<V>::take(const median_h<V>& other)
+ median_interval<n>::take(const median_interval<n>& other)
{
- // h_
- h_.take(other.h_);
+ for (unsigned i = 0; i < h_.size(); ++i)
+ h_[i] += other.h_[i];
// sum_minus_
for (unsigned i = 0; i < i_; ++i)
sum_minus_ += other.h_[i];
// sum_plus_
- for (unsigned i = i_ + 1; i < h_.nvalues(); ++i)
+ for (unsigned i = i_ + 1; i < h_.nelements(); ++i)
sum_plus_ += other.h_[i];
if (valid_)
valid_ = false;
}
- template <typename V>
- inline
+
+ template <unsigned n>
void
- median_h<V>::untake(const argument& t)
+ median_interval<n>::untake(const argument& t)
{
- mln_precondition(h_(t) != 0);
- h_.untake(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 (t < t_)
+ if (index < i_)
--sum_minus_;
- else if (t > t_)
+ else if (index > i_)
--sum_plus_;
if (valid_)
valid_ = false;
}
- template <typename V>
+ template <unsigned n>
+ void
+ median_interval<n>::init()
+ {
+ h_.resize(inter_.nvalues(), 0);
+ sum_minus_ = 0;
+ sum_plus_ = 0;
+ i_ = inter_.nvalues() / 2;
+ t_ = inter_.ith_element(i_);
+ }
+
+ template <unsigned n>
+ const value::intsub<n>&
+ median_interval<n>::to_result() const
+ {
+ if (! valid_)
+ update_();
+ return t_;
+ }
+
+ template <unsigned n>
+ bool
+ median_interval<n>::is_valid() const
+ {
+ return true;
+ }
+
+ template <unsigned n>
inline
void
- median_h<V>::update_() const
+ median_interval<n>::update_() const
{
valid_ = true;
- if (h_.sum() == 0)
+ if (sum_ == 0)
return;
- if (2 * sum_minus_ > h_.sum())
+ if (2 * sum_minus_ > sum_)
go_minus_();
else
- if (2 * sum_plus_ > h_.sum())
+ if (2 * sum_plus_ > sum_)
go_plus_();
else
if (h_[i_] == 0)
@@ -227,10 +237,10 @@ namespace mln
}
}
- template <typename V>
- inline
+
+ template <unsigned n>
void
- median_h<V>::go_minus_() const
+ median_interval<n>::go_minus_() const
{
do
{
@@ -240,14 +250,14 @@ namespace mln
while (h_[i_] == 0);
sum_minus_ -= h_[i_];
}
- while (2 * sum_minus_ > h_.sum());
- t_ = s_[i_];
+ while (2 * sum_minus_ > sum_);
+ t_ = inter_.ith_element(i_);
}
- template <typename V>
- inline
+
+ template <unsigned n>
void
- median_h<V>::go_plus_() const
+ median_interval<n>::go_plus_() const
{
do
{
@@ -257,56 +267,23 @@ namespace mln
while (h_[i_] == 0);
sum_plus_ -= h_[i_];
}
- while (2 * sum_plus_ > h_.sum());
- t_ = s_[i_];
+ while (2 * sum_plus_ > sum_);
+ t_ = inter_.ith_element(i_);
}
- template <typename V>
- inline
- void
- median_h<V>::init()
+ template <unsigned n>
+ std::ostream& operator<<(std::ostream& ostr, const
median_interval<n>& m)
{
- h_.init();
- sum_minus_ = 0;
- sum_plus_ = 0;
- i_ = (s_.index_of(mln_max(argument))
- - s_.index_of(mln_min(argument))) / 2;
- t_ = s_[i_];
- valid_ = true;
+ return ostr << m.to_result();
}
- template <typename V>
- inline
- const typename median_h<V>::argument&
- median_h<V>::to_result() const
- {
- if (! valid_)
- update_();
- return t_;
- }
-
- template <typename V>
- inline
- const accu::histo<V>&
- median_h<V>::histo() const
- {
- return h_;
- }
-
- template <typename V>
- inline
- bool
- median_h<V>::is_valid() const
- {
- return true;
- }
+ } // end of namespace mln::accu::stat
# 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_HH
+
+#endif // ! MLN_ACCU_STAT_MEDIAN_INTERVAL_HH
diff --git a/milena/tests/accu/stat/Makefile.am b/milena/tests/accu/stat/Makefile.am
index 47197c0..77bcf65 100644
--- a/milena/tests/accu/stat/Makefile.am
+++ b/milena/tests/accu/stat/Makefile.am
@@ -1,5 +1,5 @@
-# Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-# (LRDE).
+# Copyright (C) 2009, 2010, 2012 EPITA Research and Development
+# Laboratory (LRDE).
#
# This file is part of Olena.
#
@@ -26,6 +26,7 @@ check_PROGRAMS = \
max \
max_h \
median_h \
+ median_interval \
mean \
rank
@@ -33,6 +34,7 @@ deviation_SOURCES = deviation.cc
var_SOURCES = var.cc
mean_SOURCES = mean.cc
median_h_SOURCES = median_h.cc
+median_interval_SOURCES = median_interval.cc
min_SOURCES = min.cc
min_h_SOURCES = min_h.cc
max_SOURCES = max.cc
diff --git a/milena/tests/world/k1/is_primary_face.cc
b/milena/tests/accu/stat/median_interval.cc
similarity index 78%
copy from milena/tests/world/k1/is_primary_face.cc
copy to milena/tests/accu/stat/median_interval.cc
index 32eb871..a0c05a9 100644
--- a/milena/tests/world/k1/is_primary_face.cc
+++ b/milena/tests/accu/stat/median_interval.cc
@@ -23,17 +23,28 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-/// \file
+#include <mln/accu/stat/median_interval.hh>
-#include <mln/core/alias/point2d.hh>
-#include <mln/world/k1/is_primary_face.hh>
int main()
{
using namespace mln;
- mln_assertion(!world::k1::is_primary_face(point2d(-1, -1)));
- mln_assertion(!world::k1::is_primary_face(point2d(-1, 0)));
- mln_assertion(!world::k1::is_primary_face(point2d(0, -1)));
- mln_assertion(world::k1::is_primary_face(point2d(0, 0)));
+ {
+ accu::stat::median_interval<2> med(2, 5);
+
+ med.take(2);
+ med.take(2);
+ med.take(2.5);
+ med.take(2.5);
+ med.take(4.5);
+ med.take(4.5);
+ med.take(4.5);
+ med.take(4.5);
+ med.take(5);
+ med.take(5);
+ med.take(5);
+
+ mln_assertion(med.to_result() == 4.5);
+ }
}
--
1.7.2.5