| [c4fd03] | 1 | /*
 | 
|---|
 | 2 |  * Histogram.hpp
 | 
|---|
 | 3 |  *
 | 
|---|
 | 4 |  *  Created on: Jul 26, 2012
 | 
|---|
 | 5 |  *      Author: heber
 | 
|---|
 | 6 |  */
 | 
|---|
 | 7 | 
 | 
|---|
 | 8 | #ifndef HISTOGRAM_HPP_
 | 
|---|
 | 9 | #define HISTOGRAM_HPP_
 | 
|---|
 | 10 | 
 | 
|---|
 | 11 | 
 | 
|---|
 | 12 | // include config.h
 | 
|---|
 | 13 | #ifdef HAVE_CONFIG_H
 | 
|---|
 | 14 | #include <config.h>
 | 
|---|
 | 15 | #endif
 | 
|---|
 | 16 | 
 | 
|---|
| [3f6bbb] | 17 | #include <iosfwd>
 | 
|---|
| [c4fd03] | 18 | #include <map>
 | 
|---|
 | 19 | #include <vector>
 | 
|---|
 | 20 | 
 | 
|---|
 | 21 | class HistogramTest;
 | 
|---|
 | 22 | 
 | 
|---|
 | 23 | /** This class generates a histogram from a given vector of sampled values.
 | 
|---|
 | 24 |  *
 | 
|---|
 | 25 |  * Most importantly, it also contains operator+=() and operator-=() to perform
 | 
|---|
 | 26 |  * sum on the \b histograms.
 | 
|---|
 | 27 |  *
 | 
|---|
 | 28 |  * This is to be used with the OrthogonalSummation which requires these specific
 | 
|---|
 | 29 |  * operator implementations.
 | 
|---|
 | 30 |  *
 | 
|---|
 | 31 |  */
 | 
|---|
 | 32 | class Histogram
 | 
|---|
 | 33 | {
 | 
|---|
 | 34 |   //!> grant unit test access to private parts
 | 
|---|
 | 35 |   friend class HistogramTest;
 | 
|---|
| [cf18c5] | 36 |   //!> grant output operator access
 | 
|---|
 | 37 |   friend std::ostream & operator<<(std::ostream &ost, const Histogram &histogram);
 | 
|---|
| [c4fd03] | 38 | public:
 | 
|---|
 | 39 |   //!> named type for a vector of sample values
 | 
|---|
 | 40 |   typedef std::vector<double> samples_t;
 | 
|---|
 | 41 |   //!> named type for the start of a bin
 | 
|---|
 | 42 |   typedef double BinLowerEnd;
 | 
|---|
 | 43 |   //!> named type for the count of a bin, may be fractional
 | 
|---|
 | 44 |   typedef double BinWeight;
 | 
|---|
 | 45 |   //!> named type for the pair identifying a bin by its lower end and count
 | 
|---|
 | 46 |   typedef std::pair< BinLowerEnd, BinWeight> Bin_t;
 | 
|---|
 | 47 | private:
 | 
|---|
 | 48 |   //!> named type for a vector of bins
 | 
|---|
 | 49 |   typedef std::map< BinLowerEnd, BinWeight > Bins_t;
 | 
|---|
 | 50 | public:
 | 
|---|
| [6bed1f] | 51 |   Histogram() :
 | 
|---|
 | 52 |     binwidth(0.5),
 | 
|---|
 | 53 |     offset(0.)
 | 
|---|
 | 54 |   {}
 | 
|---|
 | 55 | 
 | 
|---|
 | 56 |   /** Constructor for class Histogram.
 | 
|---|
 | 57 |    *
 | 
|---|
 | 58 |    * @param offset where the bins should start
 | 
|---|
 | 59 |    * @param binwidth width of the bins
 | 
|---|
 | 60 |    */
 | 
|---|
 | 61 |   Histogram(const BinLowerEnd _offset, const double _binwidth) :
 | 
|---|
 | 62 |     binwidth(_binwidth),
 | 
|---|
 | 63 |     offset(_offset)
 | 
|---|
 | 64 |   {}
 | 
|---|
 | 65 | 
 | 
|---|
| [c4fd03] | 66 |   /** Constructor for class Histogram.
 | 
|---|
 | 67 |    *
 | 
|---|
 | 68 |    * @param samples samples to put in the histogram.
 | 
|---|
| [6bed1f] | 69 |    * @param offset where the bins should start
 | 
|---|
 | 70 |    * @param binwidth width of the bins
 | 
|---|
| [c4fd03] | 71 |    */
 | 
|---|
| [6bed1f] | 72 |   Histogram(const samples_t &samples, const BinLowerEnd _offset, const double _binwidth);
 | 
|---|
| [c4fd03] | 73 | 
 | 
|---|
 | 74 |   /** Adding another histogram onto this one.
 | 
|---|
| [45f4f96] | 75 |    *
 | 
|---|
 | 76 |    * \note The operation is area-conserving, i.e. the new area is the sum of
 | 
|---|
 | 77 |    * both areas.
 | 
|---|
| [c4fd03] | 78 |    *
 | 
|---|
 | 79 |    * @param other other histogram
 | 
|---|
 | 80 |    * @return ref to this instance
 | 
|---|
 | 81 |    */
 | 
|---|
 | 82 |   Histogram& operator+=(const Histogram &other);
 | 
|---|
 | 83 | 
 | 
|---|
 | 84 |   /** Subtracting another histogram from this one.
 | 
|---|
| [45f4f96] | 85 |    *
 | 
|---|
 | 86 |    * \note The operation is area-conserving, i.e. the new area is the
 | 
|---|
 | 87 |    * difference of both areas.
 | 
|---|
| [c4fd03] | 88 |    *
 | 
|---|
 | 89 |    * @param other other histogram
 | 
|---|
 | 90 |    * @return ref to this instance
 | 
|---|
 | 91 |    */
 | 
|---|
 | 92 |   Histogram& operator-=(const Histogram &other);
 | 
|---|
 | 93 | 
 | 
|---|
 | 94 |   /** States whether each bin of this histogram has count of zero.
 | 
|---|
 | 95 |    *
 | 
|---|
 | 96 |    * @return true - all bins are zero, false - else
 | 
|---|
 | 97 |    */
 | 
|---|
 | 98 |   bool isEmpty() const;
 | 
|---|
 | 99 | 
 | 
|---|
| [45f4f96] | 100 |   /** Sums all found weights times the Histogram::binwidth.
 | 
|---|
 | 101 |    *
 | 
|---|
 | 102 |    * @return sum over all weights times width.
 | 
|---|
 | 103 |    */
 | 
|---|
 | 104 |   double area() const;
 | 
|---|
 | 105 | 
 | 
|---|
| [9fd889] | 106 |   /** Adds given vector of samples to the histogram.
 | 
|---|
 | 107 |    *
 | 
|---|
 | 108 |    * @param samples vector of samples to add
 | 
|---|
 | 109 |    */
 | 
|---|
 | 110 |   void addSamples(const samples_t &samples);
 | 
|---|
 | 111 | 
 | 
|---|
| [c4fd03] | 112 | private:
 | 
|---|
| [1c365e] | 113 |   /** Returns the iterator to the bin representing the lower end into which the \a value fits.
 | 
|---|
| [c4fd03] | 114 |    *
 | 
|---|
 | 115 |    * @param _value value to fit.
 | 
|---|
 | 116 |    * @return iterator to bin or to bins.end() if not matching
 | 
|---|
 | 117 |    */
 | 
|---|
| [1c365e] | 118 |   Bins_t::iterator getLowerEndBin(const double _value);
 | 
|---|
 | 119 | 
 | 
|---|
 | 120 |   /** Returns the iterator to the bin representing the upper end into which the \a value fits.
 | 
|---|
 | 121 |    *
 | 
|---|
 | 122 |    * @param _value value to fit.
 | 
|---|
 | 123 |    * @return iterator to bin or to bins.end() if not matching
 | 
|---|
 | 124 |    */
 | 
|---|
 | 125 |   Bins_t::iterator getHigherEndBin(const double _value);
 | 
|---|
| [1dd419] | 126 | 
 | 
|---|
 | 127 |   /** Returns the lower end regardless of whether such a bin exists.
 | 
|---|
 | 128 |    *
 | 
|---|
 | 129 |    * @param _value value to place into a bin
 | 
|---|
 | 130 |    * @return start of would-be bin to contain this \a _value
 | 
|---|
 | 131 |    */
 | 
|---|
 | 132 |   BinLowerEnd getLowerEnd(const double _value) const;
 | 
|---|
 | 133 | 
 | 
|---|
| [22c4f57] | 134 |   /** Helper function that contains all the logic of how to superpose two
 | 
|---|
 | 135 |    * histograms.
 | 
|---|
 | 136 |    *
 | 
|---|
 | 137 |    * Is called by Histogram::operator+=() and Histogram::operator-=()
 | 
|---|
 | 138 |    *
 | 
|---|
 | 139 |    * @param other other histogram
 | 
|---|
 | 140 |    * @param prefactor +1. is then addition, -1. is subtraction.
 | 
|---|
 | 141 |    */
 | 
|---|
 | 142 |   void superposeOtherHistogram(const Histogram &other, const double prefactor);
 | 
|---|
| [c4fd03] | 143 | 
 | 
|---|
| [e4048f] | 144 |   /** Helper function to add missing bins in superposition operation.
 | 
|---|
 | 145 |    *
 | 
|---|
 | 146 |    *  We add here enough bins, initialized to weight zero such that the bin
 | 
|---|
 | 147 |    *  of [LowerEnd, NextLowerEnd) fully fits. Does nothing if the bins are
 | 
|---|
 | 148 |    *  already present.
 | 
|---|
 | 149 |    *
 | 
|---|
 | 150 |    * @param LowerEnd lowerend of the other bin (to superpose)
 | 
|---|
 | 151 |    * @param NextLowerEnd lower end of bin (to superpose) next adjacent to other
 | 
|---|
 | 152 |    */
 | 
|---|
 | 153 |   void extendMissingBins(const BinLowerEnd LowerEnd, const BinLowerEnd NextLowerEnd);
 | 
|---|
 | 154 | 
 | 
|---|
| [e5dbd5] | 155 |   /** Helper function to print BinLowerEnd and BinWeight to a string for every bin.
 | 
|---|
 | 156 |    *
 | 
|---|
 | 157 |    * @return string containing information on each consecutive bin
 | 
|---|
 | 158 |    */
 | 
|---|
 | 159 |   std::string printBins() const;
 | 
|---|
 | 160 | 
 | 
|---|
| [c4fd03] | 161 | private:
 | 
|---|
 | 162 |   //!> vector of bins containing the histogram
 | 
|---|
 | 163 |   Bins_t bins;
 | 
|---|
 | 164 |   //!> width of bin
 | 
|---|
| [bb68c0] | 165 |   const double binwidth;
 | 
|---|
| [6bed1f] | 166 |   //!> offset for the start of the bins
 | 
|---|
 | 167 |   const BinLowerEnd offset;
 | 
|---|
| [c4fd03] | 168 | };
 | 
|---|
 | 169 | 
 | 
|---|
| [3f6bbb] | 170 | /** Function to print an arbitrary pair to ostream.
 | 
|---|
 | 171 |  *
 | 
|---|
 | 172 |  * @param ost output stream
 | 
|---|
 | 173 |  * @param elem element to print
 | 
|---|
 | 174 |  * @return ref to given ostream for concatenation
 | 
|---|
 | 175 |  */
 | 
|---|
 | 176 | std::ostream & operator<<(std::ostream &ost, const Histogram::Bin_t &elem);
 | 
|---|
 | 177 | 
 | 
|---|
| [cf18c5] | 178 | /** Function to print histogram to ostream.
 | 
|---|
 | 179 |  *
 | 
|---|
 | 180 |  * @param ost output stream
 | 
|---|
 | 181 |  * @param histogram histogram to print
 | 
|---|
 | 182 |  * @return ref to given ostream for concatenation
 | 
|---|
 | 183 |  */
 | 
|---|
 | 184 | std::ostream & operator<<(std::ostream &ost, const Histogram &histogram);
 | 
|---|
 | 185 | 
 | 
|---|
| [c4fd03] | 186 | 
 | 
|---|
 | 187 | #endif /* HISTOGRAM_HPP_ */
 | 
|---|