Files
tensor/stats/degenerate_input_pin_test.go
petrbalvin af4ee19703
Release / gates (push) Successful in 4m38s
Test / test (push) Successful in 5m16s
Release / release (push) Successful in 35s
feat: initial release
Assisted-by: GLM 5.3 Flash
2026-09-03 10:00:00 +02:00

75 lines
2.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: MIT
package stats
import (
"sourcedock.dev/petrbalvin/tensor/internal/core"
"testing"
)
// TestPoissonDrawsZeroLambda pins the degenerate distribution: λ = 0
// must draw 0, never the −1 the multiplication loop used to hand back.
func TestPoissonDrawsZeroLambda(t *testing.T) {
g := core.NewGenerator(7)
out, err := PoissonDraws(g, 16, 0)
if err != nil {
t.Fatalf("PoissonDraws: %v", err)
}
for i := range 16 {
if out.FloatAt(i) != 0 {
t.Fatalf("draw %d = %g, want 0", i, out.FloatAt(i))
}
}
}
// TestChiSquareComplexRejects pins the dtype guard.
func TestChiSquareComplexRejects(t *testing.T) {
obs, err := core.FromComplexes([]complex128{1, 2, 3}, 3)
if err != nil {
t.Fatalf("FromComplexes: %v", err)
}
exp, _ := core.FromFloats([]float64{1, 2, 3}, 3)
if _, _, _, err := ChiSquareGoodnessOfFit(obs, exp); err == nil {
t.Fatal("ChiSquareGoodnessOfFit accepted complex observed")
}
if _, _, _, err := ChiSquareGoodnessOfFit(exp, obs); err == nil {
t.Fatal("ChiSquareGoodnessOfFit accepted complex expected")
}
}
// TestBootstrapCIFreshArray pins the documented contract: a statistic
// that retains its argument must observe values frozen at call time,
// never the next resample's mutation through the shared buffer.
func TestBootstrapCIFreshArray(t *testing.T) {
data, err := core.FromFloats([]float64{1, 2, 3, 4, 5, 6, 7, 8}, 8)
if err != nil {
t.Fatalf("FromFloats: %v", err)
}
type snapshot struct {
arr *core.Array
mean float64
}
var kept []snapshot
stat := func(a *core.Array) (float64, error) {
m, err := core.Mean(a)
if err != nil {
return 0, err
}
kept = append(kept, snapshot{a, m})
return m, nil
}
if _, _, err := BootstrapCI(data, stat, 0.9, 8, 42); err != nil {
t.Fatalf("BootstrapCI: %v", err)
}
for i, s := range kept {
m, err := core.Mean(s.arr)
if err != nil {
t.Fatalf("kept[%d] mean: %v", i, err)
}
if m != s.mean {
t.Fatalf("kept[%d] mean drifted from %g to %g (buffer was mutated)", i, s.mean, m)
}
}
}