OpenMS
Histogram.h
Go to the documentation of this file.
1 // Copyright (c) 2002-2023, The OpenMS Team -- EKU Tuebingen, ETH Zurich, and FU Berlin
2 // SPDX-License-Identifier: BSD-3-Clause
3 //
4 // --------------------------------------------------------------------------
5 // $Maintainer: Timo Sachsenberg$
6 // $Authors: Marc Sturm $
7 // --------------------------------------------------------------------------
8 
9 #pragma once
10 
11 //OpenMS
12 #include <OpenMS/CONCEPT/Types.h>
14 
15 //STL
16 #include <vector>
17 #include <cmath>
18 #include <limits>
19 #include <iostream>
20 #include <algorithm>
21 
22 namespace OpenMS
23 {
24  namespace Math
25  {
26 
36  template <typename ValueType = UInt, typename BinSizeType = double>
37  class Histogram
38  {
39 public:
40 
42  typedef typename std::vector<ValueType>::const_iterator ConstIterator;
43 
49  min_(0),
50  max_(0),
51  bin_size_(0)
52  {
53  }
54 
56  Histogram(const Histogram & histogram) :
57  min_(histogram.min_),
58  max_(histogram.max_),
59  bin_size_(histogram.bin_size_),
60  bins_(histogram.bins_)
61  {
62  }
63 
69  Histogram(BinSizeType min, BinSizeType max, BinSizeType bin_size) :
70  min_(min),
71  max_(max),
72  bin_size_(bin_size)
73  {
74  this->initBins_();
75  }
76 
77 
83  template <typename DataIterator>
84  Histogram(DataIterator begin, DataIterator end, BinSizeType min, BinSizeType max, BinSizeType bin_size) :
85  min_(min),
86  max_(max),
87  bin_size_(bin_size)
88  {
89  this->initBins_();
90  for (DataIterator it = begin; it != end; ++it)
91  {
92  this->inc((BinSizeType) *it);
93  }
94  }
95 
97  virtual ~Histogram()
98  {
99  }
100 
102 
104  BinSizeType minBound() const
105  {
106  return min_;
107  }
108 
110  BinSizeType maxBound() const
111  {
112  return max_;
113  }
114 
116  ValueType maxValue() const
117  {
118  return *(std::max_element(bins_.begin(), bins_.end()));
119  }
120 
122  ValueType minValue() const
123  {
124  return *(std::min_element(bins_.begin(), bins_.end()));
125  }
126 
128  BinSizeType binSize() const
129  {
130  return bin_size_;
131  }
132 
134  Size size() const
135  {
136  return bins_.size();
137  }
138 
144  ValueType operator[](Size index) const
145  {
146  if (index >= bins_.size())
147  {
148  throw Exception::IndexOverflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION);
149  }
150  return bins_[index];
151  }
152 
158  BinSizeType centerOfBin(Size bin_index) const
159  {
160  if (bin_index >= bins_.size())
161  {
162  throw Exception::IndexOverflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION);
163  }
164 
165  return (BinSizeType)(min_ + ((BinSizeType)bin_index + 0.5) * bin_size_);
166  }
167 
173  BinSizeType rightBorderOfBin(Size bin_index) const
174  {
175  if (bin_index >= bins_.size())
176  {
177  throw Exception::IndexOverflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION);
178  }
179  if (bin_index + 1 == bins_.size())
180  { // rightmost bin is special. It contains the maximum value - see valueToBin().
181  return std::nextafter(maxBound(), maxBound() + 1);
182  }
183  return (BinSizeType)(min_ + ((BinSizeType) bin_index + 1) * bin_size_);
184  }
185 
191  BinSizeType leftBorderOfBin(Size bin_index) const
192  {
193  if (bin_index >= bins_.size())
194  {
195  throw Exception::IndexOverflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION);
196  }
197 
198  return (BinSizeType)(min_ + (BinSizeType)bin_index * bin_size_);
199  }
200 
206  ValueType binValue(BinSizeType val) const
207  {
208  return bins_[valueToBin(val)];
209  }
210 
218  Size inc(BinSizeType val, ValueType increment = 1)
219  {
220  Size bin_index = this->valueToBin(val);
221  this->bins_[bin_index] += increment;
222  return bin_index;
223  }
224 
232  Size incUntil(BinSizeType val, bool inclusive, ValueType increment = 1)
233  {
234  Size bin_index = this->valueToBin(val);
235  for (Size i = 0; i < bin_index; ++i)
236  {
237  this->bins_[i] += increment;
238  }
239  if (inclusive)
240  {
241  this->bins_[bin_index] += increment;
242  }
243  return bin_index;
244  }
245 
253  Size incFrom(BinSizeType val, bool inclusive, ValueType increment = 1)
254  {
255  Size bin_index = this->valueToBin(val);
256  for (Size i = bin_index + 1; i < this->bins_.size(); ++i)
257  {
258  this->bins_[i] += increment;
259  }
260  if (inclusive)
261  {
262  this->bins_[bin_index] += increment;
263  }
264  return bin_index;
265  }
266 
267  template< typename DataIterator >
268  static void getCumulativeHistogram(DataIterator begin, DataIterator end,
269  bool complement,
270  bool inclusive,
272  {
273  for (DataIterator it = begin; it != end; ++it)
274  {
275  if (complement)
276  {
277  histogram.incUntil(*it, inclusive);
278  }
279  else
280  {
281  histogram.incFrom(*it, inclusive);
282  }
283  }
284  }
285 
286 
292  void reset(BinSizeType min, BinSizeType max, BinSizeType bin_size)
293  {
294  min_ = min;
295  max_ = max;
296  bin_size_ = bin_size;
297  bins_.clear();
298 
299  if (bin_size_ <= 0)
300  {
301  throw Exception::OutOfRange(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION);
302  }
303  else
304  {
305  // if max_ == min_ there is only one bin
306  if (max_ != min_)
307  {
308  bins_.resize(Size(ceil((max_ - min_) / bin_size_)), 0);
309  }
310  else
311  {
312  bins_.resize(1, 0);
313  }
314  }
315  }
316 
321  bool operator==(const Histogram & histogram) const
322  {
323  return min_ == histogram.min_ &&
324  max_ == histogram.max_ &&
325  bin_size_ == histogram.bin_size_ &&
326  bins_ == histogram.bins_;
327  }
328 
330  bool operator!=(const Histogram & histogram) const
331  {
332  return !operator==(histogram);
333  }
334 
336  Histogram & operator=(const Histogram & histogram)
337  {
338  if (&histogram == this) return *this;
339 
340  min_ = histogram.min_;
341  max_ = histogram.max_;
342  bin_size_ = histogram.bin_size_;
343  bins_ = histogram.bins_;
344 
345  return *this;
346  }
347 
349 
354  inline ConstIterator begin() const { return bins_.begin(); }
355 
357  inline ConstIterator end() const { return bins_.end(); }
359 
361  void applyLogTransformation(BinSizeType multiplier)
362  {
363  for (typename std::vector<ValueType>::iterator it = bins_.begin(); it != bins_.end(); ++it)
364  {
365  *it = (ValueType)(multiplier * log((BinSizeType)(*it + 1.0f)));
366  }
367  }
368 
374  Size valueToBin(BinSizeType val) const
375  {
376  //std::cout << "val: " << val << " (min: " << min_ << " max: " << max_ << ")" << std::endl;
377  if (val < min_ || val > max_)
378  {
379  throw Exception::OutOfRange(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION);
380  }
381  if (val == max_)
382  {
383  return Size(bins_.size() - 1);
384  }
385  else
386  {
387  return (Size) floor((val - min_) / bin_size_);
388  }
389  }
390 
391 protected:
393  BinSizeType min_;
395  BinSizeType max_;
397  BinSizeType bin_size_;
399  std::vector<ValueType> bins_;
400 
401 
403  void initBins_()
404  {
405  if (this->bin_size_ <= 0)
406  {
407  throw Exception::OutOfRange(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION);
408  }
409  else
410  {
411  if (this->max_ != this->min_)
412  {
413  this->bins_ = std::vector<ValueType>(Size(ceil((max_ - min_) / bin_size_)), 0);
414  }
415  else
416  { // if max_ == min_ there is only one bin
417  this->bins_ = std::vector<ValueType>(1, 0);
418  }
419  }
420  }
421  };
422 
424  template <typename ValueType, typename BinSizeType>
425  std::ostream & operator<<(std::ostream & os, const Histogram<ValueType, BinSizeType> & hist)
426  {
427  for (Size i = 0; i < hist.size(); ++i)
428  {
429  os << hist.centerOfBin(i) << "\t"<< hist[i] << std::endl;
430  }
431  return os;
432  }
433 
434  } // namespace Math
435 
436 } // namespace OpenMS
437 
Int overflow exception.
Definition: Exception.h:221
Out of range exception.
Definition: Exception.h:287
Representation of a histogram.
Definition: Histogram.h:38
Histogram(BinSizeType min, BinSizeType max, BinSizeType bin_size)
constructor with min, max (inclusive) and bin width
Definition: Histogram.h:69
std::vector< ValueType > bins_
Vector of bins.
Definition: Histogram.h:399
ValueType operator[](Size index) const
returns the value of bin index
Definition: Histogram.h:144
Histogram(DataIterator begin, DataIterator end, BinSizeType min, BinSizeType max, BinSizeType bin_size)
constructor with data iterator and min, max, bin_size parameters
Definition: Histogram.h:84
void applyLogTransformation(BinSizeType multiplier)
Transforms the bin values with f(x)=multiplier*log(x+1)
Definition: Histogram.h:361
BinSizeType bin_size_
Bin size.
Definition: Histogram.h:397
virtual ~Histogram()
destructor
Definition: Histogram.h:97
std::vector< ValueType >::const_iterator ConstIterator
Non-mutable iterator of the bins.
Definition: Histogram.h:42
bool operator!=(const Histogram &histogram) const
Inequality operator.
Definition: Histogram.h:330
BinSizeType max_
Upper bound.
Definition: Histogram.h:395
ValueType maxValue() const
returns the bin with the highest count
Definition: Histogram.h:116
BinSizeType maxBound() const
returns the upper bound (inclusive)
Definition: Histogram.h:110
ConstIterator end() const
Non-mutable iterator pointing after the last bin.
Definition: Histogram.h:357
Size inc(BinSizeType val, ValueType increment=1)
increases the bin corresponding to value val by increment
Definition: Histogram.h:218
ValueType binValue(BinSizeType val) const
returns the value of bin corresponding to the value val
Definition: Histogram.h:206
bool operator==(const Histogram &histogram) const
Equality operator.
Definition: Histogram.h:321
BinSizeType rightBorderOfBin(Size bin_index) const
returns the first value to the right side of the bin with the index bin_index, which is not part of t...
Definition: Histogram.h:173
BinSizeType minBound() const
returns the lower bound (inclusive)
Definition: Histogram.h:104
Histogram & operator=(const Histogram &histogram)
Assignment.
Definition: Histogram.h:336
BinSizeType centerOfBin(Size bin_index) const
returns the center position of the bin with the index bin_index
Definition: Histogram.h:158
BinSizeType leftBorderOfBin(Size bin_index) const
returns the leftmost value of the bin with the index bin_index, which is part of this bin,...
Definition: Histogram.h:191
static void getCumulativeHistogram(DataIterator begin, DataIterator end, bool complement, bool inclusive, Histogram< ValueType, BinSizeType > &histogram)
Definition: Histogram.h:268
void reset(BinSizeType min, BinSizeType max, BinSizeType bin_size)
resets the histogram with the given range and bin size
Definition: Histogram.h:292
Size size() const
returns the number of bins
Definition: Histogram.h:134
ConstIterator begin() const
Non-mutable iterator pointing to the first bin.
Definition: Histogram.h:354
BinSizeType binSize() const
returns the bin size
Definition: Histogram.h:128
Histogram()
default constructor
Definition: Histogram.h:48
ValueType minValue() const
returns the bin with lowest count
Definition: Histogram.h:122
Size incFrom(BinSizeType val, bool inclusive, ValueType increment=1)
Increment all bins from the bin of val to the highest(=last) bin by a certain number of counts.
Definition: Histogram.h:253
Histogram(const Histogram &histogram)
copy constructor
Definition: Histogram.h:56
void initBins_()
initialize the bins
Definition: Histogram.h:403
Size incUntil(BinSizeType val, bool inclusive, ValueType increment=1)
Increment all bins from to lowest(=first) bin up to (and including?) the bin for val by a certain num...
Definition: Histogram.h:232
Size valueToBin(BinSizeType val) const
Returns the bin index a given value belongs to.
Definition: Histogram.h:374
BinSizeType min_
Lower bound.
Definition: Histogram.h:393
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:101
std::ostream & operator<<(std::ostream &os, const Histogram< ValueType, BinSizeType > &hist)
Print the contents to a stream.
Definition: Histogram.h:425
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:22