Files
tensor/signal/misc_bench_test.go
T
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

160 lines
3.2 KiB
Go

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: MIT
package signal
import (
"testing"
core "sourcedock.dev/petrbalvin/tensor/internal/core"
)
// Signal bulk-path benchmarks: the wavelet filter banks, the spectral
// estimators and the finite-difference stencils at analysis-like sizes.
func benchWave(b *testing.B, seed, n int, shape ...int) *core.Array {
b.Helper()
v := make([]float64, n)
for i := range v {
v[i] = float64(i%31)*float64(seed%5)*0.25 + float64(i%13) - 6
}
a, err := core.FromFloats(v, shape...)
if err != nil {
b.Fatal(err)
}
return a
}
func BenchmarkDWT4096(b *testing.B) {
x := benchWave(b, 1, 4096, 4096)
b.ReportAllocs()
for b.Loop() {
if _, err := DWT(x, 8); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkIDWT4096(b *testing.B) {
x := benchWave(b, 2, 4096, 4096)
coef, err := DWT(x, 8)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
b.ReportAllocs()
for b.Loop() {
if _, err := IDWT(coef, 8); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkCWTMorlet(b *testing.B) {
x := benchWave(b, 3, 4096, 4096)
scales := make([]float64, 32)
for i := range scales {
scales[i] = float64(int(1) << (i / 4))
}
b.ReportAllocs()
for b.Loop() {
if _, err := CWT(x, Morlet, scales, 1.0/512); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkWelchPSD(b *testing.B) {
x := benchWave(b, 4, 1<<16, 1<<16)
b.ReportAllocs()
for b.Loop() {
if _, _, err := WelchPSD(x, 1024, 1024, 512, "hann"); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkLombScargle(b *testing.B) {
t := benchWave(b, 5, 2048, 2048)
y := benchWave(b, 6, 2048, 2048)
b.ReportAllocs()
for b.Loop() {
if _, _, err := LombScargle(t, y, 0.01, 1, 512); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkSavitzkyGolay(b *testing.B) {
x := benchWave(b, 7, 1<<18, 1<<18)
b.ReportAllocs()
for b.Loop() {
if _, err := SavitzkyGolay(x, 11, 3); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkFilterApply(b *testing.B) {
x := benchWave(b, 8, 1<<18, 1<<18)
coefB, coefA, err := ButterworthLowPass(4, 1024, 64)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
b.ReportAllocs()
for b.Loop() {
if _, err := FilterApply(coefB, coefA, x); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkLaplacian2D(b *testing.B) {
g := benchWave(b, 9, 512*512, 512, 512)
b.ReportAllocs()
for b.Loop() {
if _, err := Laplacian(g, 1, 1); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkARMASpectrum(b *testing.B) {
res := &ARMAResult{
AR: []float64{0.75, -0.5, 0.2, -0.1},
MA: []float64{0.4, -0.25, 0.1},
InnovationVariance: 1.5,
}
b.ReportAllocs()
for b.Loop() {
if _, _, err := ARMASpectrum(res, 4096); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkNUFFTType1(b *testing.B) {
const n = 4096
xv := make([]float64, n)
cv := make([]complex128, n)
for i := range n {
xv[i] = float64(i%1024)/1024 - 0.5
cv[i] = complex(float64(i%7)*0.5-1, float64(i%5)*0.25)
}
xs, err := core.FromFloats(xv, n)
if err != nil {
b.Fatal(err)
}
cs, err := core.FromComplexes(cv, n)
if err != nil {
b.Fatal(err)
}
b.ReportAllocs()
for b.Loop() {
if _, err := NUFFTType1(xs, cs, 2048); err != nil {
b.Fatal(err)
}
}
}