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_MIN_H_HH
00027 # define MLN_ACCU_STAT_MIN_H_HH
00028
00032
00033 # include <mln/accu/internal/base.hh>
00034 # include <mln/accu/histo.hh>
00035 # include <mln/value/set.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 min_h;
00051
00052 }
00053
00054 namespace meta
00055 {
00056
00057 namespace stat
00058 {
00059
00061 struct min_h : public Meta_Accumulator< min_h >
00062 {
00063 template <typename T>
00064 struct with
00065 {
00066 typedef accu::stat::min_h<T> ret;
00067 };
00068 };
00069
00070 }
00071
00072 }
00073
00074
00075 namespace stat
00076 {
00077
00082
00083 template <typename V>
00084 struct min_h : public mln::accu::internal::base< const V& , min_h<V> >
00085 {
00086 typedef V argument;
00087
00088 min_h();
00089
00092 void init();
00093 void take(const argument& t);
00094 void take_as_init_(const argument& t);
00095 void take(const min_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
00130 template <typename I> struct min_h< util::pix<I> >;
00131
00132
00133 # ifndef MLN_INCLUDE_ONLY
00134
00135 template <typename V>
00136 inline
00137 min_h<V>::min_h()
00138 : h_(),
00139 s_(h_.vset())
00140 {
00141 init();
00142 }
00143
00144 template <typename V>
00145 inline
00146 void
00147 min_h<V>::take(const argument& t)
00148 {
00149 if (h_.sum() == 0)
00150 {
00151 this->take_as_init_(t);
00152 return;
00153 }
00154 h_.take(t);
00155 if (t < t_)
00156 {
00157 ++sum_;
00158 valid_ = false;
00159 }
00160 }
00161
00162 template <typename V>
00163 inline
00164 void
00165 min_h<V>::take(const min_h<V>& other)
00166 {
00167
00168 h_.take(other.h_);
00169 for (unsigned i = 0; i < i_; ++i)
00170 sum_ += other.h_[i];
00171 valid_ = false;
00172
00173 }
00174
00175 template <typename V>
00176 inline
00177 void
00178 min_h<V>::untake(const argument& t)
00179 {
00180 mln_precondition(h_(t) != 0);
00181 h_.untake(t);
00182 if (h_.sum() == 0)
00183 {
00184 init();
00185 return;
00186 }
00187 if (t < t_)
00188 {
00189 mln_invariant(sum_ >= 1);
00190 --sum_;
00191 valid_ = false;
00192 }
00193 else
00194 if (t == t_ && h_[i_] == 0)
00195 valid_ = false;
00196 }
00197
00198 template <typename V>
00199 inline
00200 void
00201 min_h<V>::update_() const
00202 {
00203 if (sum_ != 0)
00204 go_minus_();
00205 else
00206 if (h_[i_] == 0)
00207 go_plus_();
00208 valid_ = true;
00209 }
00210
00211 template <typename V>
00212 inline
00213 void
00214 min_h<V>::go_minus_() const
00215 {
00216 do
00217 {
00218 --i_;
00219 if (h_[i_] != 0)
00220 sum_ -= h_[i_];
00221 }
00222 while (sum_ != 0);
00223 t_ = s_[i_];
00224 }
00225
00226 template <typename V>
00227 inline
00228 void
00229 min_h<V>::go_plus_() const
00230 {
00231 do
00232 ++i_;
00233 while (h_[i_] == 0);
00234 t_ = s_[i_];
00235 }
00236
00237 template <typename V>
00238 inline
00239 void
00240 min_h<V>::init()
00241 {
00242 h_.init();
00243 sum_ = 0;
00244 i_ = mln_max(argument);
00245 t_ = s_[i_];
00246 valid_ = true;
00247 }
00248
00249 template <typename V>
00250 inline
00251 void
00252 min_h<V>::take_as_init_(const argument& t)
00253 {
00254 h_.take(t);
00255 sum_ = 0;
00256 i_ = s_.index_of(t);
00257 t_ = t;
00258 valid_ = true;
00259 }
00260
00261 template <typename V>
00262 inline
00263 const typename min_h<V>::argument&
00264 min_h<V>::to_result() const
00265 {
00266 if (! valid_)
00267 update_();
00268 return t_;
00269 }
00270
00271 template <typename V>
00272 inline
00273 const accu::histo<V>&
00274 min_h<V>::histo() const
00275 {
00276 return h_;
00277 }
00278
00279 template <typename V>
00280 inline
00281 bool
00282 min_h<V>::is_valid() const
00283 {
00284 return true;
00285 }
00286
00287
00288 template <typename V>
00289 inline
00290 void
00291 min_h<V>::debug_print_() const
00292 {
00293 std::cout << "h={" << h_ << "} ";
00294 std::cout << "sum=" << sum_ << ' '
00295 << "valid=" << valid_ << ' '
00296 << "i=" << i_ << ' '
00297 << "t=" << t_ << std::endl;
00298 }
00299
00300 template <typename V>
00301 inline
00302 std::ostream& operator<<(std::ostream& ostr, const min_h<V>& m)
00303 {
00304 return ostr << m.to_result();
00305 }
00306
00307 # endif // ! MLN_INCLUDE_ONLY
00308
00309
00310 }
00311
00312 }
00313
00314 }
00315
00316 #endif // ! MLN_ACCU_STAT_MIN_H_HH