LinearInterpolation between two points

MWE:

using Interpolations

itp1 = LinearInterpolation([1,8600],[1,8600]; extrapolation_bc=Line())
convert(Float64, itp1(8700)) #-1421.6002606281033

itp2 = LinearInterpolation([1,3200,8600],[1,3200,8600]; extrapolation_bc=Line())
convert(Float64, itp2(8700)) #8700.0

itp3 = LinearInterpolation([1,2150,4300,6450,8600],[1,2150,4300,6450,8600]; extrapolation_bc=Line())
convert(Float64, itp3(8700)) #8700.0

The linear extrapolation between 2 points is wrong. Is that a limitation of the scheme?

Julia and package versions:

julia> versioninfo()
Julia Version 1.6.1
Commit 6aaedecc44 (2021-04-23 05:59 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, skylake)

(jl_QhuT0L) pkg> st
      Status `/tmp/jl_QhuT0L/Project.toml`
  [a98d9a8b] Interpolations v0.13.4

It appears related to the (integer) type of the numbers you use. Apparently, when these numbers are small enough, things go fine:

julia> itp = LinearInterpolation([1,2],[1,2]; extrapolation_bc=Line())
2-element extrapolate(interpolate((::Vector{Int64},), ::Vector{Int64}, Gridded(Linear())), Line()) with element type Float64:
 Ratios.SimpleRatio{Int64}(1, 1)
 Ratios.SimpleRatio{Int64}(2, 1)

julia> convert(Float64,itp(3))
3.0

But as soon as the numbers are higher, the integers needed for defining the ratios within the approximation algorithm apparently overflow:

julia> itpi = LinearInterpolation([1,10000],[1,10000]; extrapolation_bc=Line())
2-element extrapolate(interpolate((::Vector{Int64},), ::Vector{Int64}, Gridded(Linear())), Line()) with element type Float64:
 Ratios.SimpleRatio{Int64}(99980001, 99980001)
 Ratios.SimpleRatio{Int64}(999800010000, 99980001)

julia> convert(Float64,itpi(10001))
773.9376918087789

An easy fix is to use floats as the input data:

julia> itpf = LinearInterpolation([1.0,10000.0],[1.0,10000.0]; extrapolation_bc=Line())
2-element extrapolate(interpolate((::Vector{Float64},), ::Vector{Float64}, Gridded(Linear())), Line()) with element type Float64:
     1.0
 10000.0

julia> convert(Float64,itpf(10001.0))
10001.0

6 Likes

@zdenek_hurak You’re right. In fact, the problem appears on interpolations of any number of points, e.g.,

itpi = LinearInterpolation([1,4000,10000],[1,4000,10000]; extrapolation_bc=Line())
convert(Float64, itpi(10001)) #-4232.5988223067525

The fix works. Thanks!

Hmm, I am hesitating if this should be regarded (and filed) as an Issue. In general the responsibility for the overflow problems is on the application programmer, right? But shouldn’t the interpolation function give some warning here? The parameters of the problem look innocent, don’t they?

EDIT: so I did it Integer overflow in innocent looking linear interpolation. Should some warning be issued? · Issue #457 · JuliaMath/Interpolations.jl · GitHub

7 Likes

Agreed. A warning message indicating integer overflow would be very helpful especially for new Julia users who do not familiar with the function output (Rational type).

1 Like

With SaferIntegers.jl version 3, you can detect overflow.

julia> using SaferIntegers, Interpolations

julia> itpi = LinearInterpolation(SafeInt[1,10000],SafeInt[1,10000]; extrapolation_bc=Line())
2-element extrapolate(interpolate((::Vector{SafeInt64},), ::Vector{SafeInt64}, Gridded(Linear())), Line()) with element type Float64:
 SimpleRatio{SafeInt64}(99980001, 99980001)
 SimpleRatio{SafeInt64}(999800010000, 99980001)

julia> itpi(10001)
ERROR: OverflowError: 999800010000 * 99980001 overflowed for type Int64
Stacktrace:
...
3 Likes