Sorted-batch evaluators for the remaining piecewise interpolation types (7-13x)#528
Draft
ChrisRackauckas-Claude wants to merge 2 commits into
Draft
Conversation
Extends the pattern from SciML#526 to two more piecewise interpolation types. When the query vector is sorted and the extrapolation modes are simple (None / Constant / Linear / Extension), walk the knots and queries in lockstep in O(n+m) instead of running a per-query binary search via the iguesser. Falls back to `map!` when the inputs don't fit the fast path: unsorted `tt`, Periodic/Reflective extrapolation, or (for LinearInterpolation) `u` containing NaN — preserving the existing NaN-handling semantics from `_interpolate(::LinearInterpolation, ...)`. The scalar `_interpolate`, derivative, integral, AD, and plotting paths are unchanged. Output matches the per-point path to floating-point round-off, verified across each fast-path extrapolation mode paired left × right, both `cache_parameters` settings for CubicSpline, knot pass-through, the Periodic/Reflective fallback, the `None` throwing behavior on out-of-range sorted queries, and the NaN-in-u fallback for LinearInterpolation. Benchmarks (Julia 1.10, n=256, m=4096 sorted queries, BenchmarkTools `minimum`): LinearInterpolation: 126 us -> 13.6 us 9.3x CubicSpline: 167 us -> 19.7 us 8.5x Unsorted-input fallback path stays at ~450 us for both (matches the prior `map!` cost; the `issorted` short-circuits on the first out-of-order pair). Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Extends the sorted-batch fast path to the rest of the piecewise types that have a fixed per-segment polynomial form: - ConstantInterpolation (both :left and :right dir) - QuadraticInterpolation - QuadraticSpline - CubicHermiteSpline - QuinticHermiteSpline Also extracts a shared `_sorted_batch_extrapolation_supported(A)` predicate (None / Constant / Linear / Extension on each side), used by all five new evaluators. The earlier per-type predicates for Akima / Linear / CubicSpline are left in place to keep this PR's diff focused on the new types; they can be folded into the shared helper in a follow-up if desired. The scalar `_interpolate`, derivative, integral, AD, and plotting paths are unchanged. Output matches the per-point path to floating-point round-off across every fast-path extrapolation mode paired left × right, both `cache_parameters` settings for QuadraticSpline, knot pass-through, Periodic/Reflective fallback, the `None` throwing behavior on out-of-range sorted queries, the unsorted fallback, and non-Number eltypes for ConstantInterpolation. Benchmarks (Julia 1.10, n=256, m=4096 sorted queries, BenchmarkTools `minimum`): Type before after speedup ConstantInterpolation 107 us 14.6 us 7.3x QuadraticInterpolation 166 us 15.2 us 10.9x QuadraticSpline 858 us 67.5 us 12.7x CubicHermiteSpline 167 us 16.8 us 9.9x QuinticHermiteSpline 278 us 26.9 us 10.3x SmoothedConstantInterpolation is intentionally left out: its boundary smoothing logic means adjacent queries can fall in the smoothed region or in the constant region within the same segment, which doesn't fit cleanly into the per-segment hoist pattern used here. Worth a separate focused PR if anyone wants it. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
4 tasks
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.
Summary
Extends the sorted-batch fast path to all remaining piecewise types with a fixed per-segment polynomial form:
ConstantInterpolation(both:leftand:rightdirections)QuadraticInterpolationQuadraticSplineCubicHermiteSplineQuinticHermiteSplinePairs with #527 (
Linear+CubicSpline) and the earlier #526 (Akima). After both this PR and #527 land, every piecewise interpolation type in DataInterpolations.jl has an O(n+m) batch evaluator for sorted queries.This PR is stacked on #527 — branched off
sorted-batch-linear-cubic. If reviewed first I'll rebase onto master once #527 lands. Order-independent otherwise.Why a shared helper now
Adds a
_sorted_batch_extrapolation_supported(A)predicate used by all five new evaluators (None / Constant / Linear / Extension on each side). The earlier per-type predicates (_akima_eval_fast_applicable,_linear_eval_fast_applicable,_cubicspline_eval_fast_applicable) are left in place to keep this PR's diff focused on the new types; they're all equivalent and can be folded into the shared helper in a 5-line follow-up if desired.Benchmarks
Julia 1.10, n=256 knots, m=4096 sorted queries, BenchmarkTools
minimum:ConstantInterpolationQuadraticInterpolationQuadraticSplineCubicHermiteSplineQuinticHermiteSplineQuadraticSplinegets the biggest absolute win because its per-segment cost is dominated byget_parameters(A, idx)(the segment α, β coefficients) — the lockstep walk amortizes that across all queries in the segment instead of recomputing per query.What is in this PR
src/interpolation_methods.jl:_sorted_batch_extrapolation_supported(A)helper near the top.(A::T)(out, tt)callables + the corresponding_*_eval_sorted!inner loops for each of the 5 types, each following the same shape: dispatch on extrapolation type outside the per-region loop, hoist segment-local coefficients once per segment.CubicHermiteSplineandQuinticHermiteSplineuse the Hermite property that the slope at each knot equalsdu[idx], soLinearextrapolation reduces to a single multiply.ConstantInterpolation's eltype constraint is relaxed to<:AbstractVector(not<:AbstractVector{<:Number}) so it works for non-numeric data like["a", "b", ...]— no arithmetic is performed.test/interpolation_tests.jl: "Sorted-batch evaluator" sub-testsets in each type's section. Coverage matches Optimize AkimaInterpolation constructor (3.6-4.1x) and add sorted-batch evaluator (8-9x) #526 and Sorted-batch evaluators for LinearInterpolation and CubicSpline (~9x speedup) #527: all fast-path extrapolation modes paired left × right, knot pass-through,Periodic/Reflectivefallback,Nonethrowing, unsorted fallback,DimensionMismatch, pluscache_parameters=trueforQuadraticSplineand the non-Number eltype path forConstantInterpolation.What is intentionally NOT in this PR
SmoothedConstantInterpolation— its boundary smoothing means adjacent queries within the same segment can fall in either the smoothed region (at the segment edges) or the constant region (in the middle), so the per-segment hoist pattern doesn't apply cleanly. Worth a separate PR if someone wants it.Test plan
Pkg.test()all groups pass locally on Julia 1.10 (Core 5036 / Methods 42151 / Extensions 13178 / Misc 11)max diffcheck before adding the testset)Please ignore until reviewed by @ChrisRackauckas.
🤖 Generated with Claude Code