snapshot.
This commit is contained in:
parent
472d04b3fa
commit
814470733e
10 changed files with 187 additions and 54 deletions
14
sequence/array.go
Normal file
14
sequence/array.go
Normal 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]
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package util
|
||||
package sequence
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -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())
|
||||
}
|
|
@ -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)}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package util
|
||||
package sequence
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
|
41
sequence/linear.go
Normal file
41
sequence/linear.go
Normal 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
21
sequence/random.go
Normal 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()
|
||||
}
|
|
@ -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]
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package util
|
||||
package sequence
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
|
Loading…
Reference in a new issue