00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_ACCU_STAT_MAX_H_HH
00027 # define MLN_ACCU_STAT_MAX_H_HH
00028
00032
00033 # include <mln/accu/internal/base.hh>
00034 # include <mln/core/concept/meta_accumulator.hh>
00035 # include <mln/accu/histo.hh>
00036 # include <mln/util/pix.hh>
00037
00038
00039 namespace mln
00040 {
00041
00042 namespace accu
00043 {
00044
00045 namespace stat
00046 {
00047
00048
00049 template <typename V>
00050 struct max_h;
00051
00052 }
00053
00054 namespace meta
00055 {
00056
00057 namespace stat
00058 {
00059
00061 struct max_h : public Meta_Accumulator< max_h >
00062 {
00063 template <typename T>
00064 struct with
00065 {
00066 typedef accu::stat::max_h<T> ret;
00067 };
00068 };
00069
00070 }
00071
00072 }
00073
00074
00075 namespace stat
00076 {
00077
00082
00083 template <typename V>
00084 struct max_h : public mln::accu::internal::base< const V&, max_h<V> >
00085 {
00086 typedef V argument;
00087
00088 max_h();
00089
00092 void init();
00093 void take(const argument& t);
00094 void take_as_init_(const argument& t);
00095 void take(const max_h<V>& other);
00096 void untake(const argument& t);
00098
00099 unsigned card() const { return h_.sum(); }
00100
00102 const argument& to_result() const;
00103
00104 const accu::histo<V>& histo() const;
00105
00108 bool is_valid() const;
00109
00110 void debug_print_() const;
00111
00112 protected:
00113
00114 mutable accu::histo<V> h_;
00115 const value::set<V>& s_;
00116
00117 mutable unsigned sum_;
00118 mutable bool valid_;
00119 mutable unsigned i_;
00120 mutable argument t_;
00121
00122
00123 void update_() const;
00124 void go_minus_() const;
00125 void go_plus_() const;
00126 };
00127
00128
00129 template <typename I> struct max_h< util::pix<I> >;
00130
00131 # ifndef MLN_INCLUDE_ONLY
00132
00133 template <typename V>
00134 inline
00135 max_h<V>::max_h()
00136 : h_(),
00137 s_(h_.vset())
00138 {
00139 init();
00140 }
00141
00142 template <typename V>
00143 inline
00144 void
00145 max_h<V>::take(const argument& t)
00146 {
00147 if (h_.sum() == 0)
00148 {
00149 this->take_as_init_(t);
00150 return;
00151 }
00152 h_.take(t);
00153 if (t > t_)
00154 {
00155 ++sum_;
00156 valid_ = false;
00157 }
00158 }
00159
00160 template <typename V>
00161 inline
00162 void
00163 max_h<V>::take(const max_h<V>& other)
00164 {
00165
00166 h_.take(other.h_);
00167 for (unsigned i = this->card() - 1; i > i_; --i)
00168 sum_ += other.h_[i];
00169 valid_ = false;
00170
00171 }
00172
00173 template <typename V>
00174 inline
00175 void
00176 max_h<V>::untake(const argument& t)
00177 {
00178 mln_precondition(h_(t) != 0);
00179 h_.untake(t);
00180 if (h_.sum() == 0)
00181 {
00182 init();
00183 return;
00184 }
00185 if (t > t_)
00186 {
00187 mln_invariant(sum_ >= 1);
00188 --sum_;
00189 valid_ = false;
00190 }
00191 else
00192 if (t == t_ && h_[i_] == 0)
00193 valid_ = false;
00194 }
00195
00196 template <typename V>
00197 inline
00198 void
00199 max_h<V>::update_() const
00200 {
00201 if (sum_ != 0)
00202 go_plus_();
00203 else
00204 if (h_[i_] == 0)
00205 go_minus_();
00206 valid_ = true;
00207 }
00208
00209 template <typename V>
00210 inline
00211 void
00212 max_h<V>::go_plus_() const
00213 {
00214 do
00215 {
00216 ++i_;
00217 if (h_[i_] != 0)
00218 sum_ -= h_[i_];
00219 }
00220 while (sum_ != 0);
00221 t_ = s_[i_];
00222 }
00223
00224 template <typename V>
00225 inline
00226 void
00227 max_h<V>::go_minus_() const
00228 {
00229 do
00230 --i_;
00231 while (h_[i_] == 0);
00232 t_ = s_[i_];
00233 }
00234
00235 template <typename V>
00236 inline
00237 void
00238 max_h<V>::init()
00239 {
00240 h_.init();
00241 sum_ = 0;
00242 i_ = mln_min(argument);
00243 t_ = s_[i_];
00244 valid_ = true;
00245 }
00246
00247 template <typename V>
00248 inline
00249 void
00250 max_h<V>::take_as_init_(const argument& t)
00251 {
00252 h_.take(t);
00253 sum_ = 0;
00254 i_ = s_.index_of(t);
00255 t_ = t;
00256 valid_ = true;
00257 }
00258
00259 template <typename V>
00260 inline
00261 const typename max_h<V>::argument&
00262 max_h<V>::to_result() const
00263 {
00264 if (! valid_)
00265 update_();
00266 return t_;
00267 }
00268
00269 template <typename V>
00270 inline
00271 const accu::histo<V>&
00272 max_h<V>::histo() const
00273 {
00274 return h_;
00275 }
00276
00277 template <typename V>
00278 inline
00279 bool
00280 max_h<V>::is_valid() const
00281 {
00282 return true;
00283 }
00284
00285 template <typename V>
00286 inline
00287 void
00288 max_h<V>::debug_print_() const
00289 {
00290 std::cout << "h={" << h_ << "} ";
00291 std::cout << "sum=" << sum_ << ' '
00292 << "valid=" << valid_ << ' '
00293 << "i=" << i_ << ' '
00294 << "t=" << t_ << std::endl;
00295 }
00296
00297 template <typename V>
00298 inline
00299 std::ostream& operator<<(std::ostream& ostr, const max_h<V>& m)
00300 {
00301 return ostr << m.to_result();
00302 }
00303
00304 # endif // ! MLN_INCLUDE_ONLY
00305
00306 }
00307
00308 }
00309
00310 }
00311
00312
00313 #endif // ! MLN_ACCU_STAT_MAX_H_HH