87 lines
1.3 KiB
Go
87 lines
1.3 KiB
Go
|
package onlinestats
|
||
|
|
||
|
// add http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm
|
||
|
|
||
|
import "math"
|
||
|
|
||
|
type Windowed struct {
|
||
|
data []float64
|
||
|
head int
|
||
|
|
||
|
length int
|
||
|
sum float64
|
||
|
}
|
||
|
|
||
|
func NewWindowed(capacity int) *Windowed {
|
||
|
return &Windowed{
|
||
|
data: make([]float64, capacity),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (w *Windowed) Push(n float64) float64 {
|
||
|
old := w.data[w.head]
|
||
|
|
||
|
w.length++
|
||
|
|
||
|
w.data[w.head] = n
|
||
|
w.head++
|
||
|
if w.head >= len(w.data) {
|
||
|
w.head = 0
|
||
|
}
|
||
|
|
||
|
w.sum -= old
|
||
|
w.sum += n
|
||
|
|
||
|
return old
|
||
|
}
|
||
|
|
||
|
func (w *Windowed) Len() int {
|
||
|
if w.length < len(w.data) {
|
||
|
return w.length
|
||
|
}
|
||
|
|
||
|
return len(w.data)
|
||
|
}
|
||
|
|
||
|
func (w *Windowed) Mean() float64 {
|
||
|
return w.sum / float64(w.Len())
|
||
|
}
|
||
|
|
||
|
func (w *Windowed) Var() float64 {
|
||
|
n := float64(w.Len())
|
||
|
mean := w.Mean()
|
||
|
l := w.Len()
|
||
|
|
||
|
sum1 := 0.0
|
||
|
sum2 := 0.0
|
||
|
|
||
|
for i := 0; i < l; i++ {
|
||
|
xm := w.data[i] - mean
|
||
|
sum1 += xm * xm
|
||
|
sum2 += xm
|
||
|
}
|
||
|
|
||
|
return (sum1 - (sum2*sum2)/n) / (n - 1)
|
||
|
}
|
||
|
|
||
|
func (w *Windowed) Stddev() float64 {
|
||
|
return math.Sqrt(w.Var())
|
||
|
}
|
||
|
|
||
|
// Set sets the current windowed data. The length is reset, and Push() will start overwriting the first element of the array.
|
||
|
func (w *Windowed) Set(data []float64) {
|
||
|
if w.data != nil {
|
||
|
w.data = w.data[:0]
|
||
|
}
|
||
|
|
||
|
w.data = append(w.data, data...)
|
||
|
|
||
|
w.sum = 0
|
||
|
for _, v := range w.data {
|
||
|
w.sum += v
|
||
|
}
|
||
|
|
||
|
w.head = 0
|
||
|
w.length = len(data)
|
||
|
}
|