Poindexter/signal.go
Claude fa998619dc
feat: Add math modules — stats, scale, epsilon, score, signal
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>
2026-02-16 16:16:49 +00:00

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)
}