SciML / DataInterpolations.jl

A library of data interpolation and smoothing functions
MIT License
203 stars 43 forks source link

BSplineInterpolation errors on small vectors #239

Closed alecloudenback closed 4 days ago

alecloudenback commented 3 months ago

Describe the bug 🐞

Interpolation errors on small vectors

Expected behavior

Would expect a handling similar to BSplineKit.jl which does not error on smaller vectors.

Context

When bootstrapping a yield curve (e.g. FinanceModels.jl) we want to construct a curve which iteratively constructs a fit curve by using a longer and longer set of input/output vectors. The last element of the intermediate vectors $n_i$ is applied to the range between $xi$ and $x{i+t}$ when solving for the $x_{i+1}th$ parameter.

Minimal Reproducible Example 👇

Shows how BSplineKit handles the case while DataInterpolations does not:

julia> import BSplineKit

julia> import DataInterpolations 

       # Dependent variable

julia> u = [14.7, 11.51, 10.41, 14.95, 12.24, 11.22]

       # Independent variable
6-element Vector{Float64}:
 14.7
 11.51
 10.41
 14.95
 12.24
 11.22

julia> t = [0.0, 62.25, 109.66, 162.66, 205.8, 252.3]
6-element Vector{Float64}:
   0.0
  62.25
 109.66
 162.66
 205.8
 252.3

julia> DataInterpolations.BSplineInterpolation(u[1:3], t[1:3], 3, :ArcLen, :Average)(50)
ERROR: BoundsError: attempt to access 3-element Vector{Float64} at index [0]
Stacktrace:
 [1] setindex!
   @ ./array.jl:1021 [inlined]
 [2] spline_coefficients(n::Int64, d::Int64, k::Vector{Float64}, u::Float64)
   @ DataInterpolations ~/.julia/packages/DataInterpolations/Pz5Mr/src/interpolation_utils.jl:16
 [3] spline_coefficients(n::Int64, d::Int64, k::Vector{Float64}, u::Vector{Float64})
   @ DataInterpolations ~/.julia/packages/DataInterpolations/Pz5Mr/src/interpolation_utils.jl:30
 [4] DataInterpolations.BSplineInterpolation(u::Vector{…}, t::Vector{…}, d::Int64, pVecType::Symbol, knotVecType::Symbol; extrapolate::Bool)
   @ DataInterpolations ~/.julia/packages/DataInterpolations/Pz5Mr/src/interpolation_caches.jl:450
 [5] DataInterpolations.BSplineInterpolation(u::Vector{…}, t::Vector{…}, d::Int64, pVecType::Symbol, knotVecType::Symbol)
   @ DataInterpolations ~/.julia/packages/DataInterpolations/Pz5Mr/src/interpolation_caches.jl:391
 [6] top-level scope
   @ REPL[58]:1
Some type information was truncated. Use `show(err)` to see complete types.

julia> BSplineKit.interpolate(t[1:3],u[1:3],BSplineKit.BSplineOrder(3))(50)
11.981117652658668
SouthEndMusic commented 4 days ago

Hmm, I think this error occurs because the B-Spline implementation in DataInterpolations assumes that a degree $n$ B-Spline curve has at least $n+1$ data points. DataInterpolations is not a dedicated B-Spline package, so I think (unless someone wants to dive into this) it is sufficient to raise an informative error if this condition is not met.

ChrisRackauckas commented 4 days ago

But this has n+1=4 data points?

sathvikbhagavan commented 4 days ago

But this has n+1=4 data points?

The interpolation is with 3 points - BSplineInterpolation(u[1:3], t[1:3], 3, :ArcLen, :Average)

it is sufficient to raise an informative error if this condition is not met.

Yeah, that might be easier.

ChrisRackauckas commented 4 days ago

The interpolation is with 3 points - BSplineInterpolation(u[1:3], t[1:3], 3, :ArcLen, :Average)

Oh missed that. yeah error.