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_HISTO_HH
00027 # define MLN_ACCU_HISTO_HH
00028
00034
00035 # include <vector>
00036 # include <algorithm>
00037
00038 # include <mln/core/concept/value_set.hh>
00039 # include <mln/core/concept/meta_accumulator.hh>
00040 # include <mln/accu/internal/base.hh>
00041 # include <mln/value/set.hh>
00042 # include <mln/histo/array.hh>
00043
00044
00045 namespace mln
00046 {
00047
00048 namespace accu
00049 {
00050
00051
00055 template <typename V>
00056 struct histo :
00057 public mln::accu::internal::base<const std::vector<unsigned>& ,
00058 histo<V> >
00059 {
00060 histo();
00061
00062 typedef V argument;
00063
00066 void take(const argument& t);
00067 void take(const histo<V>& other);
00068 void untake(const argument& t);
00069 void init();
00070
00071 unsigned operator()(const argument& t) const;
00072 unsigned operator[](unsigned i) const;
00073 unsigned nvalues() const;
00074 unsigned sum() const;
00076
00079 const std::vector<unsigned>& vect() const;
00080 const std::vector<unsigned>& to_result() const;
00082
00083 const value::set<V>& vset() const;
00084
00087 bool is_valid() const;
00088
00089 protected:
00090
00091 mln::histo::array<V> h_;
00092 unsigned sum_;
00093 };
00094
00095 template <typename V>
00096 std::ostream& operator<<(std::ostream& ostr, const histo<V>& h);
00097
00098 namespace meta
00099 {
00100
00102 struct histo : public Meta_Accumulator< histo >
00103 {
00104 template <typename V>
00105 struct with
00106 {
00107 typedef accu::histo<V> ret;
00108 };
00109 };
00110
00111 }
00112
00113
00114
00115
00116 # ifndef MLN_INCLUDE_ONLY
00117
00118 template <typename V>
00119 inline
00120 histo<V>::histo()
00121 : h_(),
00122 sum_(0)
00123 {
00124 }
00125
00126 template <typename V>
00127 inline
00128 void
00129 histo<V>::take(const argument& t)
00130 {
00131 ++h_[h_.vset().index_of(t)];
00132 ++sum_;
00133 }
00134
00135 template <typename V>
00136 inline
00137 void
00138 histo<V>::take(const histo<V>& other)
00139 {
00140 for (unsigned i = 0; i < h_.nvalues(); ++i)
00141 h_[i] += other.h_[i];
00142 sum_ += other.sum_;
00143 }
00144
00145 template <typename V>
00146 inline
00147 void
00148 histo<V>::untake(const argument& t)
00149 {
00150 mln_precondition(h_[h_.vset().index_of(t)] > 0);
00151 mln_precondition(sum_ > 0);
00152 --h_[h_.vset().index_of(t)];
00153 --sum_;
00154 }
00155
00156 template <typename V>
00157 inline
00158 void
00159 histo<V>::init()
00160 {
00161 h_.clear();
00162 sum_ = 0;
00163 }
00164
00165 template <typename V>
00166 inline
00167 unsigned
00168 histo<V>::operator()(const argument& t) const
00169 {
00170 return h_[h_.vset().index_of(t)];
00171 }
00172
00173 template <typename V>
00174 inline
00175 unsigned
00176 histo<V>::operator[](unsigned i) const
00177 {
00178 mln_precondition(i < h_.vset().nvalues());
00179 return h_[i];
00180 }
00181
00182 template <typename V>
00183 inline
00184 unsigned
00185 histo<V>::nvalues() const
00186 {
00187 return h_.vset().nvalues();
00188 }
00189
00190 template <typename V>
00191 inline
00192 unsigned
00193 histo<V>::sum() const
00194 {
00195 return sum_;
00196 }
00197
00198 template <typename V>
00199 inline
00200 const std::vector<unsigned>&
00201 histo<V>::vect() const
00202 {
00203 return h_.vect();
00204 }
00205
00206 template <typename V>
00207 inline
00208 const std::vector<unsigned>&
00209 histo<V>::to_result() const
00210 {
00211 return this->vect();
00212 }
00213
00214 template <typename V>
00215 inline
00216 const value::set<V>&
00217 histo<V>::vset() const
00218 {
00219 return h_.vset();
00220 }
00221
00222 template <typename V>
00223 inline
00224 std::ostream& operator<<(std::ostream& ostr, const histo<V>& h)
00225 {
00226 mln_viter(value::set<V>) v(h.vset());
00227 for_all(v)
00228 if (h(v) != 0)
00229 ostr << v << ':' << h(v) << ' ';
00230 return ostr;
00231 }
00232
00233 template <typename V>
00234 inline
00235 bool
00236 histo<V>::is_valid() const
00237 {
00238 return true;
00239 }
00240
00241 # endif // ! MLN_INCLUDE_ONLY
00242
00243 }
00244
00245 }
00246
00247
00248 #endif // ! MLN_ACCU_HISTO_HH