hpp-statistics: include/hpp/statistics/distribution.hh Source File

hpp-statistics 9.0.2 Classes for doing statistics.

distribution.hh
Go to the documentation of this file.
1 // Copyright (c) 2014, LAAS-CNRS
2 // Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
3 //
4 // This file is part of hpp-statistics.
5 // hpp-statistics is free software: you can redistribute it
6 // and/or modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation, either version
8 // 3 of the License, or (at your option) any later version.
9 //
10 // hpp-statistics is distributed in the hope that it will be
11 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Lesser Public License for more details. You should have
14 // received a copy of the GNU Lesser General Public License along with
15 // hpp-statistics. If not, see <http://www.gnu.org/licenses/>.
16
17 #ifndef HPP_STATISTICS_DISTRIBUTION_HH
18 #define HPP_STATISTICS_DISTRIBUTION_HH
19
20 #include <assert.h>
21 #include <stdlib.h>
22
23 #include <climits>
24 #include <vector>
25
26 #include "hpp/statistics/fwd.hh"
27
28 namespace hpp {
29 namespace statistics {
30 template <typename Value_t>
31 class DiscreteDistribution {
32 public:
33 typedef std::size_t Weight_t;
34 typedef typename std::pair<Weight_t, Value_t> ProbaTPair;
35 typedef typename std::vector<ProbaTPair>::iterator iterator;
36 typedef typename std::vector<ProbaTPair>::const_iterator const_iterator;
37
38 DiscreteDistribution() = default;
39
40 Value_t operator()() const {
41 assert(values_.size() > 0);
42 Weight_t r = rand() % cumulative_weights_.back();
43 return operator()(r);
44 }
45 Value_t operator()(const Proba_t& p) const {
46 return operator()((Weight_t)(p * cumulative_weights_.back()));
47 }
48 Value_t operator()(const Weight_t& w) const {
49 assert(values_.size() > 0);
50 return values_[dichotomy(w % cumulative_weights_.back())].second;
51 }
52
56 void insert(Value_t v, Weight_t w = 1) {
57 iterator itv = values_.begin();
58 WeightsIterator itcumul = cumulative_weights_.begin();
59 Weight_t c = 0;
60 while (itv != values_.end()) {
61 if (itv->second == v) break;
62 c = *itcumul;
63 itv++;
64 itcumul++;
65 }
66 if (itv == values_.end()) {
67 values_.push_back(ProbaTPair(w, v));
68 cumulative_weights_.push_back(c + w);
69 if (cumulative_weights_.back() >= INT_MAX / 2) shrink();
70 return;
71 }
72 itv->first = w;
73 while (itv != values_.end()) {
74 c = c + itv->first;
75 *itcumul = c;
76 itv++;
77 itcumul++;
78 }
79 if (cumulative_weights_.back() >= INT_MAX / 2) shrink();
80 }
81
84 Weight_t get(const Value_t& v) const {
85 const_iterator itv = values_.begin();
86 while (itv != values_.end()) {
87 if (itv->second == v) return itv->first;
88 itv++;
89 }
90 return 0;
91 }
92
94 size_t size() const { return values_.size(); }
95
97 std::vector<Proba_t> probabilities() const {
98 if (values_.empty()) return std::vector<Proba_t>(0);
99 std::vector<Proba_t> proba(values_.size());
100 Proba_t total = (double)cumulative_weights_.back();
101 for (size_t i = 0; i < values_.size(); i++)
102 proba[i] = (Proba_t)values_[i].first / total;
103 return proba;
104 }
105
107 std::vector<Value_t> values() const {
108 if (values_.empty()) return std::vector<Value_t>(0);
109 std::vector<Value_t> v(values_.size());
110 for (size_t i = 0; i < values_.size(); i++) v[i] = values_[i].second;
111 return v;
112 }
113
115 Weight_t totalWeight() const {
116 if (cumulative_weights_.empty()) return 0;
117 return cumulative_weights_.back();
118 }
119
123 iterator begin() { return values_.begin(); }
124 const_iterator begin() const { return values_.begin(); }
125 iterator end() { return values_.end(); }
126 const_iterator end() const { return values_.end(); }
128 private:
129 size_t dichotomy(const Weight_t& r) const {
130 if (r < cumulative_weights_[0]) return 0;
131 size_t l = 0, h = values_.size() - 1, m;
132 while (l < h - 1) {
133 m = (l + h) / 2;
134 if (cumulative_weights_[m] <= r)
135 l = m;
136 else if (cumulative_weights_[m] > r)
137 h = m;
138 else
139 return m;
140 }
141 return h;
142 }
143
145 void shrink() {
146 iterator itv = values_.begin();
147 WeightsIterator itcumul = cumulative_weights_.begin();
148 Weight_t total = 0;
149 while (itv != values_.end()) {
150 if (itv->first > 1) {
151 itv->first = itv->first >> 1;
152 }
153 total += itv->first;
154 *itcumul = total;
155 itv++;
156 itcumul++;
157 }
158 }
159
160 std::vector<ProbaTPair> values_;
161 std::vector<Weight_t> cumulative_weights_;
162
163 typedef std::vector<Weight_t>::iterator WeightsIterator;
164 };
165 } // namespace statistics
166 } // namespace hpp
167
168 #endif // HPP_STATISTICS_DISTRIBUTION_HH
hpp::statistics::DiscreteDistribution
Definition: distribution.hh:31
hpp::statistics::DiscreteDistribution::iterator
std::vector< ProbaTPair >::iterator iterator
Definition: distribution.hh:35
hpp::statistics::DiscreteDistribution::begin
const_iterator begin() const
Definition: distribution.hh:124
hpp::statistics::DiscreteDistribution::size
size_t size() const
Return the number of value.
Definition: distribution.hh:94
hpp::statistics::DiscreteDistribution::get
Weight_t get(const Value_t &v) const
Definition: distribution.hh:84
hpp::statistics::DiscreteDistribution::end
iterator end()
Definition: distribution.hh:125
hpp::statistics::DiscreteDistribution::const_iterator
std::vector< ProbaTPair >::const_iterator const_iterator
Definition: distribution.hh:36
hpp::statistics::DiscreteDistribution::operator()
Value_t operator()(const Proba_t &p) const
Definition: distribution.hh:45
hpp::statistics::DiscreteDistribution::begin
iterator begin()
Definition: distribution.hh:123
hpp::statistics::DiscreteDistribution::Weight_t
std::size_t Weight_t
Definition: distribution.hh:33
hpp::statistics::DiscreteDistribution::values
std::vector< Value_t > values() const
Return the values.
Definition: distribution.hh:107
hpp::statistics::DiscreteDistribution::DiscreteDistribution
DiscreteDistribution()=default
hpp::statistics::DiscreteDistribution::operator()
Value_t operator()() const
Definition: distribution.hh:40
hpp::statistics::DiscreteDistribution::totalWeight
Weight_t totalWeight() const
Return the total weight.
Definition: distribution.hh:115
hpp::statistics::DiscreteDistribution::ProbaTPair
std::pair< Weight_t, Value_t > ProbaTPair
Definition: distribution.hh:34
hpp::statistics::DiscreteDistribution::probabilities
std::vector< Proba_t > probabilities() const
Return the probabilities.
Definition: distribution.hh:97
hpp::statistics::DiscreteDistribution::insert
void insert(Value_t v, Weight_t w=1)
Definition: distribution.hh:56
hpp::statistics::DiscreteDistribution::operator()
Value_t operator()(const Weight_t &w) const
Definition: distribution.hh:48
hpp::statistics::DiscreteDistribution::end
const_iterator end() const
Definition: distribution.hh:126
fwd.hh
hpp::statistics::Proba_t
double Proba_t
Definition: fwd.hh:22
hpp
Implementation.