Julia version of Matlab function interp1

question

#1

I am try to find the Julia version of Matlab function interp1.

In Matlab, vq = interp1(x,v,xq) returns interpolated values of a 1-D function at specific query points using linear interpolation. Vector x contains the sample points, and v contains the corresponding values, v(x). Vector xq contains the coordinates of the query points.


#2
using Dierckx # could also use Interpolations.jl, but its syntax is less familiar
x = linspace(0,π)
v = sin.(x)
xq = linspace(π/2, 3π/2)

# Create & evaluate spline interpolant
spl = Spline1D(x, v; k=1) # k: order of interpolant; can be between 1-5
vq = spl(xq)

# or equivalently, as a one-liner:
vq = Spline1D(x, v; k=1)(xq)

#3

If you want to use Interpolations.jl (a pure julia implementation), but stick with a familiar syntax you can create a reusable wrapper. I’m sure this could be improved, but here is an example that contains the same basic functionality as the matlab version including extrapolation options. Note that Interpolations has way many more options for spline degree, boundary conditions, and grid representation if you want to customize further.

using Interpolations

function interp1(xpt, ypt, x; method="linear", extrapvalue=nothing)

    if extrapvalue == nothing
        y = zeros(x)
        idx = trues(x)
    else
        y = extrapvalue*ones(x)
        idx = (x .>= xpt[1]) .& (x .<= xpt[end])
    end
    
    if method == "linear"
        intf = interpolate((xpt,), ypt, Gridded(Linear()))
        y[idx] = intf[x[idx]]

    elseif method == "cubic"
        itp = interpolate(ypt, BSpline(Cubic(Natural())), OnGrid())
        intf = scale(itp, xpt)
        y[idx] = [intf[xi] for xi in x[idx]]
    end
    
    return y
end

#4

I tried this function
using Interpolations

function interp1(xpt, ypt, x; method="linear", extrapvalue=nothing)

    if extrapvalue == nothing
        y = zeros(x)
        idx = trues(x)
    else
        y = extrapvalue*ones(x)
        idx = (x .>= xpt[1]) .& (x .<= xpt[end])
    end
    
    if method == "linear"
        intf = interpolate((xpt,), ypt, Gridded(Linear()))
        y[idx] = intf[x[idx]]

    elseif method == "cubic"
        itp = interpolate(ypt, BSpline(Cubic(Natural())), OnGrid())
        intf = scale(itp, xpt)
        y[idx] = [intf[xi] for xi in x[idx]]
    end
    
    return y
end


interp1(xpt, ypt, x) works fine but
interp1(xpt, ypt, x, method="cubic") got the error message

ERROR: MethodError: no method matching scale(::Interpolations.BSplineInterpolation{Float64,1,Array{Float64,1},Interpolations.BSpline{Interpolations.Cubic{Interpolations.Line}},Interpolations.OnGrid,1}, ::DataArrays.DataArray{Float64,1})

#5

This works for me.

x = 0:pi/4:2*pi
v = sin.(x)
xq = 0:pi/16:1.5*2*pi
vq = interp1(x, v, xq, method="cubic")

This is with Interpolations v 0.7.3, Julia v 0.6.2. I just wrote this as a quick example so I’m sure it’s not super robust.