Files
tensor/integrate/cubature_heap_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

113 lines
3.0 KiB
Go

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: MIT
package integrate
import (
"math"
"testing"
)
// cubHeapPop takes the heap's head the way IntegrateND does: the last
// box replaces the root and sifts down.
func cubHeapPop(h []*cubBox) ([]*cubBox, *cubBox) {
top := h[0]
last := len(h) - 1
h[0] = h[last]
h[last] = nil
h = h[:last]
if last > 0 {
cubSiftDown(h)
}
return h, top
}
// TestCubatureBoxHeapOrder pins the order the box heap pops in, the
// substance of the heap replacing the linear scan: the largest finite
// estimate first, the earliest insertion among equals, and a
// non-finite estimate, which only an overflowed measure produces,
// below every finite one.
func TestCubatureBoxHeapOrder(t *testing.T) {
t.Run("larger estimate first", func(t *testing.T) {
h := []*cubBox{{est: 5, seq: 1}, {est: 1, seq: 2}, {est: math.NaN(), seq: 3}, {est: 3, seq: 4}}
for i := range h {
cubSiftUp(h[:i+1])
}
for _, want := range []float64{5, 3, 1} {
var top *cubBox
h, top = cubHeapPop(h)
if top.est != want {
t.Fatalf("popped estimate %v, want %v", top.est, want)
}
}
if h[0].est == h[0].est {
t.Fatalf("a finite estimate %v survived before the non-finite one", h[0].est)
}
})
t.Run("earliest insertion among equals", func(t *testing.T) {
h := []*cubBox{{est: 2, seq: 2}, {est: 2, seq: 0}, {est: 2, seq: 3}, {est: 2, seq: 1}}
for i := range h {
cubSiftUp(h[:i+1])
}
for _, want := range []int{0, 1, 2, 3} {
var top *cubBox
h, top = cubHeapPop(h)
if top.seq != want {
t.Fatalf("popped insertion %d, want %d", top.seq, want)
}
}
})
t.Run("interleaved push and pop", func(t *testing.T) {
h := []*cubBox{{est: 5, seq: 0}}
for _, b := range []*cubBox{{est: 7, seq: 1}, {est: 6, seq: 2}} {
h = append(h, b)
cubSiftUp(h)
}
var top *cubBox
h, top = cubHeapPop(h)
if top.est != 7 {
t.Fatalf("popped estimate %v, want 7", top.est)
}
h = append(h, &cubBox{est: 4, seq: 3})
cubSiftUp(h)
h, top = cubHeapPop(h)
if top.est != 6 {
t.Fatalf("popped estimate %v, want 6", top.est)
}
h, top = cubHeapPop(h)
if top.est != 5 {
t.Fatalf("popped estimate %v, want 5", top.est)
}
})
t.Run("overflowed estimates sort below every finite one", func(t *testing.T) {
// An overflowed measure can carry +Inf, and a corrupted one a
// NaN: both belong at the bottom of the heap, and the insertion
// order holds between them.
h := []*cubBox{
{est: math.Inf(1), seq: 0},
{est: 2, seq: 1},
{est: math.NaN(), seq: 2},
{est: 4, seq: 3},
{est: math.Inf(-1), seq: 4},
{est: 3, seq: 5},
}
for i := range h {
cubSiftUp(h[:i+1])
}
for _, want := range []float64{4, 3, 2} {
var top *cubBox
h, top = cubHeapPop(h)
if top.est != want {
t.Fatalf("popped estimate %v, want %v", top.est, want)
}
}
for _, want := range []int{0, 2, 4} {
var top *cubBox
h, top = cubHeapPop(h)
if top.seq != want {
t.Fatalf("popped insertion %d, want %d", top.seq, want)
}
}
})
}