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
+20 -1
View File
@@ -6,9 +6,11 @@ package linalg
import (
"math"
"math/cmplx"
"strings"
"testing"
"sourcedock.dev/petrbalvin/tensor/internal/base"
"sourcedock.dev/petrbalvin/tensor/internal/core"
"testing"
)
func mustComplexes(t *testing.T, vals []complex128, shape ...int) *core.Array {
@@ -291,3 +293,20 @@ func subComplex(a, b []complex128) []complex128 {
}
return out
}
// TestEigenComplexRefusesNonFinite pins that a poisoned matrix never
// reads as Hermitian: the mirror comparison cannot see a NaN
// difference, so the entry is refused outright, the way the sparse
// sibling's Hermitian check refuses it.
func TestEigenComplexRefusesNonFinite(t *testing.T) {
cv := []complex128{complex(math.NaN(), 0), 0, 0, 1}
a := mustComplexes(t, cv, 2, 2)
if _, _, err := EigenComplex(a); err == nil || !strings.Contains(err.Error(), "not finite") {
t.Fatalf("EigenComplex(NaN): %v", err)
}
cv2 := []complex128{complex(0, math.Inf(1)), 0, 0, 1}
b := mustComplexes(t, cv2, 2, 2)
if _, _, err := EigenComplex(b); err == nil || !strings.Contains(err.Error(), "not finite") {
t.Fatalf("EigenComplex(Inf): %v", err)
}
}