olena-2.0-40-gbbd4359 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. --- 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 4216a2c..18fa3cb 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,14 @@ 2012-10-04 Guillaume Lazzara <z@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@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
participants (1)
-
Guillaume Lazzara