Files

133 lines
2.5 KiB
Go
Raw Permalink Normal View History

2026-09-03 10:00:00 +02:00
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: MIT
package linalg
import (
"math"
"testing"
core "sourcedock.dev/petrbalvin/tensor/internal/core"
)
// Dense solver benchmarks guard the factorisation kernels. Inputs are
// diagonally dominant so every path stays on the well-conditioned side
// and the timings measure the kernel, not pivoting churn.
func benchMatrix(b *testing.B, n int, spd bool) *core.Array {
b.Helper()
v := make([]float64, n*n)
for i := range n {
for j := range n {
v[i*n+j] = float64((i*7+j*13)%11) - 5
}
v[i*n+i] += float64(n)
if spd {
// Symmetrise, then push the diagonal past the row sum so
// positive definiteness is guaranteed by strict diagonal
// dominance.
for j := i + 1; j < n; j++ {
avg := (v[i*n+j] + v[j*n+i]) / 2
v[i*n+j], v[j*n+i] = avg, avg
}
row := float64(0)
for j := range n {
if j != i {
row += math.Abs(v[i*n+j])
}
}
v[i*n+i] += row
}
}
a, err := core.FromFloats(v, n, n)
if err != nil {
b.Fatal(err)
}
return a
}
func benchRHS(b *testing.B, n int) *core.Array {
b.Helper()
v := make([]float64, n)
for i := range v {
v[i] = float64(i%9) - 4
}
x, err := core.FromFloats(v, n)
if err != nil {
b.Fatal(err)
}
return x
}
func BenchmarkSolve64(b *testing.B) {
a := benchMatrix(b, 64, false)
x := benchRHS(b, 64)
b.ReportAllocs()
for b.Loop() {
if _, err := Solve(a, x); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkSolve256(b *testing.B) {
a := benchMatrix(b, 256, false)
x := benchRHS(b, 256)
b.ReportAllocs()
for b.Loop() {
if _, err := Solve(a, x); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkInv256(b *testing.B) {
a := benchMatrix(b, 256, false)
b.ReportAllocs()
for b.Loop() {
if _, err := Inv(a); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkCholesky256(b *testing.B) {
a := benchMatrix(b, 256, true)
b.ReportAllocs()
for b.Loop() {
if _, err := Cholesky(a); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkQR256(b *testing.B) {
a := benchMatrix(b, 256, false)
b.ReportAllocs()
for b.Loop() {
if _, _, err := QR(a); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkSVD128(b *testing.B) {
a := benchMatrix(b, 128, true)
b.ReportAllocs()
for b.Loop() {
if _, _, _, err := SVD(a); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkDet256(b *testing.B) {
a := benchMatrix(b, 256, false)
b.ReportAllocs()
for b.Loop() {
if _, err := Det(a); err != nil {
b.Fatal(err)
}
}
}