fix(linalg): refuse non-finite input in dense Cholesky, Eigen and rank-one updates

Assisted-by: GLM 5.3 Flash
This commit is contained in:
2026-09-27 11:12:43 +02:00
parent af4ee19703
commit 7bc030c78b
10 changed files with 144 additions and 11 deletions
+18 -1
View File
@@ -5,8 +5,10 @@ package linalg
import (
"math"
"sourcedock.dev/petrbalvin/tensor/internal/core"
"strings"
"testing"
"sourcedock.dev/petrbalvin/tensor/internal/core"
)
// TestSVDReconstruction checks that A = U · Σ · Vᵀ reconstructs A
@@ -477,3 +479,18 @@ func TestHouseholderVectorIntoLargeScale(t *testing.T) {
t.Fatalf("beta = %v for a zero vector, want 0", empty.beta)
}
}
// TestEigenRefusesNonFinite pins that a poisoned matrix never reads as
// symmetric: the guard's comparison cannot see a NaN difference, so the
// entry is refused outright, the way the sparse sibling's symmetry
// check refuses it.
func TestEigenRefusesNonFinite(t *testing.T) {
nan := mustFromFloats(t, []float64{math.NaN(), 0, 0, 1}, 2, 2)
if _, _, err := Eigen(nan); err == nil || !strings.Contains(err.Error(), "not finite") {
t.Fatalf("Eigen(NaN): %v", err)
}
inf := mustFromFloats(t, []float64{math.Inf(1), 0, 0, 1}, 2, 2)
if _, _, err := Eigen(inf); err == nil || !strings.Contains(err.Error(), "not finite") {
t.Fatalf("Eigen(Inf): %v", err)
}
}