24
25 #include "precompiled.hpp"
26 #include "memory/allocation.inline.hpp"
27 #include "utilities/debug.hpp"
28 #include "utilities/globalDefinitions.hpp"
29 #include "utilities/numberSeq.hpp"
30
31 AbsSeq::AbsSeq(double alpha) :
32 _num(0), _sum(0.0), _sum_of_squares(0.0),
33 _davg(0.0), _dvariance(0.0), _alpha(alpha) {
34 }
35
36 void AbsSeq::add(double val) {
37 if (_num == 0) {
38 // if the sequence is empty, the davg is the same as the value
39 _davg = val;
40 // and the variance is 0
41 _dvariance = 0.0;
42 } else {
43 // otherwise, calculate both
44 _davg = (1.0 - _alpha) * val + _alpha * _davg;
45 double diff = val - _davg;
46 _dvariance = (1.0 - _alpha) * diff * diff + _alpha * _dvariance;
47 }
48 }
49
50 double AbsSeq::avg() const {
51 if (_num == 0)
52 return 0.0;
53 else
54 return _sum / total();
55 }
56
57 double AbsSeq::variance() const {
58 if (_num <= 1)
59 return 0.0;
60
61 double x_bar = avg();
62 double result = _sum_of_squares / total() - x_bar * x_bar;
63 if (result < 0.0) {
64 // due to loss-of-precision errors, the variance might be negative
65 // by a small bit
66
|
24
25 #include "precompiled.hpp"
26 #include "memory/allocation.inline.hpp"
27 #include "utilities/debug.hpp"
28 #include "utilities/globalDefinitions.hpp"
29 #include "utilities/numberSeq.hpp"
30
31 AbsSeq::AbsSeq(double alpha) :
32 _num(0), _sum(0.0), _sum_of_squares(0.0),
33 _davg(0.0), _dvariance(0.0), _alpha(alpha) {
34 }
35
36 void AbsSeq::add(double val) {
37 if (_num == 0) {
38 // if the sequence is empty, the davg is the same as the value
39 _davg = val;
40 // and the variance is 0
41 _dvariance = 0.0;
42 } else {
43 // otherwise, calculate both
44 // Formula from "Incremental calculation of weighted mean and variance" by Tony Finch
45 // diff := x - mean
46 // incr := alpha * diff
47 // mean := mean + incr
48 // variance := (1 - alpha) * (variance + diff * incr)
49 // PDF available at https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf
50 // Note: alpha is actually (1.0 - _alpha) in our code
51 double diff = val - _davg;
52 double incr = (1.0 - _alpha) * diff;
53 _davg += incr;
54 _dvariance = _alpha * (_dvariance + diff * incr);
55 }
56 }
57
58 double AbsSeq::avg() const {
59 if (_num == 0)
60 return 0.0;
61 else
62 return _sum / total();
63 }
64
65 double AbsSeq::variance() const {
66 if (_num <= 1)
67 return 0.0;
68
69 double x_bar = avg();
70 double result = _sum_of_squares / total() - x_bar * x_bar;
71 if (result < 0.0) {
72 // due to loss-of-precision errors, the variance might be negative
73 // by a small bit
74
|