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.AbstractInterpolation — Type
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 inu.iguesser: reusable interval-search state, normally constructed withFindFirstFunctions.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 whencache_parametersisfalse; omit this field when analytic integration is not supported.cache_parameters::Bool: whether the generic integral method reads the cachedIvalues.kindandt_props: the interval-search strategy and its properties. Construct these withFindFirstFunctions.SearchProperties(t)andFindFirstFunctions.Auto(t, t_props).
The following developer hooks define the behavior of a new interpolation method:
DataInterpolations._interpolate: evaluate one sample at a scalar location.DataInterpolations._derivative: evaluate the first derivative at a scalar location. At a knot, return the left derivative, matchingderivative.DataInterpolations._integral: integrate one interval when analytic integration is supported. A subtype that does not have anIfield automatically reportsIntegralNotFoundErrorfromintegral.
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
trueRequired 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 withlength(t)equal to the number of samples inu.iguesser: reusable interval-search state used by scalar evaluation and differentiation.extrapolation_leftandextrapolation_right: values fromExtrapolationTypecontrolling out-of-range evaluation.
For the generic integral interface, the subtype also provides:
I: cumulative integrals for the intervals, or an empty cache whencache_parametersisfalse. A method without an analytic integral should omit this field;integralthen reportsIntegralNotFoundError.cache_parameters::Bool: whether the generic integral method reads the cachedIvalues.kindandt_props: interval-search state, normally constructed fromFindFirstFunctions.SearchProperties(t)andFindFirstFunctions.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._interpolate — Function
_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: anAbstractInterpolationsubtype.t: the scalar evaluation point.iguess: the reusable interval-search state fromA.iguesserfor 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) = 2tDataInterpolations._derivative — Function
_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: anAbstractInterpolationsubtype.t: an in-range scalar evaluation point.iguess: the reusable interval-search state fromA.iguesser.
Examples
DataInterpolations._derivative(A::MyInterpolation, t::Number, iguess) = 2.0DataInterpolations._integral — Function
_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: anAbstractInterpolationsubtype.idx: the interval index, with boundsA.t[idx]andA.t[idx + 1].t1,t2: the requested interval bounds.
Examples
DataInterpolations._integral(A::MyInterpolation, idx::Integer, t1::Number, t2::Number) =
2 * (t2 - t1)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)