/
movingaverage.go
61 lines (47 loc) · 1.24 KB
/
movingaverage.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
55
56
57
58
59
60
61
package push
import "fmt"
// MovingAverage represent a moving average
// give a sample size.
type movingAverage struct {
sampleSize int
ring []float64
nextIdx int
samplingComplete bool
}
// newMovingAverage return a new movingAverage
func newMovingAverage(sampleSize int) movingAverage {
if sampleSize <= 0 {
panic("sampleSize must be greather than 0.")
}
return movingAverage{
sampleSize: sampleSize,
ring: make([]float64, sampleSize),
}
}
// average return the average of the sampleSize
// If sampleSize are not compplete it returns 0
func (m movingAverage) average() (float64, error) {
sum := .0
if !m.samplingComplete {
return sum, fmt.Errorf("cannot compute average without a full sampling")
}
for _, value := range m.ring {
sum += value
}
return sum / float64(m.sampleSize), nil
}
// append will insert a new value to the ring and return a copy
// of itself
func (m movingAverage) append(value float64) movingAverage {
nm := newMovingAverage(m.sampleSize)
nm.samplingComplete = m.samplingComplete
for i := range m.ring {
nm.ring[i] = m.ring[i]
}
nm.ring[m.nextIdx] = value
nm.nextIdx = (m.nextIdx + 1) % nm.sampleSize
if nm.nextIdx == 0 {
nm.samplingComplete = true
}
return nm
}