forked from Snider/Poindexter
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>
63 lines
1.3 KiB
Go
63 lines
1.3 KiB
Go
package poindexter
|
|
|
|
import "math"
|
|
|
|
// Sum returns the sum of all values. Returns 0 for empty slices.
|
|
func Sum(data []float64) float64 {
|
|
var s float64
|
|
for _, v := range data {
|
|
s += v
|
|
}
|
|
return s
|
|
}
|
|
|
|
// Mean returns the arithmetic mean. Returns 0 for empty slices.
|
|
func Mean(data []float64) float64 {
|
|
if len(data) == 0 {
|
|
return 0
|
|
}
|
|
return Sum(data) / float64(len(data))
|
|
}
|
|
|
|
// Variance returns the population variance. Returns 0 for empty slices.
|
|
func Variance(data []float64) float64 {
|
|
if len(data) == 0 {
|
|
return 0
|
|
}
|
|
m := Mean(data)
|
|
var ss float64
|
|
for _, v := range data {
|
|
d := v - m
|
|
ss += d * d
|
|
}
|
|
return ss / float64(len(data))
|
|
}
|
|
|
|
// StdDev returns the population standard deviation.
|
|
func StdDev(data []float64) float64 {
|
|
return math.Sqrt(Variance(data))
|
|
}
|
|
|
|
// MinMax returns the minimum and maximum values.
|
|
// Returns (0, 0) for empty slices.
|
|
func MinMax(data []float64) (min, max float64) {
|
|
if len(data) == 0 {
|
|
return 0, 0
|
|
}
|
|
min, max = data[0], data[0]
|
|
for _, v := range data[1:] {
|
|
if v < min {
|
|
min = v
|
|
}
|
|
if v > max {
|
|
max = v
|
|
}
|
|
}
|
|
return min, max
|
|
}
|
|
|
|
// IsUnderrepresented returns true if val is below threshold fraction of avg.
|
|
// For example, IsUnderrepresented(3, 10, 0.5) returns true because 3 < 10*0.5.
|
|
func IsUnderrepresented(val, avg, threshold float64) bool {
|
|
return val < avg*threshold
|
|
}
|