Elementa v8.0.0
Minimalistic library for any C++ application (C++11 and up)
Loading...
Searching...
No Matches
histograms.h
Go to the documentation of this file.
1
3#include "elementa/license.inc"
4#include "elementa/checks.inc"
5
6#ifndef ELEMENTA_MATH_STATS_HISTOGRAMS_H
7#define ELEMENTA_MATH_STATS_HISTOGRAMS_H
8
9#include <string>
10#include <cmath>
11#include <vector>
12#include <iterator>
13#include <algorithm>
16
17namespace elementa
18{
19
20namespace math
21{
22
23namespace stats
24{
25
42/* *****************************************************************************
43*
44* Class: Histogram
45*
46*******************************************************************************/
47
50{
51 public:
52
57
62 class BinDef: std::vector< double >
63 {
64 public:
65
67
70 static size_t eq_freq_nbins(size_t ndata)
71 { return(static_cast<size_t>(
72 std::round( 2.0 * std::pow(static_cast<double>(ndata),
73 2.0/5.0)))); }
74
75
77 BinDef(void):numbins_{1} {}
78
80
89 BinDef(double leftmost, double binwidth_or_rightmost, size_t numbins,
90 bool iswidthorright = true,
91 bool addleftinf = false, bool addrightinf = false);
92
94
100 BinDef(long leftcenter, long rightcenter,
101 bool addleftinf = false, bool addrightinf = false);
102
103
105 size_t numbins(void) const noexcept { return(numbins_); }
106
108
110 bool entireReals(void) const noexcept { return(binlefts_.empty()); }
111
113
115 void binBounds(size_t ind, double & left, double & right) const;
116
118 /* Return FALSE if V does not fall within any bin.
119 IND is filled with an index that is from 0 for the leftmost bin
120 (including the left infinite one if any) to numbins()-1 for the
121 rightmost one (including the right infinite if any). */
122 bool whichBin(double v, size_t & ind) const noexcept;
123
125 std::string to_string(void) const;
126
127 private:
128
129 static void checkFiniteness(double v, const std::string & name,
130 const std::string & place);
131 static void checkPositiveness(double v, const std::string & name,
132 const std::string & place,
133 bool orzero = false);
134 static void checkNumbins(size_t numbins, const std::string & place);
135
136 std::vector<double> binlefts_;
137 double rightmost_;
138 bool tominf_,topinf_;
139 size_t numbins_;
140
141 size_t calcnumbins(void) const noexcept
142 { if (binlefts_.empty()) return(1);
143 return(binlefts_.size() + (tominf_ ? 1:0) + (topinf_ ? 1:0)); }
144 };
145
153
156 template <class DIt>
157 Histogram(const DIt & first, const DIt & pastend,
158 const BinDef & bindef,
159 const GetStaDatumFun<DIt> & getdatum = getstadatum_direct<DIt>);
160
168 const BinDef & bindef(void) const { return(*bindef_); }
169
171 size_t numData(void) const noexcept { return(ndata_); }
172
174
176 size_t freq(size_t indbin) const
177 { if (indbin >= frequencies_.size()) ELE_CODE_OUTOFRANGE("");
178 return(frequencies_[indbin]); }
179
181 std::string to_string(void) const;
182
185 private:
186
187 const BinDef * bindef_;
188 std::vector<size_t> frequencies_;
189 size_t ndata_;
190};
191
192
193
194/* ===========================================================================
195
196 ========== IMPLEMENTATION OF TEMPLATES ==========
197
198============================================================================= */
199
200
201/* *****************************************************************************
202*
203* Class: Histogram
204*
205*******************************************************************************/
206
207template <class DIt>
208Histogram::Histogram(const DIt & first, const DIt & pastend,
209 const BinDef & bindef,
210 const GetStaDatumFun<DIt> & getdatum)
211{
212 if (first == pastend) ELE_CODE_INVARG("No data to form histogram");
213 bindef_ = & bindef;
214 if (bindef.entireReals())
215 {
216 ndata_ = std::distance(first,pastend);
217 frequencies_.push_back(ndata_);
218 }
219 else
220 {
221 ndata_ = 0;
222 frequencies_ = std::vector<size_t>(bindef.numbins(),0);
223 auto it{first};
224 size_t ind;
225 while (it != pastend)
226 {
227 if (bindef.whichBin(getdatum(it),ind))
228 {
229 ++(frequencies_[ind]);
230 ++ndata_;
231 }
232 ++it;
233 }
234 }
235}
236
239} // end stats namespace
240
241} // end math namespace
242
243} // end elementa namespace
244
245
246#endif
247
248
Definition of the support (bins) of a histogram.
Definition: histograms.h:63
BinDef(void)
Default constructor: one bin from -inf to +inf.
Definition: histograms.h:77
BinDef(long leftcenter, long rightcenter, bool addleftinf=false, bool addrightinf=false)
Constructor for bins that cover discrete supports.
std::string to_string(void) const
Return an informative text with the summary of the bin definition.
void binBounds(size_t ind, double &left, double &right) const
Fill LEFT and RIGHT with the boundaries of the IND-th bin.
bool entireReals(void) const noexcept
Return TRUE if there is only one bin covering from -inf to +inf.
Definition: histograms.h:110
static size_t eq_freq_nbins(size_t ndata)
Return a reasonable number of bins for a sample with NDATA data.
Definition: histograms.h:70
bool whichBin(double v, size_t &ind) const noexcept
Fill IND with the index of the bin where V lies.
size_t numbins(void) const noexcept
Return the total number of bins, including infinite ones.
Definition: histograms.h:105
BinDef(double leftmost, double binwidth_or_rightmost, size_t numbins, bool iswidthorright=true, bool addleftinf=false, bool addrightinf=false)
Constructor for periodic bins.
#define ELE_CODE_OUTOFRANGE(expl)
To throw an out-of-range exception with an explanation.
Definition: exceptions.h:314
#define ELE_CODE_INVARG(expl)
To throw an invalid-argument exception with an explanation.
Definition: exceptions.h:310
const BinDef & bindef(void) const
Return a reference to the internal ref kept of the bin definition.
Definition: histograms.h:168
size_t freq(size_t indbin) const
Return the frequency calculated for the INDBIN-th bin.
Definition: histograms.h:176
std::string to_string(void) const
Return a string with the information of the histogram.
size_t numData(void) const noexcept
Return the number of data effectively used (within bins) for the hist.
Definition: histograms.h:171
A one-dimensional histogram of data.
Definition: histograms.h:50
Histogram(const DIt &first, const DIt &pastend, const BinDef &bindef, const GetStaDatumFun< DIt > &getdatum=getstadatum_direct< DIt >)
Fill the histogram with the data got by getdatum according to bindef.
Definition: histograms.h:208
std::function< StaDatum(const DatumIterator &) > GetStaDatumFun
A function type that gets a datum from an iterator.
Definition: statistic.h:58