2017-04-29 16:19:17 -04:00
|
|
|
package util
|
2016-07-29 21:24:25 -04:00
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
import "math"
|
2016-07-29 21:24:25 -04:00
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
// SequenceProvider is a provider for values for a sequence.
|
|
|
|
type SequenceProvider interface {
|
|
|
|
Len() int
|
|
|
|
GetValue(int) float64
|
2016-07-29 21:24:25 -04:00
|
|
|
}
|
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
// Sequence is a utility wrapper for sequence providers.
|
|
|
|
type Sequence struct {
|
|
|
|
SequenceProvider
|
2016-07-29 21:24:25 -04:00
|
|
|
}
|
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
// Each applies the `mapfn` to all values in the value provider.
|
|
|
|
func (s Sequence) Each(mapfn func(int, float64)) {
|
|
|
|
for i := 0; i < s.Len(); i++ {
|
|
|
|
mapfn(i, s.GetValue(i))
|
2016-07-31 19:54:09 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
// Map applies the `mapfn` to all values in the value provider,
|
|
|
|
// returning a new sequence.
|
|
|
|
func (s Sequence) Map(mapfn func(i int, v float64) float64) Sequence {
|
|
|
|
output := make([]float64, s.Len())
|
|
|
|
for i := 0; i < s.Len(); i++ {
|
|
|
|
mapfn(i, s.GetValue(i))
|
2016-07-29 21:24:25 -04:00
|
|
|
}
|
2017-04-28 19:07:36 -04:00
|
|
|
return Sequence{Array(output)}
|
2016-07-29 21:24:25 -04:00
|
|
|
}
|
2016-07-31 19:54:09 -04:00
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
// Average returns the float average of the values in the buffer.
|
|
|
|
func (s Sequence) Average() float64 {
|
|
|
|
if s.Len() == 0 {
|
|
|
|
return 0
|
2016-07-31 19:54:09 -04:00
|
|
|
}
|
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
var accum float64
|
|
|
|
for i := 0; i < s.Len(); i++ {
|
|
|
|
accum += s.GetValue(i)
|
2016-07-31 19:54:09 -04:00
|
|
|
}
|
2017-04-28 19:07:36 -04:00
|
|
|
return accum / float64(s.Len())
|
2016-07-31 19:54:09 -04:00
|
|
|
}
|
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
// Variance computes the variance of the buffer.
|
|
|
|
func (s Sequence) Variance() float64 {
|
|
|
|
if s.Len() == 0 {
|
|
|
|
return 0
|
2016-07-31 19:54:09 -04:00
|
|
|
}
|
2016-08-01 03:50:32 -04:00
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
m := s.Average()
|
|
|
|
var variance, v float64
|
|
|
|
for i := 0; i < s.Len(); i++ {
|
|
|
|
v = s.GetValue(i)
|
|
|
|
variance += (v - m) * (v - m)
|
2016-08-01 03:50:32 -04:00
|
|
|
}
|
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
return variance / float64(s.Len())
|
2016-08-01 03:50:32 -04:00
|
|
|
}
|
2017-02-28 20:55:48 -05:00
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
// StdDev returns the standard deviation.
|
|
|
|
func (s Sequence) StdDev() float64 {
|
|
|
|
if s.Len() == 0 {
|
|
|
|
return 0
|
2017-02-28 20:55:48 -05:00
|
|
|
}
|
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
return math.Pow(s.Variance(), 0.5)
|
2017-02-28 20:55:48 -05:00
|
|
|
}
|
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
// Array is a wrapper for an array of floats that implements `ValuesProvider`.
|
|
|
|
type Array []float64
|
2017-02-28 20:55:48 -05:00
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
// Len returns the value provider length.
|
|
|
|
func (a Array) Len() int {
|
|
|
|
return len(a)
|
|
|
|
}
|
2017-02-28 20:55:48 -05:00
|
|
|
|
2017-04-28 19:07:36 -04:00
|
|
|
// GetValue returns the value at a given index.
|
|
|
|
func (a Array) GetValue(index int) float64 {
|
|
|
|
return a[index]
|
2017-02-28 20:55:48 -05:00
|
|
|
}
|