Skip to content

Specializations

The specializations module provides trait-dispatched implementations for specific kernel types, enabling optimized matrix representations and operations.

Overview

FunctionalGPs.jl uses a trait system to automatically select the most efficient algorithm for assembling covariance matrices. When you apply functionals (evaluation, integration, differentiation) to a kernel, the system:

  1. Queries the kernel's structure via kernel_structure(k)

  2. Dispatches to a specialized implementation based on the trait

  3. Returns a lazy or sparse matrix representation when available

This happens transparently - you get optimal performance without manual intervention.

Kernel Structure Traits

FunctionalGPs.KernelStructureTrait Type
julia
KernelStructureTrait

Trait describing structural properties of a kernel that influence how linear functionals should assemble covariance matrices. Subtypes enable specialised lazy matrix representations.

source
FunctionalGPs.GenericKernelTrait Type
julia
GenericKernelTrait()

Fallback trait used when a kernel does not expose special structure.

source
FunctionalGPs.StationaryKernelTrait Type
julia
StationaryKernelTrait()

Trait indicating that the kernel is stationary and supports fast evaluation via StationaryKernelMatrix when both sides are evaluation functionals with point coordinates.

source
FunctionalGPs.SignedStationaryKernelTrait Type
julia
SignedStationaryKernelTrait()

Trait for kernels that are signed-stationary (e.g., kernels involving derivatives with odd total order). These kernels have structure k(x,y) = sign(x-y) * f(|x-y|) and support specialized lazy matrix representations.

source
FunctionalGPs.kernel_structure Function
julia
kernel_structure(k)

Return the structural trait associated with kernel k. The default returns GenericKernelTrait(); specific kernels override this to signal richer structure.

Examples

julia
julia> k = HalfIntegerMaternKernel(2, [1.0]);
julia> kernel_structure(k)
StationaryKernelTrait()

julia> k_compact = CompactPolynomialKernel(Polynomial([1.0, -2.0]));
julia> kernel_structure(k_compact)
StationaryKernelTrait()
source

Trait-Dispatched Operations

These functions form the core interface for efficient kernel operations:

FunctionalGPs.kernel_evaluate_evaluate Function
julia
kernel_evaluate_evaluate(k, X)
kernel_evaluate_evaluate(k, X_left, X_right)

Assemble the covariance matrix resulting from applying evaluation functionals at coordinate collections X (and optionally X_left, X_right) to kernel k. The return value is a subtype of CovarianceMatrix or a fully materialised matrix when no lazy representation is available.

Examples

julia
julia> k = HalfIntegerMaternKernel(2, [1.0]);
julia> X = collect(range(0, 1, length=10));
julia> K = kernel_evaluate_evaluate(k, X);  # Lazy Toeplitz matrix
julia> size(K)
(10, 10)

julia> X_left = [0.0, 0.5];
julia> X_right = [0.2, 0.7, 0.9];
julia> K_cross = kernel_evaluate_evaluate(k, X_left, X_right);
julia> size(K_cross)
(2, 3)
source
julia
kernel_evaluate_evaluate(::StationaryKernelTrait, k::Kernel, X::AbstractRange)

Construct a symmetric Toeplitz covariance matrix for a stationary kernel evaluated on a uniformly spaced range. Exploits the constant spacing to avoid redundant kernel evaluations.

Returns a SymmetricToeplitz matrix when the kernel supports stationary specialization; otherwise falls back to kernelmatrix.

source
julia
kernel_evaluate_evaluate(::StationaryKernelTrait, k::Kernel, X)

Construct a lazy StationaryKernelMatrix for a stationary kernel evaluated at arbitrary point coordinates. The matrix computes entries on-demand using scaled squared distances.

Falls back to kernelmatrix if the input cannot be converted to stationary coordinates or the kernel does not provide a stationary specification.

source
julia
kernel_evaluate_evaluate(::StationaryKernelTrait, k::Kernel, X_left, X_right)

Construct a lazy StationaryKernelMatrix representing the cross-covariance between two sets of points for a stationary kernel. Uses the kernel's radial map on scaled squared distances.

source
julia
kernel_evaluate_evaluate(::SignedStationaryKernelTrait, k::Kernel, X)

Construct a lazy SignedStationaryKernelMatrix for kernels with signed-stationary structure (e.g., odd-order derivative kernels). The kernel value depends on both the squared distance and the sign of the coordinate difference.

source
julia
kernel_evaluate_evaluate(::SignedStationaryKernelTrait, k::Kernel, X_left, X_right)

Construct a lazy SignedStationaryKernelMatrix for cross-covariance between two point sets using a signed-stationary kernel.

source
FunctionalGPs.kernel_integrate_integrate Function
julia
kernel_integrate_integrate(k, domains)
kernel_integrate_integrate(k, domains1, domains2)

Assemble the covariance matrix resulting from applying integration functionals over domain collections domains (and optionally domains1, domains2) to kernel k. The return value is a lazy matrix representation when the kernel has exploitable structure (e.g., stationary), or a fully materialised matrix otherwise.

The single-argument version applies integration to both sides with the same domains (symmetric case). Implementations may specialize this for efficiency.

Examples

julia
julia> k = HalfIntegerMaternKernel(1, [0.8]);
julia> domains = [Interval(0.0, 0.2), Interval(0.2, 0.5), Interval(0.5, 1.0)];
julia> K = kernel_integrate_integrate(k, domains);  # Lazy Toeplitz-like matrix
julia> size(K)
(3, 3)

julia> domains_left = [Interval(0.0, 0.3), Interval(0.3, 0.6)];
julia> domains_right = [Interval(0.0, 0.25), Interval(0.25, 0.5), Interval(0.5, 1.0)];
julia> K_cross = kernel_integrate_integrate(k, domains_left, domains_right);
julia> size(K_cross)
(2, 3)
source
julia
kernel_integrate_integrate(::StationaryKernelTrait, k::Kernel, domains1, domains2)

Compute the covariance matrix for two-sided integration of a stationary kernel over 1D interval domains. Uses the kernel's second radial antiderivative (radial_antiderivative(k, Val(2))) to construct a lazy matrix as a sum of StationaryKernelMatrix terms.

The result represents Cov(∫_{domains1[i]} k, ∫_{domains2[j]} k).

source
julia
kernel_integrate_integrate(::StationaryKernelTrait, k::Kernel, domains)

Symmetric version of two-sided integration where both sides use the same domains. Delegates to the two-argument form.

source
julia
kernel_integrate_integrate(::StationaryKernelTrait, k::CompactPolynomialKernel, domains1, domains2)

Compute a sparse covariance matrix for two-sided integration of a compact polynomial kernel. Uses BallTree spatial indexing to efficiently find potentially interacting domain pairs, exploiting the kernel's compact support.

Returns a SparseMatrixCSC where entry [i,j] is Cov(∫_{domains1[i]} k, ∫_{domains2[j]} k).

source
FunctionalGPs.kernel_integrate_evaluate Function
julia
kernel_integrate_evaluate(k, domains, points)

Assemble the covariance matrix resulting from applying integration functionals over domains to one argument and evaluation functionals at points to the other argument of kernel k. The return value is a lazy matrix representation when available, or a fully materialised matrix otherwise.

Examples

julia
julia> k = HalfIntegerMaternKernel(2, [1.3]);
julia> domains = [Interval(0.0, 0.4), Interval(0.4, 0.9)];
julia> X = collect(range(0.0, 1.0, length=5));
julia> K = kernel_integrate_evaluate(k, domains, X);
julia> size(K)
(2, 5)

Notes

The resulting matrix K[i,j] represents cov(∫ over domains[i], evaluate at X[j]).

source
julia
kernel_integrate_evaluate(::StationaryKernelTrait, k::Kernel, domains, X)

Compute the covariance matrix for one-sided integration (integrate over domains, evaluate at points). Uses the kernel's first radial antiderivative (radial_antiderivative(k, Val(1))) and returns a lazy matrix via SignedStationaryKernelMatrix.

The result represents Cov(∫_{domains[i]} k, k(X[j])).

source
julia
kernel_integrate_evaluate(::StationaryKernelTrait, k::CompactPolynomialKernel, domains, X)

Compute a sparse covariance matrix for one-sided integration of a compact polynomial kernel (integrate over domains, evaluate at points). Uses BallTree spatial indexing for efficient neighbor search.

Returns a SparseMatrixCSC where entry [i,j] is Cov(∫_{domains[i]} k, k(X[j])).

source

Lazy Matrix Types

Specialized kernels return lazy matrix representations that defer computation:

FunctionalGPs.StationaryKernelMatrix Type
julia
StationaryKernelMatrix{T,TX,TY,TV,TW,F}

Lazy stationary covariance or cross-covariance matrix. Fields:

  • scaled_left: column-scaled left inputs of size (n_left, d)

  • scaled_right: column-scaled right inputs of size (n_right, d)

  • norms_left: row-wise squared norms of the left inputs

  • norms_right: row-wise squared norms of the right inputs

  • kernel_map: callable taking squared distance and returning covariance value

  • jitter: diagonal adjustment applied lazily when both sides alias

source
FunctionalGPs.SignedStationaryKernelMatrix Type
julia
SignedStationaryKernelMatrix{T,TX,TY,TV,TW,F}

Lazy stationary matrix where the kernel depends on both squared distance and signed differences between points. Suitable for one-sided integrals and odd derivatives that introduce direction-dependent factors.

source

Stationary Kernel Specifications

For kernels that are stationary (depend only on |x - y|), the system uses compact specifications:

FunctionalGPs.StationaryKernelSpec Type
julia
StationaryKernelSpec(scales, radial_map)

Container describing how a stationary kernel should be assembled lazily. The scales vector rescales coordinate columns, while radial_map maps squared distances to covariance values.

source
FunctionalGPs.SignedStationaryKernelSpec Type
julia
SignedStationaryKernelSpec(scales, signed_map)

Container for signed stationary kernels where the kernel depends on both squared distance and the sign of the coordinate difference.

source
FunctionalGPs.stationary_kernel_spec Function
julia
stationary_kernel_spec(k, ::Type{T})

Return a StationaryKernelSpec describing how to construct covariance matrices for kernel k with element type T. The default returns nothing, signalling that no stationary specialisation is available.

source
julia
stationary_kernel_spec(k::HalfIntegerMaternKernel{P}, ::Type{T})

Return a StationaryKernelSpec for efficient lazy matrix construction with a half-integer Matérn kernel. The radial map evaluates the exponential-polynomial form at scaled distances.

source
julia
stationary_kernel_spec(k::HalfIntegerMaternDerivativeOddKernel, ::Type{T})

Return a SignedStationaryKernelSpec for odd-order derivatives of half-integer Matérn kernels. The signed map accounts for the antisymmetric structure introduced by odd total derivative order.

source
julia
stationary_kernel_spec(k::HalfIntegerMaternDerivativeEvenKernel, ::Type{T})

Return a StationaryKernelSpec for even-order derivatives of half-integer Matérn kernels. Even total derivative order preserves the symmetric radial structure.

source
julia
stationary_kernel_spec(k::SqExponentialKernel, ::Type{T})

Return a StationaryKernelSpec for the base Squared Exponential kernel (unit scale). The radial map evaluates exp(-r²/2) at distances.

source
julia
stationary_kernel_spec(k::TransformedKernel{<:SqExponentialKernel, <:ScaleTransform}, ::Type{T})

Return a StationaryKernelSpec for a scaled SE kernel. The scale factor s = 1/ℓ is incorporated into the scales vector.

source
julia
stationary_kernel_spec(k::SEDerivativeEvenKernel, ::Type{T})

Return a StationaryKernelSpec for even-order SE derivatives.

source
julia
stationary_kernel_spec(k::SEDerivativeOddKernel, ::Type{T})

Return a SignedStationaryKernelSpec for odd-order SE derivatives.

source
FunctionalGPs.radial_antiderivative Function
julia
radial_antiderivative(k, ::Val{N})

Generic function for computing the Nth radial antiderivative of a kernel. Specific kernel types implement this for N=1 (one-sided integration) and N=2 (two-sided integration).

source

Supported Kernel Specializations

Half-Integer Matern Kernels

Half-integer Matern kernels (HalfIntegerMaternKernel{P} for smoothness nu = P + 1/2) support:

  • Lazy evaluation via StationaryKernelMatrix

  • Toeplitz matrices for uniformly spaced points

  • Closed-form radial antiderivatives for integration

  • Automatic derivative kernel construction

julia
using FunctionalGPs

# Create a Matern 5/2 kernel
k = HalfIntegerMaternKernel(2, [1.0])

# The trait system recognizes this as stationary
kernel_structure(k)  # Returns StationaryKernelTrait()

# Evaluation returns a lazy matrix
X = collect(range(0, 1, length=100))
K = kernel_evaluate_evaluate(k, X)  # StationaryKernelMatrix

# Derivatives are also specialized
dk = derivative(k, 1, 0)  # First derivative kernel
kernel_structure(dk.inner_kernel)  # SignedStationaryKernelTrait()

Compact Polynomial Kernels

Compact kernels (including Wendland kernels) have finite support and return sparse matrices:

julia
using FunctionalGPs, SparseArrays

# Wendland kernel with support radius 1.0
k = WendlandKernel(1, 2, 1.0)

# Kernel matrix is sparse
X = collect(range(0, 2, length=100))
K = kernelmatrix(k, X)
issparse(K)  # true

# Integration also produces sparse matrices
domains = [Interval(i*0.1, (i+1)*0.1) for i in 0:19]
K_int = kernel_integrate_integrate(StationaryKernelTrait(), k.inner_kernel, domains)

Extending with Custom Kernels

To add specialization support for a custom kernel:

  1. Declare the trait by implementing kernel_structure:
julia
kernel_structure(::MyKernel) = StationaryKernelTrait()
  1. Provide a stationary specification if applicable:
julia
function stationary_kernel_spec(k::MyKernel, ::Type{T}) where {T}
    scales = T[1 / k.lengthscale]
    radial_map = r2 -> my_radial_function(sqrt(r2))
    return StationaryKernelSpec(scales, radial_map)
end
  1. Implement radial antiderivatives for integration support:
julia
function radial_antiderivative(k::MyKernel, ::Val{1})
    return r -> my_first_antiderivative(r)
end

function radial_antiderivative(k::MyKernel, ::Val{2})
    return r -> my_second_antiderivative(r)
end