Linear Interpolation API

Overview

One-shot (construction + evaluation)

FunctionDescription
linear_interp(x, y, xq)Linear interpolation at point(s) xq
linear_interp!(out, x, y, xq)In-place linear interpolation

Re-usable interpolant

FunctionDescription
itp = linear_interp(x, y)Create linear interpolant
itp(xq)Evaluate at point(s) xq
itp(out, xq)Evaluate at xq, store result in out

Derivatives

FunctionDescription
linear_interp(x, y, xq; deriv=1)First derivative (piecewise constant)
linear_interp(x, y, xq; deriv=2)Second derivative (always 0)
deriv1(itp)First derivative view
deriv2(itp)Second derivative view

Functions

FastInterpolations.linear_interpFunction
linear_interp(x, y, x_targets; extrap=:none)

Linear interpolation with automatic dispatch (allocating version):

  • For AbstractRange x: O(1) direct indexing
  • For general AbstractVector x: O(log n) binary search

Arguments

  • extrap::Symbol: :none (default, throws DomainError), :constant, :extension, or :wrap

Returns

  • Always returns a floating-point vector (Integer inputs auto-promoted to Float)

Example

rho = 0.0:0.01:1.0  # Uniform grid → fast O(1) path
y = sin.(rho)
result = linear_interp(rho, y, [0.55, 0.77])  # throws error if outside domain
result = linear_interp(rho, y, [-0.1, 1.2]; extrap=:extension)  # linear extrap
result = linear_interp(rho, y, [-0.1, 1.2]; extrap=:constant)  # clamp to boundary values
result = linear_interp(rho, y, [1.5, 2.5]; extrap=:wrap)  # wrap to domain

# Integer inputs auto-promoted to Float
x_int = 0:10
y_int = x_int.^2
result = linear_interp(x_int, y_int, [5.5, 7.3])  # Returns Vector{Float64}
source
linear_interp(x, y; extrap=:none) -> LinearInterpolant

Create a callable interpolant for broadcast fusion and reuse.

Arguments

  • x::AbstractVector: x-coordinates (must be sorted)
  • y::AbstractVector: y-values
  • extrap::Symbol: :none (default, throws DomainError), :constant, :extension, or :wrap

Returns

LinearInterpolant object that can be:

  • Called with scalar: itp(0.5)
  • Broadcasted: itp.(rho) or @. coef * itp(rho)
  • Reused multiple times without re-creating

Examples

# Create once, reuse multiple times
itp = linear_interp(x_data, y_data)

# Scalar call
val = itp(0.5)

# Broadcast (creates array)
vals = itp.(query_points)

# Fused broadcast (optimal - no intermediate arrays)
result = @. coefficient * itp(rho) * ne / Te^2

# Wrap to domain (for periodic-like data)
itp_wrap = linear_interp(x_data, y_data; extrap=:wrap)
val_wrap = itp_wrap(2.5)  # wraps to domain

# Compare with 3-argument form (returns array immediately)
vals_direct = linear_interp(x_data, y_data, query_points)

Performance Notes

  • Returns lightweight callable (~48 bytes), best for reuse and broadcast fusion
  • 3-argument form returns array immediately, best for single use
source
linear_interp(x, ys::AbstractVector{<:AbstractVector}; extrap=:none)

Create a multi-Y linear interpolant for multiple y-data series sharing the same x-grid.

Arguments

  • x::AbstractVector: x-coordinates (sorted, length ≥ 2)
  • ys: Vector of y-value vectors (all same length as x)
  • extrap: Extrapolation mode (:none, :constant, :extension, :wrap)

Returns

LinearSeriesInterpolant object with matrix storage.

Example

x = collect(range(0.0, 1.0, 101))
y1 = sin.(2π .* x)
y2 = cos.(2π .* x)
y3 = exp.(-x)

sitp = linear_interp(x, [y1, y2, y3])
vals = sitp(0.5)  # [sin(π), cos(π), exp(-0.5)]
source
linear_interp(x, Y::AbstractMatrix; extrap=:none)

Create a multi-Y linear interpolant from a matrix where each column is a y-series.

Arguments

  • x::AbstractVector: x-coordinates (length n)
  • Y::AbstractMatrix: n×m matrix, each column is a y-series
  • extrap: Extrapolation mode

Example

x = collect(range(0.0, 1.0, 101))
Y = hcat(sin.(2π .* x), cos.(2π .* x))  # 101×2 matrix

sitp = linear_interp(x, Y)
source
FastInterpolations.linear_interp!Function
linear_interp!(output, x, y, x_targets; extrap=:none)

Zero-allocation linear interpolation with automatic dispatch:

  • For AbstractRange x: O(1) direct indexing
  • For general AbstractVector x: O(log n) binary search

Arguments

  • output: Pre-allocated output vector (must be floating-point type)
  • extrap::Symbol: :none (default, throws DomainError), :constant, :extension, or :wrap

Example

rho = 0.0:0.01:1.0  # Uniform grid → fast O(1) path
y = sin.(rho)
out = Vector{Float64}(undef, 2)
linear_interp!(out, rho, y, [0.55, 0.77])  # throws error if outside domain
linear_interp!(out, rho, y, [-0.1, 1.2]; extrap=:extension)  # linear extrapolation
linear_interp!(out, rho, y, [-0.1, 1.2]; extrap=:constant)  # clamp to boundary values
linear_interp!(out, rho, y, [1.5, 2.5]; extrap=:wrap)  # wrap to domain (periodic)

Implementation Note

  • Optimized core works with AbstractFloat types (calls optimized scalar version)
  • Integer/Real inputs automatically promoted via wrapper methods
source

Interpolant Type

FastInterpolations.LinearInterpolantType
LinearInterpolant{T,X,Y}

Lightweight callable interpolant for broadcast fusion optimization. Returned by linear_interp(x, y) (2-argument form).

Fields

  • x::X: x-coordinates (sorted)
  • y::Y: y-values
  • mode::Val: Evaluation mode (Val(:none), Val(:extension), Val(:constant), or Val(:wrap))

Usage

# Create interpolator (minimal allocation)
itp = linear_interp(x, y)  # default extrap=:none (throws error if outside domain)

# Use in broadcast (fused, no intermediate arrays)
result = @. coef * itp(rho) * other_terms

# Reuse interpolator multiple times
vals1 = itp.(query_points1)
vals2 = @. compute(itp(query_points2))

# Extrapolation options
itp_ext = linear_interp(x, y; extrap=:extension)  # linear extrap
itp_const = linear_interp(x, y; extrap=:constant)  # clamp to boundary values
itp_wrap = linear_interp(x, y; extrap=:wrap)  # wrap to domain
val = itp_wrap(2.5)  # wraps to domain
source