func (s *Stddev) Update(newValue interface{}) interface{} {
	value := newValue.(float64)
	s.values = append(s.values, value)
	if len(s.values) > s.Window {
		s.values = s.values[len(s.values)-s.Window:]
	}
	var sum, sum2 float64
	for _, v := range s.values {
		sum += v
		sum2 += v * v
	}
	total := float64(len(s.values))
	return math.Sqrt((total*sum2 - sum*sum) / (total * total))  
}
Update returns the standard deviation of samples in the window.
package filters
import (
	"fmt"
	"io"
	"math"
	"time"
)
type Filter interface {
	Check(interface{}) bool
	Update(interface{}) interface{}
}
type Model struct {
}
func (t *Model) Check(newValue interface{}) bool { return true }
func (t *Model) Update(newValue interface{}) interface{} {
	return newValue
}
type None struct {
	Model
}
type Sink struct {
	Model
}
func (s *Sink) Check(newValue interface{}) bool {
	return false
}
type Mute struct {
	Duration time.Duration
	previous time.Time
	Model
}
func (m *Mute) Check(newValue interface{}) bool {
	t := time.Now()
	if t.Sub(m.previous) < m.Duration {
		return false
	}
	m.previous = t
	return true
}
type Print struct {
	Writer io.Writer
	Prefix string
	Model
}
func (p *Print) Update(v interface{}) interface{} {
	_, err := fmt.Fprintf(p.Writer, "%s %v\n", p.Prefix, v)
	if err != nil {
		fmt.Printf("%s %v\n", p.Prefix, v)
	}
	return v
}
type OnChange struct {
	Value interface{}
}
func (t *OnChange) Check(newValue interface{}) bool { return t.Value != newValue }
func (t *OnChange) Update(newValue interface{}) interface{} {
	t.Value = newValue
	return newValue
}
type OnValue struct {
	Value interface{}
}
func (t *OnValue) Check(newValue interface{}) bool { return t.Value == newValue }
func (t *OnValue) Update(newValue interface{}) interface{} {
	return newValue
}
type AboveFloat64 struct {
	Value float64
}
func (t *AboveFloat64) Check(newValue interface{}) bool { return newValue.(float64) > t.Value }
func (t *AboveFloat64) Update(newValue interface{}) interface{} {
	return newValue
}
type BelowFloat64 struct {
	Value float64
}
func (t *BelowFloat64) Check(newValue interface{}) bool { return newValue.(float64) < t.Value }
func (t *BelowFloat64) Update(newValue interface{}) interface{} {
	return newValue
}
type MovingAverage struct {
	Window int
	values []float64
}
func NewMovingAverage(size int) Filter {
	return &MovingAverage{Window: size}
}
func (t *MovingAverage) Check(newValue interface{}) bool { return true }
func (t *MovingAverage) Update(newValue interface{}) interface{} {
	t.values = append(t.values, newValue.(float64))
	if len(t.values) > t.Window {
		t.values = t.values[len(t.values)-t.Window:]
	}
	var movingAverage float64
	for _, v := range t.values {
		movingAverage += v
	}
	return movingAverage / float64(len(t.values))
}
type Sigma struct {
	Window int
	Factor float64
	values []float64
	stddev float64
	mean   float64
	Model
}
func (s *Sigma) Check(newValue interface{}) bool {
	value := newValue.(float64)
	if len(s.values) >= s.Window {
		if s.stddev > 0.0 {
			sigma := (value - s.mean) / s.stddev
			if math.Abs(sigma) > s.Factor {
				return true
			}
		}
	}
	s.values = append(s.values, value)
	if len(s.values) > s.Window {
		s.values = s.values[len(s.values)-s.Window:]
	}
	var sum, sum2 float64
	for _, v := range s.values {
		sum += v
		sum2 += v * v
	}
	total := float64(len(s.values))
	s.mean = sum / total
	s.stddev = math.Sqrt((total*sum2 - sum*sum) / (total * total))  
	return false
}
type Stddev struct {
	Window int
	values []float64
	stddev float64
	Model
}