Is it possible to use BSplines to interpolate when scaling using collection of ranges

I want to use scaled linear interpolation using BSplines with a 4-D matrix. One of the dimensions does not have all points equally spaced but is a 2 ranges put together. I read that BSplines are much faster than Gridded interpolations and was wondering if I could use BSplines here somehow. Just giving a small example similar to my case here.

using Interpolations;
d1=range(1.,stop=2.,length=11);
d2 = [range(1.,stop=1.4,length=5); range(1.5,stop=2.,length=3);];
A = [log(x1+x2) for x1 in d1,x2 in d2];
itp = interpolate(A, BSpline(Linear()));
sitp = scale(itp, d1, d2);

If I do this I get the error

ERROR: MethodError: no method matching scale(::Interpolations.BSplineInterpolation{Float64,2,Array{Float64,2},BSpline{Linear},Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}}, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Array{Float64,1})
Closest candidates are:
  scale(::AbstractInterpolation{T,N,IT}, ::AbstractRange...) where {T, N, IT} at C:\Users\hayag\.julia\packages\Interpolations\AiRSM\src\scaling\scaling.jl:23
Stacktrace:
 [1] top-level scope at none:0

Is there a workaround for this?

In terms of performance, the key issue is that when you compute f(x, y, ...) for some interpolant f, you have to identify the knots that bracket x, y, etc. If the knots are regularly spaced, this can be computed in O(1) (e.g., xi = floor(Int, (x - xfirst)/xstep)), but if the knots are arbitrary then you need to call searchsortedfirst which is O(logN) and considerably slower in practice.

In your case, you could define a custom AbstractVector subtype, TwoRanges, and provide a specialized searchsortedfirst method that exploits its structure to achieve O(1) performance. You could then use Gridded interpolants, but they would not pay the typical price.

If you’ve not defined your own AbstractVector subtype before, it’s much simpler than it may sound. See the interfaces chapter of the manual, and several examples at https://github.com/JuliaArrays. (Choose a pretty simple type, e.g., UnalignedVectors, to start with.)

1 Like

Thank you! This is what I was looking for. I will try this