GP Conditioning
This module provides tools for conditioning Gaussian processes on observations made through linear functionals. This enables GP regression with not just point observations, but also derivatives, integrals, and other linear transformations.
Overview
The core workflow is:
Create a GP prior with a kernel
Define observations using
LinearObservationCondition the GP using
condition_on_observationQuery the posterior with
mean,var,cov, orrand
using FunctionalGPs, AbstractGPs
# Prior GP
k = Matern52Kernel()
f = GP(k)
# Observe function values
X = [0.0, 0.5, 1.0]
y = sin.(X)
f_post = condition_on_observation(f, X, y; noise=0.01)
# Posterior predictions
X_new = 0:0.1:1
posterior_mean = mean(f_post(X_new))
posterior_var = var(f_post(X_new))Types
FunctionalGPs.LinearObservation Type
LinearObservation{Tℒ, Tε, Ty}Represents a noisy observation of a GP through a linear functional.
Given a GP f, a linear functional ℒ, and observed values y, this encodes the observation model y = ℒ(f) + ε where ε is additive Gaussian noise.
Fields
linfunc: The linear functional applied to the GPnoise: The noise distribution (MvNormal or nothing for noise-free)y: The observed values
See also: condition_on_observation, LinearConditionalGP
FunctionalGPs.LinearConditionalGP Type
LinearConditionalGP <: AbstractGPA Gaussian process conditioned on linear observations.
This type represents a GP posterior after conditioning on one or more LinearObservations. It stores the prior GP and all observation data needed for efficient posterior inference.
Use condition_on_observation to construct instances rather than calling the constructor directly.
Posterior Computations
For a LinearConditionalGP f, you can:
Evaluate at points:
f(X)returns aFiniteGPGet posterior mean:
mean(f(X))Get posterior variance:
var(f(X))Get posterior covariance:
cov(f(X))Sample:
rand(rng, f(X), n)Apply further functionals:
ℒ(f)returns anMvNormal
See also: LinearObservation, condition_on_observation
Conditioning
FunctionalGPs.condition_on_observation Function
condition_on_observation(f::AbstractGP, observation::LinearObservation) -> LinearConditionalGP
condition_on_observation(f::AbstractGP, ℒ, y; noise=nothing) -> LinearConditionalGP
condition_on_observation(f::AbstractGP, X::AbstractVector, y; noise=nothing) -> LinearConditionalGPCondition a GP on observations through a linear functional.
Returns a LinearConditionalGP representing the posterior distribution.
Methods
condition_on_observation(f, obs): Condition on aLinearObservationcondition_on_observation(f, ℒ, y; noise): Condition onℒ(f) = ywith optional noisecondition_on_observation(f, X, y; noise): Shorthand for point evaluation atX
Multiple observations can be added sequentially by calling condition_on_observation on an existing LinearConditionalGP.
Example
using FunctionalGPs, AbstractGPs
k = Matern52Kernel()
f = GP(k)
# Condition on function values
X = [0.0, 0.5, 1.0]
y = sin.(X)
f_post = condition_on_observation(f, X, y; noise=0.01)
# Add derivative observation
∂x = PartialDerivative((1,))
ℒ = EvaluationFunctional([0.25]) ∘ ∂x
f_post2 = condition_on_observation(f_post, ℒ, [0.5]; noise=1e-6)
# Compute posterior at new points
X_new = 0:0.1:1
μ = mean(f_post2(X_new))
σ² = var(f_post2(X_new))Posterior Access
After conditioning, you can access properties of the posterior:
FunctionalGPs.G_chol Function
G_chol(f::LinearConditionalGP)Return the Cholesky factorization of the Gram matrix G = ℒ(ℒ(k)) + Σ_ε.
This is the core matrix needed for posterior computations and is cached (memoized).
sourceFunctionalGPs.representer_weights Function
representer_weights(f::LinearConditionalGP)Compute the representer weights G⁻¹(y - ℒ(m) - μ_ε) used for posterior mean computation.
The posterior mean at new points is m(x) + k(x, ℒ) * representer_weights(f). This is cached (memoized) for efficiency.
FunctionalGPs.predictive_residual Function
predictive_residual(f::LinearConditionalGP)Compute the predictive residual y - ℒ(m) - μ_ε where y is observed data, ℒ(m) is the prior mean evaluated through the functional, and μ_ε is the noise mean.
This is cached (memoized) for efficiency.
sourceFunctionalGPs.y_vec Function
y_vec(f::LinearConditionalGP)Return all observed values concatenated into a single vector.
sourceNoise Access
FunctionalGPs.εs Function
εs(f::LinearConditionalGP)Return the tuple of noise distributions from all observations.
sourceFunctionalGPs.μs Function
μs(f::LinearConditionalGP)Return the tuple of noise means from all observations.
sourceApplying Functionals to GPs
Linear functionals can be applied directly to GPs (both prior and posterior) to obtain the distribution of the transformed quantity:
# Prior GP
f = GP(Matern52Kernel())
# Distribution of integral over [0, 1]
ℒ = VectorizedLebesgueIntegral(Interval(0.0, 1.0))
integral_dist = ℒ(f) # Returns MvNormal
# For a posterior GP
f_post = condition_on_observation(f, [0.5], [0.0]; noise=0.01)
posterior_integral = ℒ(f_post; noise=1e-6)This works because linear functionals preserve Gaussianity: if f ~ GP(m, k), then ℒ(f) ~ Normal(ℒ(m), ℒ(ℒ(k))).
See also
For models that need to bundle several linear functionals of the same GP into a single joint Gaussian — preserving the cross-covariances between blocks that are otherwise dropped by independent per-functional treatment, e.g. inside a Turing or DynamicPPL model — see the Joint Functional Gaussians page in this API Reference.