npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
WeightedStatAccumulator.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_WEIGHTEDSTATACCUMULATOR_HH_
2 #define NPSTAT_WEIGHTEDSTATACCUMULATOR_HH_
3 
4 /*!
5 // \file WeightedStatAccumulator.hh
6 //
7 // \brief Single-pass accumulator of statistical summary for a set of weighted
8 // observations.
9 //
10 // Author: I. Volobouev
11 //
12 // May 2010
13 */
14 
15 #include <utility>
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 of weighted 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  // It is assumed that the weights are known precisely and that the weights
28  // do not depend on the observations (this is important!). Weights can not
29  // be negative.
30  //
31  // This code updates a running average, so it should work better than
32  // a "naive" implementation.
33  */
35  {
36  public:
38 
39  /** Minimum value in the processed sample */
40  inline double min() const {return min_;}
41 
42  /** Maximum value in the processed sample */
43  inline double max() const {return max_;}
44 
45  /** Maximum weight among observations processed so far */
46  inline double maxWeight() const {return maxWeight_;}
47 
48  /** Accumulated sample average */
49  double mean() const;
50 
51  /** Estimate of the population standard deviation */
52  double stdev() const;
53 
54  /** Uncertainty of the population mean */
55  double meanUncertainty() const;
56 
57  //@{
58  /** Standard plotting accessor */
59  inline double location() const {return mean();}
60  inline double rangeDown() const {return stdev();}
61  inline double rangeUp() const {return stdev();}
62  //@}
63 
64  /**
65  // Accumulated sample average. Will not throw an exception if
66  // no data is accumulated. Instead, the provided function
67  // argument will be returned.
68  */
69  double noThrowMean(double valueIfNoData=0.0) const;
70 
71  /**
72  // Standard deviation estimate. Will not throw an exception if
73  // no data is accumulated. Instead, the provided function
74  // argument will be returned.
75  */
76  double noThrowStdev(double valueIfNoData=0.0) const;
77 
78  /**
79  // Uncertainty of the mean. Will not throw an exception if
80  // no data is accumulated. Instead, the provided function
81  // argument will be returned.
82  */
83  double noThrowMeanUncertainty(double valueIfNoData=0.0) const;
84 
85  /**
86  // This method returns the effective number of counts
87  // which is (squared sum of weights)/(sum of squared weights)
88  */
89  double count() const;
90 
91  /**
92  // This method returns the total number of times
93  // the "accumulate(double, double)" method was called since
94  // the last reset (or since the object was created)
95  */
96  inline unsigned long ncalls() const {return callCount_;}
97 
98  /**
99  // This method returns the number of times
100  // the "accumulate(double, double)" method
101  // was called with a positive weight
102  */
103  inline unsigned long nfills() const {return cnt_;}
104 
105  /** Average weight (fills with 0 weight are ignored) */
106  double averageWeight() const;
107 
108  /** Sum of weights accumulated so far */
109  double sumOfWeights() const;
110 
111  /** Sum of squared weights accumulated so far */
112  double sumOfSquaredWeights() const;
113 
114  /** Main data accumulating function */
115  void accumulate(double value, double weight);
116 
117  /** Add the sample from another accumulator */
119 
120  /** Accumulate a product of a WeightedStatAccumulator times double */
121  void accumulate(const WeightedStatAccumulator&, double weight);
122 
123  /**
124  // In this method, it is assumed that the first element
125  // of the pair is the value and the second is the weight
126  */
127  template<typename Pair>
128  inline WeightedStatAccumulator& operator+=(const Pair& pair)
129  {accumulate(pair.first, pair.second); return *this;}
130 
131  /** Add the summary from another accumulator */
133  const WeightedStatAccumulator& r)
134  {accumulate(r); return *this;}
135 
136  /**
137  // The effect of "operator*=" is the same as if all values
138  // were multiplied by "r" for each "accumulate" call
139  */
140  template<typename ConvertibleToDouble>
141  inline WeightedStatAccumulator& operator*=(const ConvertibleToDouble& r)
142  {
143  if (cnt_)
144  {
145  const long double factor(static_cast<long double>(r));
146  const double scale(factor);
147  sum_ *= factor;
148  sumsq_ *= factor*factor;
149  runningMean_ *= factor;
150  min_ *= scale;
151  max_ *= scale;
152  if (max_ < min_)
153  {
154  const double tmp(min_);
155  min_ = max_;
156  max_ = tmp;
157  }
158  }
159  return *this;
160  }
161 
162  /**
163  // The effect of "operator/=" is the same as if all values
164  // were divided by "r" for each "accumulate" call
165  */
166  template<typename ConvertibleToDouble>
167  inline WeightedStatAccumulator& operator/=(const ConvertibleToDouble& r)
168  {
169  const long double denom = static_cast<long double>(r);
170  if (denom == 0.0L) throw std::domain_error(
171  "In npstat::WeightedStatAccumulator::operator/=: "
172  "division by zero");
173  return operator*=(1.0L/denom);
174  }
175 
176  /** Binary multiplication by a double */
177  template<typename ConvToDouble>
178  inline WeightedStatAccumulator operator*(const ConvToDouble& r) const
179  {
180  WeightedStatAccumulator acc(*this);
181  acc *= r;
182  return acc;
183  }
184 
185  /** Binary division by a double */
186  template<typename ConvToDouble>
187  inline WeightedStatAccumulator operator/(const ConvToDouble& r) const
188  {
189  WeightedStatAccumulator acc(*this);
190  acc /= r;
191  return acc;
192  }
193 
194  /** Binary sum with another accumulator */
196  const WeightedStatAccumulator& r) const
197  {
198  WeightedStatAccumulator acc(*this);
199  acc += r;
200  return acc;
201  }
202 
203  /**
204  // Scaling of the weights. The effect is the same as if all
205  // weights were multiplied by "r" for each "accumulate" call.
206  // Note that r can not be negative for this method.
207  */
209 
210  /** Clear all accumulators */
211  void reset();
212 
213  /** Comparison for equality */
214  bool operator==(const WeightedStatAccumulator& r) const;
215 
216  /** Logical negation of operator== */
217  inline bool operator!=(const WeightedStatAccumulator& r) const
218  {return !(*this == r);}
219 
220  //@{
221  /** Method related to "geners" I/O */
222  inline gs::ClassId classId() const {return gs::ClassId(*this);}
223  bool write(std::ostream& of) const;
224  //@}
225 
226  static inline const char* classname()
227  {return "npstat::WeightedStatAccumulator";}
228  static inline unsigned version() {return 2;}
229  static void restore(const gs::ClassId& id, std::istream& in,
230  WeightedStatAccumulator* acc);
231  private:
232  void recenter();
233  void recenter(long double newCenter);
234 
235  long double sum_;
236  long double sumsq_;
237  long double wsum_;
238  long double wsumsq_;
239  long double runningMean_;
240  double min_;
241  double max_;
242  double maxWeight_;
243  unsigned long cnt_;
244  unsigned long callCount_;
245  unsigned long nextRecenter_;
246 
247 #ifdef SWIG
248  public:
249  inline WeightedStatAccumulator mul2(const double r)
250  {return operator*(r);}
251 
252  inline WeightedStatAccumulator div2(const double r)
253  {return operator/(r);}
254 
255  inline WeightedStatAccumulator& imul2(const double r)
256  {*this *= r; return *this;}
257 
258  inline WeightedStatAccumulator& idiv2(const double r)
259  {*this /= r; return *this;}
260 
261  inline WeightedStatAccumulator& operator+=(
262  const std::pair<double,double>& pair)
263  {accumulate(pair.first, pair.second); return *this;}
264 #endif // SWIG
265  };
266 }
267 
268 #endif // NPSTAT_WEIGHTEDSTATACCUMULATOR_HH_
Definition: WeightedStatAccumulator.hh:35
bool operator!=(const WeightedStatAccumulator &r) const
Definition: WeightedStatAccumulator.hh:217
void accumulate(double value, double weight)
WeightedStatAccumulator & operator+=(const Pair &pair)
Definition: WeightedStatAccumulator.hh:128
WeightedStatAccumulator operator/(const ConvToDouble &r) const
Definition: WeightedStatAccumulator.hh:187
double min() const
Definition: WeightedStatAccumulator.hh:40
bool operator==(const WeightedStatAccumulator &r) const
WeightedStatAccumulator & operator/=(const ConvertibleToDouble &r)
Definition: WeightedStatAccumulator.hh:167
double maxWeight() const
Definition: WeightedStatAccumulator.hh:46
WeightedStatAccumulator & operator+=(const WeightedStatAccumulator &r)
Definition: WeightedStatAccumulator.hh:132
void accumulate(const WeightedStatAccumulator &)
double max() const
Definition: WeightedStatAccumulator.hh:43
unsigned long nfills() const
Definition: WeightedStatAccumulator.hh:103
gs::ClassId classId() const
Definition: WeightedStatAccumulator.hh:222
double noThrowMean(double valueIfNoData=0.0) const
void accumulate(const WeightedStatAccumulator &, double weight)
double location() const
Definition: WeightedStatAccumulator.hh:59
unsigned long ncalls() const
Definition: WeightedStatAccumulator.hh:96
double noThrowStdev(double valueIfNoData=0.0) const
WeightedStatAccumulator operator*(const ConvToDouble &r) const
Definition: WeightedStatAccumulator.hh:178
WeightedStatAccumulator & scaleWeights(double r)
double noThrowMeanUncertainty(double valueIfNoData=0.0) const
WeightedStatAccumulator & operator*=(const ConvertibleToDouble &r)
Definition: WeightedStatAccumulator.hh:141
WeightedStatAccumulator operator+(const WeightedStatAccumulator &r) const
Definition: WeightedStatAccumulator.hh:195
Definition: AbsArrayProjector.hh:14