feat: initial release
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package integrate
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"sourcedock.dev/petrbalvin/tensor/internal/core"
|
||||
)
|
||||
|
||||
// TestFixedStepTimeGrid pins the exact time grid of the fixed-step
|
||||
// solvers: the stage times come from t0 + i·h, never from an
|
||||
// accumulated t += h, whose rounding walks over a long run. On
|
||||
// y' = cos t from t0 = 1e6 the walk used to hold the answer at an
|
||||
// error of 1.1e-8 that no step count refined away; the grid puts RK4
|
||||
// at its own truncation floor and lets the first-order schemes show
|
||||
// their h. The tolerances sit an order below the old walk, so the pin
|
||||
// fails on an accumulated-time build.
|
||||
func TestFixedStepTimeGrid(t *testing.T) {
|
||||
const t0, span, steps = 1e6, 1e-1, 1e5
|
||||
cos := func(t float64, y *core.Array) (*core.Array, error) {
|
||||
return core.FromFloats([]float64{math.Cos(t)}, 1)
|
||||
}
|
||||
exact := math.Sin(t0 + span)
|
||||
end, err := IntegrateRK4(cos, t0, t0+span, mustFloats(t, []float64{math.Sin(t0)}), steps)
|
||||
if err != nil {
|
||||
t.Fatalf("IntegrateRK4: %v", err)
|
||||
}
|
||||
if got := math.Abs(end.FloatAt(0) - exact); got > 1e-11 {
|
||||
t.Fatalf("RK4 error %.3e exceeds 1e-11: the stage times have left the exact grid", got)
|
||||
}
|
||||
end, err = IntegrateBackwardEuler(cos, t0, t0+span, mustFloats(t, []float64{math.Sin(t0)}), 1e6, ODEOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("IntegrateBackwardEuler: %v", err)
|
||||
}
|
||||
if got := math.Abs(end.FloatAt(0) - exact); got > 5e-9 {
|
||||
t.Fatalf("backward Euler error %.3e exceeds 5e-9: the step times have left the exact grid", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user