/
dea.go
54 lines (46 loc) · 1.35 KB
/
dea.go
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
package onlinestats
import (
"math"
)
// http://www.drdobbs.com/tools/discontiguous-exponential-averaging/184410671
type DEA struct {
sumOfWeights float64
sumOfData float64
sumOfSquaredData float64
previousTime float64
alpha float64
newDataWeightUpperBound float64
}
func NewDEA(alpha float64, maxDt float64) *DEA {
return &DEA{
alpha: alpha,
newDataWeightUpperBound: 1 - math.Pow(alpha, maxDt),
}
}
func (ew *DEA) Update(newData float64, t float64) {
weightReductionFactor := math.Pow(ew.alpha, t-ew.previousTime)
newDataWeight := minf(1-weightReductionFactor, ew.newDataWeightUpperBound)
ew.sumOfWeights = weightReductionFactor*ew.sumOfWeights + newDataWeight
ew.sumOfData = weightReductionFactor*ew.sumOfData + newDataWeight*newData
ew.sumOfSquaredData = weightReductionFactor*ew.sumOfSquaredData + (newDataWeight * (newData * newData))
ew.previousTime = t
}
func (ew *DEA) CompletenessFraction(t float64) float64 {
return math.Pow(ew.alpha, t-ew.previousTime*ew.sumOfWeights)
}
func (ew *DEA) Mean() float64 {
return (ew.sumOfData / ew.sumOfWeights)
}
func (ew *DEA) Var() float64 {
m := ew.Mean()
return (ew.sumOfSquaredData/ew.sumOfWeights - m*m)
}
func (ew *DEA) Stddev() float64 {
return math.Sqrt(ew.Var())
}
func minf(a, b float64) float64 {
if a < b {
return a
}
return b
}