Directory: | ./ |
---|---|
File: | include/hpp/statistics/bin.hh |
Date: | 2025-03-06 12:03:19 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 28 | 58 | 48.3% |
Branches: | 14 | 44 | 31.8% |
Line | Branch | Exec | Source |
---|---|---|---|
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_BIN_HH | ||
18 | #define HPP_STATISTICS_BIN_HH | ||
19 | |||
20 | #include <algorithm> | ||
21 | #include <list> | ||
22 | #include <ostream> | ||
23 | |||
24 | #include "hpp/statistics/config.hh" | ||
25 | #include "hpp/statistics/fwd.hh" | ||
26 | |||
27 | namespace hpp { | ||
28 | namespace statistics { | ||
29 | /// Abstract class representing a bin. | ||
30 | /// | ||
31 | /// Bins are use for statistics. They keep the number of | ||
32 | /// of apparition of a given value. | ||
33 | /// Inherited class should also implement comparison and equality | ||
34 | /// operators. | ||
35 | class HPP_STATISTICS_DLLAPI Bin { | ||
36 | public: | ||
37 | /// Return the number of element in the bin. | ||
38 | 4 | const std::size_t& freq() const { return freq_; } | |
39 | |||
40 | /// Add an occurence | ||
41 | /// \return The frequency after increment; | ||
42 | std::size_t operator++() { return ++freq_; } | ||
43 | |||
44 | /// Add an occurence | ||
45 | /// \return The frequency before increment; | ||
46 | 200 | std::size_t operator++(int) { return freq_++; } | |
47 | |||
48 | /// Print the bin. | ||
49 | ✗ | virtual std::ostream& print(std::ostream& os) const { | |
50 | ✗ | return printValue(os << freq() << " - "); | |
51 | } | ||
52 | |||
53 | /// Print the inner value of the bin. | ||
54 | virtual std::ostream& printValue(std::ostream& os) const = 0; | ||
55 | |||
56 | protected: | ||
57 | /// Constructor | ||
58 | 304 | Bin() : freq_(0) {} | |
59 | 814 | virtual ~Bin() {} | |
60 | |||
61 | private: | ||
62 | /// The number of occurence. | ||
63 | std::size_t freq_; | ||
64 | }; | ||
65 | |||
66 | inline std::ostream& operator<<(std::ostream& os, | ||
67 | const hpp::statistics::Bin& b) { | ||
68 | return b.print(os); | ||
69 | } | ||
70 | |||
71 | /// Template class to do statistics. | ||
72 | /// You should derivate class Bin and construct a class | ||
73 | /// Statistics < YourBin >. | ||
74 | template <typename T> | ||
75 | class HPP_STATISTICS_DLLAPI Statistics { | ||
76 | public: | ||
77 | typedef typename std::list<T> Container; | ||
78 | typedef typename Container::iterator iterator; | ||
79 | typedef typename Container::const_iterator const_iterator; | ||
80 | |||
81 | /// Return the number of occurence of a Bin. | ||
82 | /// \param bin a Bin for which only the value is useful. | ||
83 | /// \note It searches for the equivalent Bin is the set and | ||
84 | /// returns the frequency of the result. | ||
85 | virtual std::size_t freq(const T& bin) const; | ||
86 | |||
87 | /// Return the relative frequency of a Bin. | ||
88 | /// \param bin a Bin for which only the value is useful. | ||
89 | /// \note It searches for the equivalent Bin is the set and | ||
90 | /// returns the frequency of the result. | ||
91 | virtual Proba_t relativeFreq(const T& bin) const; | ||
92 | |||
93 | /// Return the number of times an observation has recorded. It is the | ||
94 | /// total number of observations. | ||
95 | 1 | std::size_t numberOfObservations() const { return counts_; } | |
96 | |||
97 | /// Return the number of bins. | ||
98 | unsigned int numberOfBins() const { return bins_.size(); } | ||
99 | |||
100 | /// Put the results in a stream. | ||
101 | virtual std::ostream& print(std::ostream& os) const; | ||
102 | |||
103 | const_iterator find(const T& bin) const; | ||
104 | |||
105 | template <typename U> | ||
106 | const_iterator find(const U& value) const; | ||
107 | |||
108 | /// Return an iterator pointing at the beginning of | ||
109 | /// the set of bins. | ||
110 | ✗ | const_iterator begin() const { return bins_.begin(); } | |
111 | |||
112 | /// Return an iterator pointing at the end of | ||
113 | /// the set of bins. | ||
114 | 100 | const_iterator end() const { return bins_.end(); } | |
115 | |||
116 | /// Remove all element | ||
117 | void clear() { bins_.clear(); } | ||
118 | |||
119 | protected: | ||
120 | /// Constructor | ||
121 | Statistics(); | ||
122 | |||
123 | /// Increment a Bin | ||
124 | /// \note bin is inserted in the set of bins if it was not | ||
125 | /// already in the set. | ||
126 | virtual T& increment(const T& bin) __attribute__((deprecated)); | ||
127 | |||
128 | /// insert a Bin. | ||
129 | /// \note bin is inserted in the set of bins if it was not | ||
130 | /// already in the set. | ||
131 | virtual iterator insert(const T& bin); | ||
132 | |||
133 | private: | ||
134 | Container bins_; | ||
135 | |||
136 | std::size_t counts_; | ||
137 | }; | ||
138 | |||
139 | template <typename T> | ||
140 | std::ostream& operator<<(std::ostream& os, | ||
141 | const hpp::statistics::Statistics<T>& ss); | ||
142 | } // namespace statistics | ||
143 | } // namespace hpp | ||
144 | |||
145 | /// Implementation | ||
146 | |||
147 | namespace hpp { | ||
148 | namespace statistics { | ||
149 | template <typename T> | ||
150 | ✗ | T& Statistics<T>::increment(const T& b) { | |
151 | ✗ | counts_++; | |
152 | ✗ | iterator it = bins_.begin(); | |
153 | ✗ | for (; it != bins_.end(); it++) { | |
154 | ✗ | if (!(*it < b)) { | |
155 | ✗ | if (!(*it == b)) it = bins_.insert(it, b); | |
156 | ✗ | (*it)++; | |
157 | ✗ | return *it; | |
158 | } | ||
159 | } | ||
160 | ✗ | it = bins_.insert(it, b); | |
161 | ✗ | (*it)++; | |
162 | ✗ | return *it; | |
163 | } | ||
164 | |||
165 | template <typename T> | ||
166 | 200 | typename Statistics<T>::iterator Statistics<T>::insert(const T& b) { | |
167 | 200 | counts_++; | |
168 | 200 | iterator it = bins_.begin(); | |
169 |
2/2✓ Branch 3 taken 5153 times.
✓ Branch 4 taken 101 times.
|
5254 | for (; it != bins_.end(); it++) { |
170 |
2/2✓ Branch 2 taken 99 times.
✓ Branch 3 taken 5054 times.
|
5153 | if (!(*it < b)) { |
171 |
3/4✓ Branch 2 taken 2 times.
✓ Branch 3 taken 97 times.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
99 | if (!(*it == b)) it = bins_.insert(it, b); |
172 | 99 | (*it)++; | |
173 | 99 | return it; | |
174 | } | ||
175 | } | ||
176 |
1/2✓ Branch 2 taken 101 times.
✗ Branch 3 not taken.
|
101 | it = bins_.insert(it, b); |
177 | 101 | (*it)++; | |
178 | 101 | return it; | |
179 | } | ||
180 | |||
181 | template <typename T> | ||
182 | 100 | typename Statistics<T>::const_iterator Statistics<T>::find(const T& b) const { | |
183 |
1/2✓ Branch 4 taken 5050 times.
✗ Branch 5 not taken.
|
5050 | for (const_iterator it = bins_.begin(); it != bins_.end(); it++) { |
184 |
2/2✓ Branch 2 taken 4950 times.
✓ Branch 3 taken 100 times.
|
5050 | if (*it < b) continue; |
185 |
1/2✓ Branch 2 taken 100 times.
✗ Branch 3 not taken.
|
100 | if (*it == b) return it; |
186 | ✗ | break; | |
187 | } | ||
188 | ✗ | return bins_.end(); | |
189 | } | ||
190 | |||
191 | template <typename T> | ||
192 | template <typename U> | ||
193 | 100 | typename Statistics<T>::const_iterator Statistics<T>::find(const U& v) const { | |
194 | 100 | return find(T(v)); | |
195 | } | ||
196 | |||
197 | template <typename T> | ||
198 | 4 | size_t Statistics<T>::freq(const T& b) const { | |
199 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | const_iterator it = std::find(bins_.begin(), bins_.end(), b); |
200 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
4 | if (it == bins_.end()) { |
201 | ✗ | return 0; | |
202 | } | ||
203 | 4 | return it->freq(); | |
204 | } | ||
205 | |||
206 | template <typename T> | ||
207 | ✗ | Proba_t Statistics<T>::relativeFreq(const T& b) const { | |
208 | ✗ | const_iterator it = std::find(bins_.begin(), bins_.end(), b); | |
209 | ✗ | if (it == bins_.end()) { | |
210 | ✗ | return 0; | |
211 | } | ||
212 | ✗ | return (Proba_t)it->freq() / (Proba_t)numberOfObservations(); | |
213 | } | ||
214 | |||
215 | template <typename T> | ||
216 | 2 | Statistics<T>::Statistics() : bins_(), counts_(0) {} | |
217 | |||
218 | template <typename T> | ||
219 | ✗ | std::ostream& Statistics<T>::print(std::ostream& os) const { | |
220 | ✗ | const_iterator it; | |
221 | ✗ | for (it = begin(); it != end(); it++) { | |
222 | ✗ | it->print(os) << std::endl; | |
223 | } | ||
224 | ✗ | os << "Total number of observations: " << numberOfObservations(); | |
225 | ✗ | return os; | |
226 | } | ||
227 | |||
228 | template <typename T> | ||
229 | ✗ | std::ostream& operator<<(std::ostream& os, | |
230 | const hpp::statistics::Statistics<T>& ss) { | ||
231 | ✗ | return ss.print(os); | |
232 | } | ||
233 | } // namespace statistics | ||
234 | } // namespace hpp | ||
235 | |||
236 | #endif // HPP_STATISTICS_BIN_HH | ||
237 |