feat: initial release
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package integrate
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"sourcedock.dev/petrbalvin/tensor/internal/core"
|
||||
)
|
||||
|
||||
// Regression pins: budgets that did not bound what they
|
||||
// promised, and non-finite states that integrated to no error.
|
||||
|
||||
// TestIntegrateNDDimensionBudget: in 10 dimensions the root box alone
|
||||
// costs 5^10 + 3^10 evaluations, about five times the default budget,
|
||||
// before the first budget check could fire.
|
||||
func TestIntegrateNDDimensionBudget(t *testing.T) {
|
||||
lower := make([]float64, 10)
|
||||
upper := make([]float64, 10)
|
||||
for i := range upper {
|
||||
upper[i] = 1
|
||||
}
|
||||
f := func(x []float64) float64 { return 1 }
|
||||
_, err := IntegrateND(f, lower, upper, CubatureOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "budget") {
|
||||
t.Fatalf("IntegrateND in 10 dimensions under the default budget: err = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestPDEStepCountBound: a dt far below tFinal/1e12 wrapped the step
|
||||
// count conversion, and the silently larger step ran past the wave
|
||||
// equation's CFL check.
|
||||
func TestPDEStepCountBound(t *testing.T) {
|
||||
u0, err := core.FromFloats([]float64{0, 1, 0, 1, 0}, 5)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := IntegrateHeat1D(u0, 1, 0.1, 1, 1e-300, 2, 0, 0); err == nil || !strings.Contains(err.Error(), "1e12") {
|
||||
t.Fatalf("Heat1D with an unhonourable dt: err = %v", err)
|
||||
}
|
||||
u2, err := core.FromFloats([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9}, 3, 3)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := IntegrateHeat2D(u2, 1, 0.1, 0.1, 1, 1e-300, 2, 0, 0, 0, 0); err == nil || !strings.Contains(err.Error(), "1e12") {
|
||||
t.Fatalf("Heat2D with an unhonourable dt: err = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestPDEVerletRejectNonFinite: a NaN or Inf initial state flowed
|
||||
// through the stencils and published an all-NaN history with no error.
|
||||
func TestPDEVerletRejectNonFinite(t *testing.T) {
|
||||
bad, err := core.FromFloats([]float64{1, math.NaN(), 0, 1, 0}, 5)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := IntegrateHeat1D(bad, 1, 0.1, 1, 0.1, 2, 0, 0); err == nil || !strings.Contains(err.Error(), "non-finite") {
|
||||
t.Fatalf("Heat1D on a NaN state: err = %v", err)
|
||||
}
|
||||
q, err := core.FromFloats([]float64{1, math.Inf(1)}, 2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
p, err := core.FromFloats([]float64{0, 0}, 2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
accel := func(x *core.Array) (*core.Array, error) { return core.Copy(x), nil }
|
||||
if _, _, err := IntegrateVerlet(accel, 0, 1, q, p, 2); err == nil || !strings.Contains(err.Error(), "non-finite") {
|
||||
t.Fatalf("Verlet on an Inf state: err = %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user