Using Interpolations

This will have to be slower.
There you couldn’t use the closed form solution.

And then you also can’t use my iterative approach either (hidden behind the “Summary” label). That one was faster because I simply only calculated the interpolations once.
Calculating the interpolations once took about 310 microseconds (meaning, given those, it only took about 40 for my closed form solution to calculate beta). That is the slowest part of the code.

If you use an iterative approach, because the fits are now a function of the parameters, you’ll have to reevaluate them each time. This will make that code much slower.

I’d look at others’ suggestions above on how to make the interpolations faster.
Is it possible to make your interpolation an evenly spaced grid, or some transform of such a grid?
I’d also sort the "x"es (use sortperm, so you can also sort y the same way), and then use some function to evaluate the batch, taking advantage of the fact they’re sorted.

The data is sampled at a consistent rate, and that will always be reasonably constant. However it isn’t always the same values. Here is a small sample of the x vector of real data.

6-element Array{Float64,1}:
 29.439125518281116
 29.519035054655205
 29.598944591028953
 29.67885412740293 
 29.75876366377679 
 29.838673200150765

The start times of the data vary a bit run-to-run with respect to where the peaks occur which is why I need the extra two parameters. What I can say about the data is that the curve shape is reasonably smooth and without discontinuities. Also, the data is much more finely sampled than necessary with about 7000 samples. One could, for instance, use every tenth sample (perhaps even coarser), especially if you fit with a cubic spline instead of a linear approximation. I’ve done this with Python and got comparable answers with faster processing times (but not ten times faster).

I guess the main concern is that the constructor will no longer be concretely inferrable, so code that creates the object and then uses it in the same function might suffer. Due to union-splitting it won’t be terrible, but it could easily cause a slowdown if the check isn’t hoisted out of the inner loop. Would be worth exploring before submitting a PR, but if the compiler is smart enough this could be a very nice improvement.

The performance improvements in Interpolations 0.12 also seem to basically solve the problem (now you pay the price of extrapolation only when you need it):

julia> itp1 = interpolate((x,), y, Gridded(Linear()));

julia> itp2 = LinearInterpolation(x, y,extrapolation_bc=Flat());

julia> @btime $itp1($x2);
  62.032 μs (9 allocations: 31.56 KiB)

julia> @btime $itp2($x2);
  62.408 μs (1 allocation: 7.94 KiB)
1 Like

Perfect, sounds like this isn’t needed any more. Is the same true of the exception throwing extrapolation (which is the current default in the convenience constructors)?

Yes

1 Like

On topic; and yet slightly off topic:

Can someone help me understand why CubicSplineInterpolation does not work with collect(). Thanks in advance:

using Interpolations
x = collect(1:0.1:5)
y = rand(length(x))
itp1 = LinearInterpolation(x, y; extrapolation_bc=Flat())
@show itp1(4)
@show itp1(6)
itp2 = CubicSplineInterpolation(x, y; extrapolation_bc=Flat())
@show itp2(4)
@show itp2(6)

It should. Post an issue about this, mention that LinearInterpolation(...) handles collected xs and ys properly.

Thanks Jeffrey. Just posted