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

**URL:** <https://discourse.julialang.org/t/is-it-possible-to-use-bsplines-to-interpolate-when-scaling-using-collection-of-ranges/24125>\
**Category:** Numerics\
**Created:** [May 11, 2019, 9:38pm UTC](https://discourse.julialang.org/t/is-it-possible-to-use-bsplines-to-interpolate-when-scaling-using-collection-of-ranges/24125 "2019-05-11T21:38:05Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jints07](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jints07/32/20586_2.png) [@jints07](https://discourse.julialang.org/u/jints07)\
**Post date:** [May 11, 2019, 9:38pm UTC](https://discourse.julialang.org/t/is-it-possible-to-use-bsplines-to-interpolate-when-scaling-using-collection-of-ranges/24125/1 "2019-05-11T21:38:05Z")

</div>

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.

```julia
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

```julia
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?

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [May 12, 2019, 8:56am UTC](https://discourse.julialang.org/t/is-it-possible-to-use-bsplines-to-interpolate-when-scaling-using-collection-of-ranges/24125/2 "2019-05-12T08:56:34Z")

</div>

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](https://docs.julialang.org/en/latest/manual/interfaces/#man-interface-array-1) of the manual, and several examples at [https://github.com/JuliaArrays](https://github.com/JuliaArrays). (Choose a pretty simple type, e.g., UnalignedVectors, to start with.)

---

<div class="post-metadata">

**Author:** ![jints07](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jints07/32/20586_2.png) [@jints07](https://discourse.julialang.org/u/jints07)\
**Post date:** [May 12, 2019, 2:55pm UTC](https://discourse.julialang.org/t/is-it-possible-to-use-bsplines-to-interpolate-when-scaling-using-collection-of-ranges/24125/3 "2019-05-12T14:55:10Z")

</div>

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