Fix QuadraticSpline edge-case crashes: n=2 BoundsError, Rational t starting at 0, duplicate knots#543
Merged
ChrisRackauckas merged 1 commit intoJun 13, 2026
Conversation
Fixes three construction crashes reported in SciML#542: - n = 2 threw a BoundsError: the knot vector for two data points has boundary multiplicity 2 < degree + 1, so the midpoint B-spline basis evaluation in quadratic_spline_parameters under-indexed. The spline now degenerates to the linear interpolant (alpha = 0, beta = u2 - u1), which evaluation, derivative, and integral all share. - Rational t with t[1] == 0 threw a DivideError: the coefficient eltype was computed as typeof(t[1] / t[1]), which evaluates 0//0. Use typeof(one(eltype(t)) / one(eltype(t))) instead. - Duplicate time points threw a raw SingularException from the tridiagonal collocation solve. Construction now throws an informative ArgumentError. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This PR should be ignored until reviewed by @ChrisRackauckas.
Fixes #542.
Changes
n = 2no longer throwsBoundsError. For two data points the knot vector[t1, t1, t2, t2, t2]has boundary multiplicity 2 < degree + 1, so the deficient B-spline basis cannot be evaluated at the interval midpoint inquadratic_spline_parameters(it under-indexed intoN[0]). Since a quadratic spline through two points is underdetermined and the natural choice is the linear interpolant, the parameter computation now special-caseslength(t) == 2withuᵢ₊ = (u[1] + u[2]) / 2, which yieldsα = 0,β = u₂ - u₁— i.e. exactly the linear interpolant. All downstream code paths (evaluation, derivative, integral, cached parameters, vector-valuedu) share these parameters, so they are all fixed by this one change.Rationalknots witht[1] == 0no longer throwDivideError. The coefficient eltype was computed astypeof(t[1] / t[1]), which evaluates0 // 0. Replaced withtypeof(one(eltype(t)) / one(eltype(t)))in all three occurrences (interpolation_utils.jland bothQuadraticSplineconstructors).Duplicate time points now throw an informative
ArgumentErrorinstead of a rawSingularExceptionfrom the tridiagonal collocation solve. Both interior duplicates (t = [0, 1, 1, 2, 3]) and boundary duplicates (t[2] == t[1]) are caught at construction inquadratic_spline_params.Verification
All three failures were reproduced on unmodified
masterbefore the fix (BoundsError,DivideError,SingularExceptionrespectively). After the fix, ran locally:n = 2: evaluation givesA(0.25) == 1.5foru = [1, 3], derivative2.0, integral over the domain2.0— exact linear interpolant; cached-parameters andVector{Vector}constructors verified too.Rational:QuadraticSpline([1//1, 4//1, 9//1], [0//1, 1//1, 2//1])(i.e.u = (t+1)^2) reproduces the quadratic exactly:A(1//2) == 9//4,A(3//2) == 25//4.ArgumentErrorwith a clear message.Tests for all three cases added to the
QuadraticSplinetestset intest/interpolation_tests.jl.🤖 Generated with Claude Code