route/vendor/github.com/dgryski/go-onlinestats/window.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)
}