Centralizes common math operations used across core/go-ai, core/go, and core/mining into Poindexter as the math pillar (alongside Borg=data, Enchantrix=encryption). New modules: - stats: Sum, Mean, Variance, StdDev, MinMax, IsUnderrepresented - scale: Lerp, InverseLerp, Remap, RoundToN, Clamp, MinMaxScale - epsilon: ApproxEqual, ApproxZero - score: WeightedScore, Ratio, Delta, DeltaPercent - signal: RampUp, SineWave, Oscillate, Noise (seeded RNG) 235 LOC implementation, 509 LOC tests, zero external deps, WASM-safe. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
57 lines
1.3 KiB
Go
57 lines
1.3 KiB
Go
package poindexter
|
|
|
|
import (
|
|
"math"
|
|
"math/rand"
|
|
)
|
|
|
|
// RampUp returns a linear ramp from 0 to 1 over the given duration.
|
|
// The result is clamped to [0, 1].
|
|
func RampUp(elapsed, duration float64) float64 {
|
|
if duration <= 0 {
|
|
return 1
|
|
}
|
|
return Clamp(elapsed/duration, 0, 1)
|
|
}
|
|
|
|
// SineWave returns a sine value with the given period and amplitude.
|
|
// Output range is [-amplitude, amplitude].
|
|
func SineWave(t, period, amplitude float64) float64 {
|
|
if period == 0 {
|
|
return 0
|
|
}
|
|
return math.Sin(t/period*2*math.Pi) * amplitude
|
|
}
|
|
|
|
// Oscillate modulates a base value with a sine wave.
|
|
// Returns base * (1 + sin(t/period*2π) * amplitude).
|
|
func Oscillate(base, t, period, amplitude float64) float64 {
|
|
if period == 0 {
|
|
return base
|
|
}
|
|
return base * (1 + math.Sin(t/period*2*math.Pi)*amplitude)
|
|
}
|
|
|
|
// Noise generates seeded pseudo-random values.
|
|
type Noise struct {
|
|
rng *rand.Rand
|
|
}
|
|
|
|
// NewNoise creates a seeded noise generator.
|
|
func NewNoise(seed int64) *Noise {
|
|
return &Noise{rng: rand.New(rand.NewSource(seed))}
|
|
}
|
|
|
|
// Float64 returns a random value in [-variance, variance].
|
|
func (n *Noise) Float64(variance float64) float64 {
|
|
return (n.rng.Float64() - 0.5) * 2 * variance
|
|
}
|
|
|
|
// Int returns a random integer in [0, max).
|
|
// Returns 0 if max <= 0.
|
|
func (n *Noise) Int(max int) int {
|
|
if max <= 0 {
|
|
return 0
|
|
}
|
|
return n.rng.Intn(max)
|
|
}
|