Files

39 lines
1.4 KiB
Go
Raw Permalink Normal View History

2026-09-03 10:00:00 +02:00
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: MIT
package core
import "testing"
// TestInterpolateQueryOnKnotTakesTheLeftSegment pins the segment choice
// for a query landing exactly on a knot: the bisection takes the first
// knot at or above the query, so the left segment is used and the query
// sits at its upper end with t exactly 1. With a lower y of zero the
// interpolation is exactly the knot's own y. A repeated knot makes the
// choice observable: the query returns the first of the repeated ys,
// where the right segment would return the second.
func TestInterpolateQueryOnKnotTakesTheLeftSegment(t *testing.T) {
xs := mustFloats(t, []float64{0, 1, 2, 3})
ys := mustFloats(t, []float64{0, 10, 20, 30})
q := mustFloats(t, []float64{1, 2})
out, err := Interpolate(xs, ys, q)
if err != nil {
t.Fatalf("Interpolate: %v", err)
}
for i, w := range []float64{10, 20} {
if got := out.FloatAt(i); got != w {
t.Fatalf("query on knot %v answered %v, want exactly %v", q.FloatAt(i), got, w)
}
}
dup, err := Interpolate(
mustFloats(t, []float64{0, 1, 1, 2}),
mustFloats(t, []float64{10, 20, 30, 40}),
mustFloats(t, []float64{1}))
if err != nil {
t.Fatalf("Interpolate: %v", err)
}
if got := dup.FloatAt(0); got != 20 {
t.Fatalf("query on a repeated knot answered %v, want the left segment's 20", got)
}
}