snapshot.

This commit is contained in:
Will Charczuk 2017-04-29 21:12:39 -07:00
parent 472d04b3fa
commit 814470733e
10 changed files with 187 additions and 54 deletions

14
sequence/array.go Normal file
View file

@ -0,0 +1,14 @@
package sequence
// Array is a wrapper for an array of floats that implements `ValuesProvider`.
type Array []float64
// Len returns the value provider length.
func (a Array) Len() int {
return len(a)
}
// GetValue returns the value at a given index.
func (a Array) GetValue(index int) float64 {
return a[index]
}

View file

@ -1,4 +1,4 @@
package util
package sequence
import (
"fmt"

View file

@ -1,4 +1,4 @@
package util
package sequence
import (
"testing"
@ -6,10 +6,10 @@ import (
"github.com/blendlabs/go-assert"
)
func TestValueBuffer(t *testing.T) {
func TestBuffer(t *testing.T) {
assert := assert.New(t)
buffer := NewValueBuffer()
buffer := NewBuffer()
buffer.Enqueue(1)
assert.Equal(1, buffer.Len())
@ -100,10 +100,10 @@ func TestValueBuffer(t *testing.T) {
assert.Zero(buffer.PeekBack())
}
func TestRingBufferClear(t *testing.T) {
func TestBufferClear(t *testing.T) {
assert := assert.New(t)
buffer := NewValueBuffer()
buffer := NewBuffer()
buffer.Enqueue(1)
buffer.Enqueue(1)
buffer.Enqueue(1)
@ -121,10 +121,10 @@ func TestRingBufferClear(t *testing.T) {
assert.Zero(buffer.PeekBack())
}
func TestRingBufferAsSlice(t *testing.T) {
func TestBufferArray(t *testing.T) {
assert := assert.New(t)
buffer := NewValueBuffer()
buffer := NewBuffer()
buffer.Enqueue(1)
buffer.Enqueue(2)
buffer.Enqueue(3)
@ -140,10 +140,10 @@ func TestRingBufferAsSlice(t *testing.T) {
assert.Equal(5, contents[4])
}
func TestRingBufferEach(t *testing.T) {
func TestBufferEach(t *testing.T) {
assert := assert.New(t)
buffer := NewValueBuffer()
buffer := NewBuffer()
for x := 1; x < 17; x++ {
buffer.Enqueue(float64(x))
@ -159,10 +159,10 @@ func TestRingBufferEach(t *testing.T) {
assert.Equal(16, called)
}
func TestNewValueBuffer(t *testing.T) {
func TestNewBuffer(t *testing.T) {
assert := assert.New(t)
empty := NewValueBuffer()
empty := NewBuffer()
assert.NotNil(empty)
assert.Zero(empty.Len())
assert.Equal(valueBufferDefaultCapacity, empty.Capacity())
@ -170,13 +170,24 @@ func TestNewValueBuffer(t *testing.T) {
assert.Zero(empty.PeekBack())
}
func TestNewValueBufferWithValues(t *testing.T) {
func TestNewBufferWithValues(t *testing.T) {
assert := assert.New(t)
values := NewValueBuffer(1, 2, 3, 4)
values := NewBuffer(1, 2, 3, 4, 5)
assert.NotNil(values)
assert.Equal(4, values.Len())
assert.Equal(5, values.Len())
assert.Equal(valueBufferDefaultCapacity, values.Capacity())
assert.Equal(1, values.Peek())
assert.Equal(4, values.PeekBack())
assert.Equal(5, values.PeekBack())
}
func TestBufferGrowth(t *testing.T) {
assert := assert.New(t)
values := NewBuffer(1, 2, 3, 4, 5)
for i := 0; i < 1<<10; i++ {
values.Enqueue(float64(i))
}
assert.Equal(1<<10-1, values.PeekBack())
}

View file

@ -1,4 +1,4 @@
package util
package sequence
import (
"math/rand"
@ -18,7 +18,7 @@ type generate struct {
}
// Values produces an array of floats from [start,end] by optional steps.
func (g generate) Values(start, end float64, steps ...float64) Sequence {
func (g generate) Values(start, end float64, steps ...float64) Seq {
var values []float64
step := 1.0
if len(steps) > 0 {
@ -34,22 +34,22 @@ func (g generate) Values(start, end float64, steps ...float64) Sequence {
values = append(values, x)
}
}
return Sequence{Array(values)}
return Seq{Array(values)}
}
// Random generates a fixed length sequence of random values between (0, scale).
func (g generate) RandomValues(samples int, scale float64) Sequence {
func (g generate) RandomValues(samples int, scale float64) Seq {
values := make([]float64, samples)
for x := 0; x < samples; x++ {
values[x] = g.rnd.Float64() * scale
}
return Sequence{Array(values)}
return Seq{Array(values)}
}
// Random generates a fixed length sequence of random values with a given average, above and below that average by (-scale, scale)
func (g generate) RandomValuesWithAverage(samples int, average, scale float64) Sequence {
func (g generate) RandomValuesWithAverage(samples int, average, scale float64) Seq {
values := make([]float64, samples)
for x := 0; x < samples; x++ {
@ -57,5 +57,5 @@ func (g generate) RandomValuesWithAverage(samples int, average, scale float64) S
values[x] = average + jitter
}
return Sequence{Array(values)}
return Seq{Array(values)}
}

View file

@ -1,4 +1,4 @@
package util
package sequence
import (
"testing"

41
sequence/linear.go Normal file
View file

@ -0,0 +1,41 @@
package sequence
// NewLinear returns a new linear generator.
func NewLinear() *Linear {
return &Linear{}
}
// Linear is a stepwise generator.
type Linear struct {
offset float64
limit float64
step float64
}
// Len returns the number of elements in the sequence.
func (lg Linear) Len() int {
return int((lg.limit - lg.offset) / lg.step)
}
// GetValue returns the value at a given index.
func (lg Linear) GetValue(index int) float64 {
return lg.offset + (float64(index) * lg.step)
}
// WithOffset sets the offset and returns the linear generator.
func (lg *Linear) WithOffset(offset float64) *Linear {
lg.offset = offset
return lg
}
// WithLimit sets the step and returns the linear generator.
func (lg *Linear) WithLimit(limit float64) *Linear {
lg.limit = limit
return lg
}
// WithStep sets the step and returns the linear generator.
func (lg *Linear) WithStep(step float64) *Linear {
lg.step = step
return lg
}

21
sequence/random.go Normal file
View file

@ -0,0 +1,21 @@
package sequence
import "math/rand"
type Random struct {
rnd *rand.Rand
scale *float64
average *float64
len int
}
func (r *Random) Len() int {
return r.len
}
func (r *Random) GetValue(_ int) float64 {
if r.scale != nil {
return r.rnd.Float64() * *r.scale
}
return r.rnd.Float64()
}

View file

@ -1,20 +1,20 @@
package util
package sequence
import "math"
// SequenceProvider is a provider for values for a sequence.
type SequenceProvider interface {
// Provider is a provider for values for a sequence.
type Provider interface {
Len() int
GetValue(int) float64
}
// Sequence is a utility wrapper for sequence providers.
type Sequence struct {
SequenceProvider
// Seq is a utility wrapper for sequence providers.
type Seq struct {
Provider
}
// Each applies the `mapfn` to all values in the value provider.
func (s Sequence) Each(mapfn func(int, float64)) {
func (s Seq) Each(mapfn func(int, float64)) {
for i := 0; i < s.Len(); i++ {
mapfn(i, s.GetValue(i))
}
@ -22,29 +22,62 @@ func (s Sequence) Each(mapfn func(int, float64)) {
// 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 {
func (s Seq) Map(mapfn func(i int, v float64) float64) Seq {
output := make([]float64, s.Len())
for i := 0; i < s.Len(); i++ {
mapfn(i, s.GetValue(i))
}
return Sequence{Array(output)}
return Seq{Array(output)}
}
// Average returns the float average of the values in the buffer.
func (s Sequence) Average() float64 {
// FoldLeft collapses a sequence from left to right.
func (s Seq) FoldLeft(mapfn func(i int, v0, v float64) float64) (v0 float64) {
if s.Len() == 0 {
return 0
}
v0 = s.GetValue(0)
for i := 1; i < s.Len(); i++ {
v0 = mapfn(i, v0, s.GetValue(i))
}
return
}
// FoldRight collapses a sequence from right to left.
func (s Seq) FoldRight(mapfn func(i int, v0, v float64) float64) (v0 float64) {
if s.Len() == 0 {
return 0
}
for i := s.Len() - 1; i >= 0; i-- {
v0 = mapfn(i, v0, s.GetValue(i))
}
return
}
// Sum adds all the elements of a series together.
func (s Seq) Sum() (accum float64) {
if s.Len() == 0 {
return 0
}
var accum float64
for i := 0; i < s.Len(); i++ {
accum += s.GetValue(i)
}
return accum / float64(s.Len())
return
}
// Average returns the float average of the values in the buffer.
func (s Seq) Average() float64 {
if s.Len() == 0 {
return 0
}
return s.Sum() / float64(s.Len())
}
// Variance computes the variance of the buffer.
func (s Sequence) Variance() float64 {
func (s Seq) Variance() float64 {
if s.Len() == 0 {
return 0
}
@ -60,23 +93,10 @@ func (s Sequence) Variance() float64 {
}
// StdDev returns the standard deviation.
func (s Sequence) StdDev() float64 {
func (s Seq) StdDev() float64 {
if s.Len() == 0 {
return 0
}
return math.Pow(s.Variance(), 0.5)
}
// Array is a wrapper for an array of floats that implements `ValuesProvider`.
type Array []float64
// Len returns the value provider length.
func (a Array) Len() int {
return len(a)
}
// GetValue returns the value at a given index.
func (a Array) GetValue(index int) float64 {
return a[index]
}

View file

@ -1 +1,27 @@
package util
package sequence
import (
"testing"
assert "github.com/blendlabs/go-assert"
)
func TestSequenceEach(t *testing.T) {
assert := assert.New(t)
values := Seq{Array([]float64{1, 2, 3, 4})}
values.Each(func(i int, v float64) {
assert.Equal(i, v)
})
}
func TestSequenceMap(t *testing.T) {
assert := assert.New(t)
values := Seq{Array([]float64{1, 2, 3, 4})}
mapped := values.Map(func(i int, v float64) float64 {
assert.Equal(i, v)
return v * 2
})
assert.Equal(4, mapped.Len())
}

View file

@ -1,4 +1,4 @@
package util
package sequence
import (
"time"