81 lines
2.1 KiB
Go
81 lines
2.1 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|||
|
|
// SPDX-License-Identifier: MIT
|
||
|
|
|
||
|
|
package tensor
|
||
|
|
|
||
|
|
import (
|
||
|
|
"math"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
// The facade must forward every domain: one smoke call per package,
|
||
|
|
// through the re-exported names only.
|
||
|
|
func TestFacadeForwardsDomains(t *testing.T) {
|
||
|
|
// core: sum of a vector
|
||
|
|
a, _ := FromFloats([]float64{1, 2, 3}, 3)
|
||
|
|
if got := Sum(a).Int(); got != 6 {
|
||
|
|
t.Fatalf("Sum = %d", got)
|
||
|
|
}
|
||
|
|
// linalg: determinant
|
||
|
|
m, _ := FromFloats([]float64{1, 2, 3, 4}, 2, 2)
|
||
|
|
if det, _ := Det(m); det != -2 {
|
||
|
|
t.Fatalf("Det = %v", det)
|
||
|
|
}
|
||
|
|
// signal: DC of a constant via FFT
|
||
|
|
c, _ := FromFloats([]float64{2, 2, 2, 2}, 4)
|
||
|
|
spec, err := FFT(c)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if real(spec.ComplexAt(0)) != 8 {
|
||
|
|
t.Fatalf("FFT DC = %v", spec.ComplexAt(0))
|
||
|
|
}
|
||
|
|
// integrate: BDF2 on decay
|
||
|
|
dy := func(t float64, y *Array) (*Array, error) {
|
||
|
|
return MulF(y, -1), nil
|
||
|
|
}
|
||
|
|
e, err := IntegrateBDF2(dy, 0, 1, mustFromFloatsT(t, 1), ODEOptions{MaxSteps: 100})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if math.Abs(e.FloatAt(0)-1/math.E) > 1e-3 {
|
||
|
|
t.Fatalf("BDF2 decay = %v", e.FloatAt(0))
|
||
|
|
}
|
||
|
|
// stats: median
|
||
|
|
med, err := Median(FromFloatsMustT(t, []float64{3, 1, 2}))
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if med != 2 {
|
||
|
|
t.Fatalf("Median = %v", med)
|
||
|
|
}
|
||
|
|
// optim: Brent root of cos(x) - x
|
||
|
|
root, err := FindRoot(func(x float64) float64 { return math.Cos(x) - x }, 0, 1, 0)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if math.Abs(root-0.7390851332151607) > 1e-9 {
|
||
|
|
t.Fatalf("root = %v", root)
|
||
|
|
}
|
||
|
|
// grad: simple backward
|
||
|
|
x := FromArray(mustFromFloatsT(t, 2), true)
|
||
|
|
loss, _ := x.Mul(x)
|
||
|
|
l, _ := loss.Sum()
|
||
|
|
if err := l.Backward(); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if g := x.Grad().FloatAt(0); g != 4 {
|
||
|
|
t.Fatalf("d/dx x^2 at 2 = %v", g)
|
||
|
|
}
|
||
|
|
// core: the scalar elliptic functions
|
||
|
|
if got := EllipticKScalar(0.5); math.Abs(got-1.8540746773013719) > 1e-12 {
|
||
|
|
t.Fatalf("EllipticKScalar = %v", got)
|
||
|
|
}
|
||
|
|
if got := EllipticFScalar(0.3, 0.5); math.Abs(got-0.30225466857501754) > 1e-12 {
|
||
|
|
t.Fatalf("EllipticFScalar = %v", got)
|
||
|
|
}
|
||
|
|
if got := JacobiCDScalar(0.4, 0.5); math.Abs(got-0.9592196373527547) > 1e-12 {
|
||
|
|
t.Fatalf("JacobiCDScalar = %v", got)
|
||
|
|
}
|
||
|
|
}
|