olena-2.0-48-gacb3c05 Fix accu::stat::median_interval.

* mln/accu/stat/median_interval.hh: Fix bugs and add support for a different return type. * tests/accu/stat/median_interval.cc: Add more tests. --- milena/ChangeLog | 9 ++++ milena/mln/accu/stat/median_interval.hh | 75 +++++++++++++--------------- milena/tests/accu/stat/median_interval.cc | 59 ++++++++++++++++++++++ 3 files changed, 103 insertions(+), 40 deletions(-) diff --git a/milena/ChangeLog b/milena/ChangeLog index 87afe57..31968b3 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,14 @@ 2012-10-18 Guillaume Lazzara <z@lrde.epita.fr> + Fix accu::stat::median_interval. + + * mln/accu/stat/median_interval.hh: Fix bugs and add support for + a different return type. + + * tests/accu/stat/median_interval.cc: Add more tests. + +2012-10-18 Guillaume Lazzara <z@lrde.epita.fr> + Introduce K2 and Kn spaces. * mln/world/k1/immerse.hh: Make use of kn::immerse. diff --git a/milena/mln/accu/stat/median_interval.hh b/milena/mln/accu/stat/median_interval.hh index ff54710..6315f61 100644 --- a/milena/mln/accu/stat/median_interval.hh +++ b/milena/mln/accu/stat/median_interval.hh @@ -55,7 +55,7 @@ namespace mln /// /// \ingroup modaccuvalues // - template <unsigned n> + template <unsigned n, unsigned m=2*n> struct median_interval : public mln::accu::internal::base< const value::intsub<2*n>&, median_interval<n> > { @@ -114,23 +114,23 @@ namespace mln namespace stat { - template <unsigned n> - median_interval<n>::median_interval(const value::interval<argument >& inter) + template <unsigned n, unsigned m> + median_interval<n,m>::median_interval(const value::interval<argument >& inter) : inter_(inter) { init(); } - template <unsigned n> - median_interval<n>::median_interval(const argument& first, const argument& last) + template <unsigned n, unsigned m> + median_interval<n,m>::median_interval(const argument& first, const argument& last) : inter_(first, last) { init(); } - template <unsigned n> + template <unsigned n, unsigned m> void - median_interval<n>::take(const argument& t) + median_interval<n,m>::take(const argument& t) { mln_precondition(inter_.has(t)); @@ -149,10 +149,10 @@ namespace mln result_ready = false; } - template <unsigned n> + template <unsigned n, unsigned m> inline void - median_interval<n>::take(const median_interval<n>& other) + median_interval<n,m>::take(const median_interval<n,m>& other) { mln_precondition(inter_ == other.inter_); @@ -171,9 +171,9 @@ namespace mln result_ready = false; } - template <unsigned n> + template <unsigned n, unsigned m> void - median_interval<n>::untake(const argument& t) + median_interval<n,m>::untake(const argument& t) { mln_precondition(inter_.has(t)); mln_precondition(h_[inter_.index_of(t)] != 0); @@ -193,11 +193,12 @@ namespace mln result_ready = false; } - template <unsigned n> + template <unsigned n, unsigned m> void - median_interval<n>::init() + median_interval<n,m>::init() { h_.resize(inter_.nvalues(), 0); + h_.fill(0); sum_minus_ = 0; sum_plus_ = 0; sum_ = 0; @@ -206,9 +207,9 @@ namespace mln result_ready = true; } - template <unsigned n> + template <unsigned n, unsigned m> const value::intsub<2*n>& - median_interval<n>::to_result() const + median_interval<n,m>::to_result() const { mln_precondition(is_valid()); @@ -217,42 +218,36 @@ namespace mln return t_; } - template <unsigned n> + template <unsigned n, unsigned m> bool - median_interval<n>::is_valid() const + median_interval<n,m>::is_valid() const { return sum_ > 1; } - template <unsigned n> + template <unsigned n, unsigned m> inline void - median_interval<n>::update_() const + median_interval<n,m>::update_() const { result_ready = true; if (sum_ < 1) return; - if (2 * sum_minus_ > sum_) + if (2 * sum_minus_ >= sum_) go_minus_(); else - if (2 * sum_plus_ > sum_) + if (2 * sum_plus_ >= sum_) go_plus_(); - else - if (h_[n_] == 0) - { - // go to the heaviest side - if (sum_plus_ > sum_minus_) - go_plus_(); - else - go_minus_(); // default when both sides are balanced - } + else // Both sides are balanced + if (h_[n_] == 0 || sum_ == 2) + go_minus_(); } - template <unsigned n> + template <unsigned n, unsigned m> void - median_interval<n>::go_minus_() const + median_interval<n,m>::go_minus_() const { do { @@ -289,9 +284,9 @@ namespace mln : value::iota<value::intsub<2*n> >::value()); } - template <unsigned n> + template <unsigned n, unsigned m> void - median_interval<n>::go_plus_() const + median_interval<n,m>::go_plus_() const { do { @@ -329,9 +324,9 @@ namespace mln : value::iota<value::intsub<2*n> >::value()); } - template <unsigned n> - typename median_interval<n>::index_t - median_interval<n>::find_n1_() const + 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) @@ -341,10 +336,10 @@ namespace mln } - template <unsigned n> - std::ostream& operator<<(std::ostream& ostr, const median_interval<n>& m) + template <unsigned n, unsigned m> + std::ostream& operator<<(std::ostream& ostr, const median_interval<n,m>& med) { - return ostr << m.to_result(); + return ostr << med.to_result(); } } // end of namespace mln::accu::stat diff --git a/milena/tests/accu/stat/median_interval.cc b/milena/tests/accu/stat/median_interval.cc index 6a5fd95..c0af4a1 100644 --- a/milena/tests/accu/stat/median_interval.cc +++ b/milena/tests/accu/stat/median_interval.cc @@ -102,6 +102,19 @@ int main() 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); @@ -241,4 +254,50 @@ int main() 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
participants (1)
-
Guillaume Lazzara