Abstract interpolation interface

AbstractInterpolation is the extension point for adding a new interpolation method. The public evaluation, differentiation, and integration functions are generic over this type, so downstream code should use those functions rather than dispatching on a concrete interpolation implementation.

DataInterpolations.AbstractInterpolationType
AbstractInterpolation{T}

Supertype of interpolation objects in DataInterpolations.jl, where T is the element type of the interpolated values. Use this type to dispatch on interpolations independently of the interpolation method.

Interface rules

A concrete subtype must provide u and t fields. The entries of t are the ordered sample locations and the samples in u correspond to those locations along its last dimension. For scalar-valued data, u is a vector; for array-valued data, the last dimension of u indexes the samples. The generic methods also expect the subtype to provide iguesser, extrapolation_left, and extrapolation_right fields.

Fields

  • u: data values, with samples indexed along the last dimension.
  • t: ordered sample locations corresponding to the samples in u.
  • iguesser: reusable interval-search state, normally constructed with FindFirstFunctions.Guesser(t).
  • extrapolation_left, extrapolation_right: out-of-range evaluation modes.

The generic integral interface additionally requires the following fields:

  • I: cumulative integrals for the intervals. Use an empty cache when cache_parameters is false; omit this field when analytic integration is not supported.
  • cache_parameters::Bool: whether the generic integral method reads the cached I values.
  • kind and t_props: the interval-search strategy and its properties. Construct these with FindFirstFunctions.SearchProperties(t) and FindFirstFunctions.Auto(t, t_props).

The following developer hooks define the behavior of a new interpolation method:

These hooks are developer API: implement them when adding a new interpolation method, but call the generic A(t), derivative, and integral interfaces from user code. Implementations should preserve the shape of one data point in all three operations and should honor the extrapolation fields for out-of-range locations.

Examples

using DataInterpolations

A = LinearInterpolation([1.0, 2.0], [0.0, 1.0])

A isa DataInterpolations.AbstractInterpolation

# output

true
source

Required data

A concrete subtype must provide the following fields:

  • u: data values. A vector stores scalar values or one array per sample; an array stores samples along its last dimension.
  • t: ordered sample locations with length(t) equal to the number of samples in u.
  • iguesser: reusable interval-search state used by scalar evaluation and differentiation.
  • extrapolation_left and extrapolation_right: values from ExtrapolationType controlling out-of-range evaluation.

For the generic integral interface, the subtype also provides:

  • I: cumulative integrals for the intervals, or an empty cache when cache_parameters is false. A method without an analytic integral should omit this field; integral then reports IntegralNotFoundError.
  • cache_parameters::Bool: whether the generic integral method reads the cached I values.
  • kind and t_props: interval-search state, normally constructed from FindFirstFunctions.SearchProperties(t) and FindFirstFunctions.Auto(t, t_props).

Construct iguesser with FindFirstFunctions.Guesser(t). The t values must remain ordered, and u must store one sample per t entry along its last dimension.

Developer hooks

The following methods are the implementation hooks used by the generic interface. They are public developer API for packages that add interpolation subtypes, but they are not intended to be called by end users.

DataInterpolations._interpolateFunction
_interpolate(A::AbstractInterpolation, t::Number)
_interpolate(A::AbstractInterpolation, t::Number, iguess)

Developer hook used by the generic call interface A(t). The two-argument method handles the configured extrapolation behavior and delegates an in-range scalar evaluation to the three-argument method. New interpolation subtypes should implement _interpolate(A, t, iguess), where iguess is a reusable search hint supplied by the interpolation object.

The implementation must return one interpolated data point with the same shape as a single sample in A.u. It must not mutate A.u or A.t while evaluating. User code should call A(t) instead of this developer hook.

Arguments

  • A: an AbstractInterpolation subtype.
  • t: the scalar evaluation point.
  • iguess: the reusable interval-search state from A.iguesser for the three-argument method.

Examples

struct MyInterpolation <: DataInterpolations.AbstractInterpolation{Float64}
    u::Vector{Float64}
    t::Vector{Float64}
    iguesser
    extrapolation_left::DataInterpolations.ExtrapolationType.T
    extrapolation_right::DataInterpolations.ExtrapolationType.T
end

DataInterpolations._interpolate(A::MyInterpolation, t::Number, iguess) = 2t
source
DataInterpolations._derivativeFunction
_derivative(A::AbstractInterpolation, t::Number, iguess)

Developer hook used by derivative for an in-range scalar evaluation. Implement this method for a new AbstractInterpolation subtype. The returned value must have the same shape as one interpolated data point, and the value at a knot must be the left derivative because the public derivative interface is left-continuous at knots.

iguess is the reusable search hint stored by the interpolation. Implementations should use it when locating the interval and must not replace it with a new mutable search state for every call.

User code should call derivative rather than this developer hook.

Arguments

  • A: an AbstractInterpolation subtype.
  • t: an in-range scalar evaluation point.
  • iguess: the reusable interval-search state from A.iguesser.

Examples

DataInterpolations._derivative(A::MyInterpolation, t::Number, iguess) = 2.0
source
DataInterpolations._integralFunction
_integral(A::AbstractInterpolation, idx::Integer, t1::Number, t2::Number)

Developer hook used by integral to integrate one interval of an interpolation. Implement this method for a new interpolation subtype that supports analytic integration. idx identifies the interval [A.t[idx], A.t[idx + 1]]; the method must return the integral over the requested subinterval [t1, t2], preserving the shape of one data point.

The subtype must also provide an I field containing cached cumulative integrals when cache_parameters is true. If analytic integration is not supported, omit I and let the generic public method report IntegralNotFoundError.

User code should call integral rather than this developer hook.

Arguments

  • A: an AbstractInterpolation subtype.
  • idx: the interval index, with bounds A.t[idx] and A.t[idx + 1].
  • t1, t2: the requested interval bounds.

Examples

DataInterpolations._integral(A::MyInterpolation, idx::Integer, t1::Number, t2::Number) =
    2 * (t2 - t1)
source

The hooks must satisfy these rules:

  • _interpolate(A, t, iguess) evaluates one scalar location and returns one data point.
  • _derivative(A, t, iguess) returns the first derivative with the same shape as one data point. At a discontinuous knot it returns the left derivative.
  • _integral(A, idx, t1, t2) integrates the requested subinterval of [A.t[idx], A.t[idx + 1]] and preserves the data-point shape.

The generic forms A(t), derivative(A, t, order = 1), and integral(A, t) compose these hooks with interval search and extrapolation. A method should therefore be tested through those generic functions, including scalar, vectorized, and in-place evaluation where its data shape supports them.

Minimal implementation

The following sketch shows the required dispatch. A production implementation should also validate its data and provide the fields needed by any optional features it supports.

using FindFirstFunctions

struct MyInterpolation <: DataInterpolations.AbstractInterpolation{Float64}
    u::Vector{Float64}
    t::Vector{Float64}
    I::Vector{Float64}
    iguesser
    extrapolation_left::DataInterpolations.ExtrapolationType.T
    extrapolation_right::DataInterpolations.ExtrapolationType.T
    kind::FindFirstFunctions.StrategyKind
    t_props::FindFirstFunctions.SearchProperties
    cache_parameters::Bool
end

DataInterpolations._interpolate(A::MyInterpolation, t::Number, iguess) = 2t
DataInterpolations._derivative(A::MyInterpolation, t::Number, iguess) = 2.0
DataInterpolations._integral(
    A::MyInterpolation, idx::Integer, t1::Number, t2::Number
) = 2 * (t2 - t1)