package ostat import ( "errors" "math" ) // from http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm type OnlineStat struct { n int64 mean float64 m2 float64 Max float64 Min float64 } func NewOnlineStat() *OnlineStat { return &OnlineStat{ Min: math.Inf(1), Max: math.Inf(-1), } } func (os *OnlineStat) Push(v float64) { os.n += 1 if v < os.Min { os.Min = v } if v > os.Max { os.Max = v } delta := v - os.mean os.mean = os.mean + delta/float64(os.n) os.m2 = os.m2 + delta*(v-os.mean) } func (os *OnlineStat) Mean() (float64, error) { if os.n == 0 { return 0.0, errors.New("no data") } return os.mean, nil } func (os *OnlineStat) Variance() (float64, error) { if os.n == 0 { return 0.0, errors.New("no data") } return os.m2 / float64(os.n-1), nil } func (os *OnlineStat) StdDev() (float64, error) { variance, err := os.Variance() return math.Sqrt(variance), err }