-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathAccumulator.h
100 lines (87 loc) · 2.78 KB
/
Accumulator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#ifndef CH1_ACCUMULATOR_H
#define CH1_ACCUMULATOR_H
#include <cmath>
#include <limits>
#include <ostream>
using std::numeric_limits;
using std::ostream;
/**
* The {@code Accumulator} class is a data type for computing the running
* mean, sample standard deviation, and sample variance of a stream of real
* numbers. It provides an example of a mutable data type and a streaming
* algorithm.
* <p>
* This implementation uses a one-pass algorithm that is less susceptible
* to floating-point roundoff error than the more straightforward
* implementation based on saving the sum of the squares of the numbers.
* This technique is due to
* <a href = "https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm">B. P. Welford</a>.
* Each operation takes constant time in the worst case.
* The amount of memory is constant - the data values are not stored.
* <p>
* For additional documentation,
* see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
class Accumulator {
private:
int n = 0; // number of data values
double sumval = 0.0; // sample variance * (n-1)
double mu = 0.0; // sample variance * (n-1)
public:
/**
* Initializes an accumulator.
*/
Accumulator() = default;
/**
* Adds the specified data value to the accumulator.
* @param x the data value
*/
void addDataValue(double x) {
n++;
double delta = x - mu;
mu += delta / n;
sumval += (double) (n - 1) / n * delta * delta;
}
/**
* Returns the mean of the data values.
* @return the mean of the data values
*/
double mean() const {
return mu;
}
/**
* Returns the sample variance of the data values.
* @return the sample variance of the data values
*/
double var() const {
if (n <= 1) return numeric_limits<double>::quiet_NaN();
return sumval / (n - 1);
}
/**
* Returns the sample standard deviation of the data values.
* @return the sample standard deviation of the data values
*/
double stddev() const {
return sqrt(var());
}
/**
* Returns the number of data values.
* @return the number of data values
*/
int count() const {
return n;
}
/**
* Returns a string representation of this accumulator.
* @return a string representation of this accumulator
*/
friend ostream &operator<<(ostream &stream, Accumulator &acc);
};
ostream &operator<<(ostream &stream, Accumulator &acc) {
stream << "n=" << acc.n << ", mean=" << acc.mean() << ", stddev=" << acc.stddev();
}
#endif //CH1_ACCUMULATOR_H