npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
StatAccumulator.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_STATACCUMULATOR_HH_
2 #define NPSTAT_STATACCUMULATOR_HH_
3 
4 /*!
5 // \file StatAccumulator.hh
6 //
7 // \brief Single-pass accumulator of statistical summary for a set of numbers
8 //
9 // Author: I. Volobouev
10 //
11 // November 2011
12 */
13 
14 #include <vector>
15 #include <cassert>
16 #include <stdexcept>
17 
18 #include "geners/ClassId.hh"
19 
20 namespace npstat {
21  /**
22  // This class calculates minimum value, maximum value, mean, and standard
23  // deviation for a set of observations. "mean" and "stdev" functions will
24  // cause a runtime exception to be thrown in case "accumulate" function
25  // was never called after the object was created (or after it was reset).
26  //
27  // This code updates a running average, so it should work better than
28  // a "naive" implementation. If you still need to improve the calculation
29  // of the standard deviation, use SampleAccumulator class which remembers
30  // all input points and performs a two-pass calculation.
31  */
33  {
34  public:
36 
37  /** Number of observations processed so far */
38  inline unsigned long count() const {return count_;}
39 
40  /** Minimum value in the processed sample */
41  inline double min() const {return min_;}
42 
43  /** Maximum value in the processed sample */
44  inline double max() const {return max_;}
45 
46  /** Sum of all observations */
47  long double sum() const;
48 
49  /** Accumulated sum of squares */
50  long double sumsq() const;
51 
52  /** Accumulated sample average */
53  double mean() const;
54 
55  /** Estimate of the population standard deviation */
56  double stdev() const;
57 
58  /** Uncertainty of the population mean */
59  double meanUncertainty() const;
60 
61  //@{
62  /** Standard plotting accessor */
63  inline double location() const {return mean();}
64  inline double rangeDown() const {return stdev();}
65  inline double rangeUp() const {return stdev();}
66  //@}
67 
68  /**
69  // Accumulated sample average. Will not throw an exception if
70  // no data is accumulated. Instead, the provided function
71  // argument will be returned.
72  */
73  double noThrowMean(double valueIfNoData=0.0) const;
74 
75  /**
76  // Standard deviation estimate. Will not throw an exception if
77  // no data is accumulated. Instead, the provided function
78  // argument will be returned.
79  */
80  double noThrowStdev(double valueIfNoData=0.0) const;
81 
82  /**
83  // Uncertainty of the mean. Will not throw an exception if
84  // no data is accumulated. Instead, the provided function
85  // argument will be returned.
86  */
87  double noThrowMeanUncertainty(double valueIfNoData=0.0) const;
88 
89  //@{
90  /** Main data accumulating function */
91  void accumulate(double value);
92 
93  inline StatAccumulator& operator+=(const double r)
94  {accumulate(r); return *this;}
95  //@}
96 
97  //@{
98  /** Add the sample from another accumulator */
100 
101  inline StatAccumulator& operator+=(const StatAccumulator& r)
102  {accumulate(r); return *this;}
103  //@}
104 
105  /** Accumulate a product of a StatAccumulator times double */
106  void accumulate(const StatAccumulator&, double w);
107 
108  /** Accumulate a sample */
109  template <typename Numeric>
110  inline void accumulate(const Numeric* values, const unsigned long n)
111  {
112  if (n)
113  {
114  assert(values);
115  for (unsigned long i=0; i<n; ++i)
116  accumulate(static_cast<double>(values[i]));
117  }
118  }
119 
120  /**
121  // The effect of "operator*=" is the same as if all values
122  // were multiplied by "r" for each "accumulate" call
123  */
124  template<typename ConvertibleToLongDouble>
125  inline StatAccumulator& operator*=(const ConvertibleToLongDouble& r)
126  {
127  if (count_)
128  {
129  const long double factor(static_cast<long double>(r));
130  const double scale(factor);
131  sum_ *= factor;
132  sumsq_ *= factor*factor;
133  runningMean_ *= factor;
134  min_ *= scale;
135  max_ *= scale;
136  if (max_ < min_)
137  {
138  const double tmp(min_);
139  min_ = max_;
140  max_ = tmp;
141  }
142  }
143  return *this;
144  }
145 
146  /**
147  // The effect of "operator/=" is the same as if all values
148  // were divided by "r" for each "accumulate" call
149  */
150  template<typename ConvertibleToLongDouble>
151  inline StatAccumulator& operator/=(const ConvertibleToLongDouble& r)
152  {
153  const long double denom = static_cast<long double>(r);
154  if (denom == 0.0L) throw std::domain_error(
155  "In npstat::StatAccumulator::operator/=: "
156  "division by zero");
157  return operator*=(1.0L/denom);
158  }
159 
160  /** Binary multiplication by a double */
161  template<typename ConvertibleToLDouble>
162  inline StatAccumulator operator*(const ConvertibleToLDouble& r) const
163  {
164  StatAccumulator acc(*this);
165  acc *= r;
166  return acc;
167  }
168 
169  /** Binary division by a double */
170  template<typename ConvertibleToLDouble>
171  inline StatAccumulator operator/(const ConvertibleToLDouble& r) const
172  {
173  StatAccumulator acc(*this);
174  acc /= r;
175  return acc;
176  }
177 
178  /** Binary sum with another accumulator */
180  {
181  StatAccumulator acc(*this);
182  acc += r;
183  return acc;
184  }
185 
186  /** Clear all accumulators */
187  void reset();
188 
189  /** Comparison for equality */
190  bool operator==(const StatAccumulator& r) const;
191 
192  /** Logical negation of operator== */
193  inline bool operator!=(const StatAccumulator& r) const
194  {return !(*this == r);}
195 
196  //@{
197  /** Method related to "geners" I/O */
198  inline gs::ClassId classId() const {return gs::ClassId(*this);}
199  bool write(std::ostream& of) const;
200  //@}
201 
202  static inline const char* classname() {return "npstat::StatAccumulator";}
203  static inline unsigned version() {return 2;}
204  static void restore(const gs::ClassId& id, std::istream& in,
205  StatAccumulator* acc);
206  private:
207  void recenter();
208  void recenter(long double newCenter);
209 
210  long double sum_;
211  long double sumsq_;
212  long double runningMean_;
213  double min_;
214  double max_;
215  unsigned long count_;
216  unsigned long nextRecenter_;
217 
218 #ifdef SWIG
219  public:
220  inline StatAccumulator mul2(const double r) const
221  {return operator*(r);}
222 
223  inline StatAccumulator div2(const double r) const
224  {return operator/(r);}
225 
226  inline StatAccumulator& imul2(const double r)
227  {*this *= r; return *this;}
228 
229  inline StatAccumulator& idiv2(const double r)
230  {*this /= r; return *this;}
231 
232  inline double sum2() const {return sum();}
233 
234  inline double sumsq2() const {return sumsq();}
235 
236  inline void accumulate(const std::vector<double>& values)
237  {if (!values.empty()) accumulate(&values[0], values.size());}
238 
239  inline void accumulate(const std::vector<float>& values)
240  {if (!values.empty()) accumulate(&values[0], values.size());}
241 #endif // SWIG
242  };
243 }
244 
245 #endif // NPSTAT_STATACCUMULATOR_HH_
Definition: StatAccumulator.hh:33
StatAccumulator operator/(const ConvertibleToLDouble &r) const
Definition: StatAccumulator.hh:171
long double sumsq() const
void accumulate(const Numeric *values, const unsigned long n)
Definition: StatAccumulator.hh:110
double meanUncertainty() const
unsigned long count() const
Definition: StatAccumulator.hh:38
double location() const
Definition: StatAccumulator.hh:63
double min() const
Definition: StatAccumulator.hh:41
double noThrowMean(double valueIfNoData=0.0) const
double noThrowStdev(double valueIfNoData=0.0) const
double stdev() const
void accumulate(const StatAccumulator &)
bool operator==(const StatAccumulator &r) const
void accumulate(const StatAccumulator &, double w)
double noThrowMeanUncertainty(double valueIfNoData=0.0) const
void accumulate(double value)
bool operator!=(const StatAccumulator &r) const
Definition: StatAccumulator.hh:193
StatAccumulator operator*(const ConvertibleToLDouble &r) const
Definition: StatAccumulator.hh:162
gs::ClassId classId() const
Definition: StatAccumulator.hh:198
StatAccumulator & operator/=(const ConvertibleToLongDouble &r)
Definition: StatAccumulator.hh:151
long double sum() const
double max() const
Definition: StatAccumulator.hh:44
StatAccumulator operator+(const StatAccumulator &r) const
Definition: StatAccumulator.hh:179
StatAccumulator & operator*=(const ConvertibleToLongDouble &r)
Definition: StatAccumulator.hh:125
Definition: AbsArrayProjector.hh:14