Pottu
binners.hpp
Go to the documentation of this file.
1 
6 #ifndef H_BINNERS
7 #define H_BINNERS
8 
9 #include <type_traits>
10 #include <cassert>
11 #include <stdexcept>
12 
13 
14 namespace pottu {
15 
18  template <class V>
19  class BinnerFloat {
20  public:
21  typedef V value_type;
22 
23  BinnerFloat( value_type low_, value_type high_, unsigned int binc )
24  : _low(low_), _high(high_), _binc(binc),
25  _step( (_high-_low)/binc ) {
26  static_assert( std::is_floating_point<V>::value, "Template argument for BinnerFloat must be floating point type." );
27  if( binc < 1 )
28  throw std::runtime_error( "Bincount must be larger than one!" );
29  }
30  BinnerFloat( const BinnerFloat &o ) = default;
31  BinnerFloat( BinnerFloat &&o ) = default;
32  BinnerFloat &operator=( const BinnerFloat &o ) = default;
33  BinnerFloat &operator=( BinnerFloat &&o ) = default;
34 
35  value_type low() const { return( _low ); }
36  value_type high() const { return( _high ); }
37  unsigned int binCount() const { return( _binc ); }
38 
39  int operator()( value_type v ) const { return( (v-_low)/_step ); }
40 
41  bool isUnderflow( value_type v ) const { return( v < _low ); }
42  bool isOverflow( value_type v ) const { return( v >= _high ); }
43 
44  value_type binWidth() const { return( _step ); }
45  value_type binLow( unsigned int i ) const { return( i * binWidth() ); }
46  value_type binHigh( unsigned int i ) const { return( (i+1)*binWidth() ); }
47  double binCenter( unsigned int i ) const { return( _low + i*_step + 0.5*_step ); }
48 
49 
50  value_type _low;
51  value_type _high;
52  unsigned int _binc;
53  value_type _step;
54  };
55 
56 
57 
60  template <class V>
61  class BinnerInteger {
62  public:
63  typedef V value_type;
64 
65  BinnerInteger( value_type low, value_type high, unsigned int binc )
66  : _low(low), _high(high), _binc(binc),
67  _step( (high-low)/binc )
68  {
69  static_assert( std::is_integral<V>::value, "Template parameter for BinnerInteger must be integer type." );
70  assert( _step != 0 && _high == _low + binc*_step );
71  }
72 
73  BinnerInteger( const BinnerInteger &o ) = default;
74  BinnerInteger( BinnerInteger &&o ) = default;
75  BinnerInteger &operator=( const BinnerInteger &o ) = default;
76  BinnerInteger &operator=( BinnerInteger &&o ) = default;
77 
78  value_type low() const { return( _low ); }
79  value_type high() const { return( _high ); }
80  unsigned int binCount() const { return( _binc ); }
81 
82  int operator()( value_type v ) const { return( (v-_low)/_step ); }
83 
84  bool isUnderflow( value_type v ) const { return( v < _low ); }
85  bool isOverflow( value_type v ) const { return( v >= _high ); }
86 
87  value_type binWidth() const { return( _step ); }
88  value_type binLow( unsigned int i ) const { return( i * binWidth() ); }
89  value_type binHigh( unsigned int i ) const { return( (i+1)*binWidth() ); }
90  double binCenter( unsigned int i ) const { return( _low + i*_step + 0.5*_step ); }
91 
92 
93  value_type _low;
94  value_type _high;
95  unsigned int _binc;
96  value_type _step;
97  };
98 
99 
100 
103  template <class V>
104  class BinnerPow2 {
105  public:
106  typedef V value_type;
107 
108  BinnerPow2( value_type high_bits, value_type bins_bits )
109  : _high_bits(high_bits),
110  _bins_bits(bins_bits),
111  _div_bits( _high_bits-bins_bits )
112  {
113  static_assert( std::is_integral<V>::value && std::is_unsigned<V>::value,
114  "Template parameter for BinnerPow2 must be unsigned integer type." );
115  assert( _high_bits >= 0 && _bins_bits >= 0 );
116  assert( _high_bits >= _bins_bits );
117  // Setting some upper limit for memory usage. 31 bits for bins
118  // is already 2 gigabins!
119  assert( _bins_bits < 32 );
120  }
121 
122  BinnerPow2( const BinnerPow2 &o ) = default;
123  BinnerPow2( BinnerPow2 &&o ) = default;
124  BinnerPow2 &operator=( const BinnerPow2 &o ) = default;
125  BinnerPow2 &operator=( BinnerPow2 &&o ) = default;
126 
127  value_type low() const { return( 0 ); }
128  value_type high() const { return( V(1) << _high_bits ); }
129  unsigned int binCount() const { return( V(1) << _bins_bits ); }
130 
131  int operator()( value_type v ) const noexcept { return( v >> _div_bits ); }
132 
133  bool isUnderflow( value_type v ) const noexcept { return( v < 0 ); }
134  bool isOverflow( value_type v ) const noexcept { return( v >= ( V(1) << _high_bits ) ); }
135 
136  value_type binWidth() const { return( V(1) << _div_bits ); }
137  value_type binLow( unsigned int i ) const { return( i * binWidth() ); }
138  value_type binHigh( unsigned int i ) const { return( (i+1)*binWidth() ); }
139  double binCenter( unsigned int i ) const { return( i*binWidth() + 0.5*binWidth() ); }
140 
141 
142  value_type _high_bits;
143  value_type _bins_bits;
144  value_type _div_bits;
145  };
146 
147 }
148 
149 
150 #endif
Binner with float values.
Definition: binners.hpp:19
Binner with integer values.
Definition: binners.hpp:61
Binner for histograms with integer values and bin counts of powers of two.
Definition: binners.hpp:104
Definition: mainpage.dox:6