Opal.jl
Welcome to the documentation for Opal.jl
Description
This package provides a collection of tools for data assimilation, uncertainty quantification and inverse modeling in real-world dynamical systems and evolutionary equations (ODEs/PDEs).
Manual
Opal.ALL — Constant
ALL, WARMUP, TRAIN, WASHOUT, SPREAD, DA
OBSALL, OBSWARMUP, OBSTRAIN, OBSWASHOUT, OBSSPREAD, OBSDAInteger phase tags used to index a TimeStencils descriptor or a StencilArray. The OBS* variants select the same time window but at the observation cadence (dt_obs) rather than the model cadence (dt).
| Constant | Phase |
|---|---|
ALL | entire simulation window |
WARMUP | reservoir warm-up |
TRAIN | RC training |
WASHOUT | washout (transient discard) |
SPREAD | ensemble spread phase |
DA | data-assimilation window |
GridapROMs.RBSteady.ℓ2 — Method
ℓ2(n::Int) -> AbstractMatrixReturns the $n \times n$ Euclidean ($\ell^2$) distance matrix for a one-dimensional grid of n equally-spaced points. Also available as the alias euclidean.
Opal.AdaptiveFilter — Type
struct AdaptiveFilter{F<:KalmanFilter} <: KalmanFilterWraps an inner Kalman filter F and estimates the process-noise covariance Q and observation-noise covariance R on-line using an innovation-based EM-like update.
At each step, the cached transition Jacobian F, observation Jacobian H, prior/posterior covariances, and innovations from the previous step are used to form new estimates $\hat Q$ and $\hat R$, which are then blended into the running estimates via an exponential moving average with weight step.
Fields:
filter: the underlyingKalmanFilter(can be any concrete subtype);last_posterior: copy of the posterior from the previous analysis step, needed for the adaptive update;step: EMA step size $\alpha \in (0,1]$ controlling how fast $Q$ and $R$ adapt;cache: pre-allocated workspace for Jacobians, covariances, and innovation history.
Construct via AdaptiveFilter(filter; step=0.1).
Opal.AddBias — Type
struct AddBias{A<:Number} <: BiasStyleAppends a constant value as an extra component to the input vector, increasing its length by one.
Opal.AdjointProblem — Type
struct AdjointProblem{A,B}Encapsulates the pieces needed to identify unknown parameters – or, for an unparameterised StateMap (no ParamSpace attached), the initial condition – of a PDE- or ODE-constrained observation model via gradient-based optimisation with automatic differentiation.
The parameter-to-state map, observation operator, and state-to-loss map are precomposed into a single μ_obs_to_ℓ(μ,obs) -> Real closure at construction time (see build_loss); they are not stored as separate fields.
Fields:
μ_to_u::A: the state map (anODEStateMaporPDEStateMap); its ownboundsandinitial_condition(derived from its attachedpspace, ornothingif unparameterised) supply the optimisation's box constraints and default initial guess – there is no separatepspacefield here anymore;μ_obs_to_ℓ::B: the precomposed(μ,obs) -> ℓloss closure.
Construct via AdjointProblem(μ_to_u, u_to_obs, args...), where args... is forwarded to build_loss (e.g. obs_noise for the StateToObservationMap case).
Opal.AlgebraicModel — Type
struct AlgebraicModel{T,A<:AbstractMatrix{T}} <: LinearModel
matrix::A
endStandard implementation of a LinearModel. The field matrix represents the constant Jacobian of the model itself.
Opal.BiasAwareFilter — Type
struct BiasAwareFilter{A<:KalmanFilter} <: KalmanFilterWraps an inner Kalman filter A and corrects for systematic observation bias using a RecurrentNeuralNetwork trained online.
During a warm-up phase (first maxiter steps) the inner filter runs as-is, accumulating innovations to train the bias model. Once the counter exceeds maxiter (isaware returns true) the analysis step adjusts the innovation by the current bias estimate before computing the Kalman gain and state update.
Fields:
filter: the underlyingKalmanFilter(can be any concrete subtype);bias_model: aRecurrentNeuralNetworkthat maps the current innovation to a bias vector;regularisation: penalty coefficientγapplied to the bias Jacobian in the modified gain;awareness: [IterCounter] tracking how many analysis steps have been performed;cache: pre-allocated workspace for Jacobians and intermediate matrices.
Construct via BiasAwareFilter(f, bias_model; γ=10, maxiter=0) where f is any KalmanFilter instance.
Opal.BiasStyle — Type
abstract type BiasStyle endBase type for bias-appending strategies within a Modifier pipeline. Concrete subtypes: NoBias, AddBias.
Opal.BickelLevina — Type
struct BickelLevina <: TaperFunction endHard-thresholding taper: returns 1 for ‖x‖ ≤ 1 and 0 elsewhere.
Opal.CalibratedFilter — Type
struct CalibratedFilter{A<:Filter,B<:Calibration} <: FilterWraps any Filter with a Calibration that corrects the observation error estimate at each assimilation step. All filter interface methods (get_prior, transition!, analyse!, etc.) delegate to the inner filter; only the observation update step additionally calls the calibration.
Construct via:
CalibratedFilter(filter, calibration)Opal.CatArray — Type
struct CatArray{T,N,D} <: AbstractArray{T,N}A block-structured array that stores its data in a flat Array{T,N} together with D pointer vectors (ptrs) that delimit the blocks along each blocked dimension.
Construct with vcatarray (blocks stacked along dimension 1) or dcatarray (blocks placed on the block diagonal of a matrix). Individual blocks are accessed via BlockArrays.Block indices or via nblocks.
Opal.ConstrainedLaw — Type
struct ConstrainedLaw{A,B,N} <: Law{N}Wraps a Law together with a box constraint (ConstrainTo) so that samples and resampled particles are projected back into the feasible set after each update step.
Construct via ConstrainTo(lb, ub) applied to a law (see also ConstrainTo):
prior = Particle(ConstrainTo(lb, ub), particles, weights)Opal.DAMethod — Type
abstract type Filter endType reserved for filter operators for data processes, such as the Kalman filter (KF). A filter should be given as input an transition operator, a observation operator, and a prior distribution, which should be representative of the distribution of the initial sample. The prior should be updated iteratively, assimilating observations at multiple different time instants, as well as the last bayesian estimate of the (unknown) state variable. Check the function loop for suitable iterative updates of the prior. Check here for more details on Kalman filtering. Subtypes:
Opal.DAResults — Type
struct DAResults
state_history::History
obs_measures::ResultsTable
endOpal.DEnKF — Type
const DEnKF{A<:Model,B<:Model,C<:Law,D<:Law,E<:Law,F<:Law} = EnsembleKalmanFilter{A,B,C,D,E,F,DEnKFStrategy}Implements the DEnKF. Construct by passing an Ensemble with strategy=DEnKFStrategy() as the prior.
Opal.DEnKFStrategy — Type
struct DEnKFStrategy <: EnsembleStyle endTrait for ensembles mimicking the DEnKF (deterministic EnKF) method:
- run the forecast step on each ensemble member (see
forecast!); - compute the Kalman gain $K$ as usual (see
kalman_gain!); - compute the ensemble innovations $ỹ$ (see
innovation!); - update the ensemble mean according to the formula:
\[μ ← μ + K ⋅ mean(ỹ),\]
where $μ$ is the ensemble mean;
- update the ensemble anomaly according to the formula:
\[A ← (I - rac{1}{2} K⋅H) A \]
where $H$ is the jacobian of the observation model, evaluated in the forecasted ensemble mean, and $A$ is the ensemble anomaly. This is the so-called deterministic approximation of DEnKF;
- update the ensemble $E$ according to the formula:
\[E[:,i] = A[:,i] + μ \]
for every $i = 1,...,nₑ$. The covariance $Σ$ is then estimated via its ensemble counterpart:
\[Σ = A ⋅ Aᵀ / (nₑ - 1)\]
Opal.DataAugmentation — Type
abstract type DataAugmentation <: DataTransformation endBase type for input-augmentation strategies applied to training data before feeding into the reservoir. Concrete subtypes: NoAugmentation, ScaledAugmentation.
Opal.DataRegularisation — Type
abstract type DataRegularisation <: DataTransformation endBase type for data-regularisation strategies (e.g. additive noise) applied to training inputs. Concrete subtypes: NoRegularisation, AdditiveNoiseRegularisation.
Opal.EchoStateNetwork — Type
struct EchoStateNetwork <: RecurrentNeuralNetworkEcho State Network (ESN) / reservoir computing model.
The hidden state evolves as
\[s_{t+1} = (1 - \alpha)\, s_t + \alpha \, f(\rho W s_t + \sigma W_{\mathrm{in}} x_t')\]
where $f$ is the activation function, $\rho$ is the spectral radius, $\sigma$ is the input scaling, and $\alpha$ is the leak rate. The readout $y_t = W_{\mathrm{out}} s_t'$ is linear and fitted by ridge regression via TrainRecurrentNeuralNetwork.
Fields:
activation: element-wise activation (defaulttanh);state: mutable hidden-state vector $s_t$;initial_state: initial hidden-state vector $s_0$;weights: reservoir weight matrix (sparse);weights_in: input weight matrix;weights_out_T: transposed readout matrix (fitted during training);modifier_in,modifier_state:Modifierpipelines for inputs and states;radius: mutable spectral-radius reference $\rho$;scaling: mutable input-scaling reference $\sigma$;leak: leak rate $\alpha$.
Construct via EchoStateNetwork(ninput, nstate, noutput; kwargs...).
Opal.EnKFStrategy — Type
struct EnKFStrategy <: EnsembleStyle endTrait for ensembles mimicking the EnKF method:
- run the forecast step on each ensemble member (see
forecast!); - compute the Kalman gain $K$ as usual (see
kalman_gain!); - compute the ensemble innovations $ỹ$ (see
innovation!); - update the ensemble according to the formula:
\[E ← E + K ⋅ ỹ \]
where $E$ is the ensemble matrix. The mean $μ$ and covariance $Σ$ are then estimated via their ensemble counterparts:
\[μ = ∑ᵢ E[:,i] / nₑ Σ = ∑ᵢ (E[:,i] - μ)⋅(E[:,i] - μ)ᵀ / (nₑ - 1)\]
Opal.EnSRKF — Type
const EnSRKF{A<:Model,B<:Model,C<:Law,D<:Law,E<:Law,F<:Law} = EnsembleKalmanFilter{A,B,C,D,E,F,EnSRKFStrategy}Ensemble Square-Root Kalman Filter. Deterministic (no perturbed observations), so the ensemble spread is updated via a square-root anomaly formula instead of the stochastic EnKF perturbation.
Construct by passing an Ensemble with strategy=EnSRKFStrategy() as the prior:
prior = Ensemble(values; strategy=EnSRKFStrategy())
f = KalmanFilter(transition, observation, prior)Opal.EnSRKFStrategy — Type
struct EnSRKFStrategy <: EnsembleStyle endTrait for ensembles using the Ensemble Square-Root Kalman Filter (EnSRKF) method. The filter is deterministic: observations are not perturbed, so the ensemble spread is updated exactly via a square-root factorisation of the innovation covariance rather than by the stochastic perturbation of the standard EnKF.
The analysis proceeds as follows:
- run the forecast step on each ensemble member (see
forecast!); - compute the observation anomaly $S = H A_f$ where $H$ is the Jacobian of the observation model and $A_f$ the forecast anomaly;
- assemble the innovation covariance
\[C = (n_e - 1)R + S S^{\top}\]
and eigendecompose it as $C = \Phi \Lambda \Phi^{\top}$;
- compute the mean Kalman gain
\[K = P_{xy} C^{-1}\]
where $P_{xy}$ is the state–observation cross-covariance;
- form $E = \Lambda^{-1/2} \Phi^{\top} S$ (shape $m \times n_e$) and compute its SVD $E = U \Sigma V^{\top}$;
- update the ensemble mean
\[\mu_a = \mu_f + K \tilde{y}\]
where $\tilde{y} = z - H \mu_f$ is the mean innovation;
- update the ensemble anomaly
\[A_a = A_f \cdot V \sqrt{I - \Sigma^{\top}\Sigma}\, V^{\top}\]
- rebuild each ensemble member as $E[:,i] = \mu_a + A_a[:,i]$.
Opal.Ensemble — Type
struct Ensemble{C<:EnsembleStyle,A<:AbstractMatrix,B<:AbstractVector} <: SecondMoment
values::A
mean::B
anomaly::A
strategy::C
endThis SecondMoment distribution represents the ensemble needed to run the EnsembleKalmanFilter. Fields:
values: $n × n_e$-dimensional matrix storing the ensemble values;mean: $n$-dimensional vector representing the ensemble mean;anomaly: $n × n_e$-dimensional matrix storing the ensemble anomaly;strategy: trait of typeEnsembleStylewhich determines the update type of the ensemble.
Opal.EnsembleKalmanFilter — Type
struct EnsembleKalmanFilter{A<:Model,B<:Model,C<:Law,D<:Law,E<:Law,F<:Law,G<:EnsembleStyle} <: KalmanFilterImplements an Ensemble Kalman Filter. In particular:
- instead of propagating a single probability distribution as in a Kalman filter, we do so for several different (ensemble) distributions.
- the explicit update of the state covariance matrix is not required. Indeed, the variability of the state is implicitly encoded in the ensemble's spread.
- the remaining steps are equivalent to a standard Kalman Filter.
The EnsembleStyle type parameter G is inferred from the strategy of the prior Ensemble at construction time. Subtypes:
Opal.EnsembleStyle — Type
abstract type EnsembleStyle endTrait specifying how the ensemble covariance of an Ensemble distribution should be updated. The reason why this is kept as a parameter is that, in ensemble filtering strategies, computing the ensemble covariance with the usual formula
\[Σ = ∑ᵢ (E[:,i] - μ)*(E[:,i] - μ)ᵀ / (nₑ - 1)\]
is generally expensive, and thus alternative strategies are sought. Here, $E$ are the ensemble members. Subtypes:
Opal.FirstMoment — Type
const FirstMoment = Law{1}Type reserved for distributions characterised only by their first moment, i.e. the mean, accessed via the function mean.
Opal.GaspariCohn — Type
struct GaspariCohn <: TaperFunction endFifth-order piecewise-polynomial taper (Gaspari & Cohn 1999). Compactly supported on |x| ≤ 1, smooth at the origin, and non-negative everywhere. The standard default for ensemble covariance localisation.
Opal.GaussianTaper — Type
struct GaussianTaper <: TaperFunction endGaussian taper exp(-x²/2). Globally supported (never exactly zero), so it damps but does not hard-threshold long-range correlations.
Opal.GenericFirstMoment — Type
struct GenericFirstMoment{A<:AbstractVector} <: FirstMoment
mean::A
endMost basic implementation of a FirstMoment distribution.
Opal.GenericModel — Type
struct GenericModel{F<:FType} <: NonlinearModel
form::F
endStandard implementation of a NonlinearModel. The field form represents the function or Gridap Map characterising the model itself.
Opal.History — Type
Opal.ImportanceSampling — Type
struct ImportanceSampling <: ResamplingStyleResampling strategy for Particle filters that uses systematic importance resampling without kernel smoothing (SIR filter). Particles are resampled when the effective sample size drops below the threshold stored in the Particle prior.
Opal.InflationFilter — Type
struct InflationFilter{A<:KalmanFilter,B<:InflationModel} <: KalmanFilterWraps an inner Kalman filter A and inflates the forecast covariance before computing the Kalman gain, using the inflation strategy B.
Covariance inflation counteracts ensemble collapse and filter divergence by artificially broadening the prior. Two strategies are available:
MultInflation: multiplies the covariance by a fixed scalarρ;NLLInflation: adaptively tunesρat each step by minimising the negative log-likelihood of the innovation.
Fields:
filter: the underlyingKalmanFilter;inflation: anInflationModelthat supplies (and optionally optimises) the inflation factor;cache: stashed prior/obs-prior and optimisation workspace for the adaptive case.
Construct via InflationFilter(filter; inflation=MultInflation()) or from raw transition/observation/prior arguments (which automatically includes localisation).
Opal.InflationModel — Type
abstract type InflationModel endBase type for covariance-inflation strategies used by InflationFilter. An InflationModel supplies a scalar factor ρ by which the forecast covariance is multiplied before the Kalman gain is computed.
Subtypes:
MultInflation: constant multiplicative inflation;NLLInflation: adaptive inflation tuned by negative log-likelihood.
Opal.KalmanFilter — Type
struct KalmanFilter{A<:Model,B<:Model,C<:Law,D<:Law,E<:Law,F<:Law} <: Filter
transition::A
observation::B
prior::C
obs_prior::D
noise::E
obs_noise::F
cache::KalmanCache
endKalman filter subtype implementing a Kalman filter procedure. Fields:
- transition:
Modelrepresenting the transition operator; - observation:
Modelrepresenting the observation operator; - prior:
Lawrepresenting the probability distribution for the state; - obs_prior:
Lawrepresenting the probability distribution for the observation; - noise:
Lawrepresenting the probability distribution for the process (state) noise; - obs_noise:
Lawrepresenting the probability distribution for the observation noise; - cache: cached object allowing for efficient in-place operations.
Opal.KrigingCalibration — Type
struct KrigingCalibration <: UnbiasedCalibrationCalibration strategy based on Kriging that estimates a bias correction and inflated observation-error covariance from reduced-basis snapshot data.
At each assimilation step the Kriging system is solved using the precomputed variogram fit to produce a weight vector λ; the correction is then applied to the current observation error estimate.
Construct via:
KrigingCalibration(observation, fesnaps, rbsnaps; variogram=ParametricSphere{2}())
KrigingCalibration(observation, fesnaps, rbsnaps, ts) # restrict to DA phase of tsOpal.Linear — Type
struct Linear <: Linearity endTrait used by LinearModel.
Opal.LinearModel — Type
const LinearModel = Model{Linear}Models that are fully characterised by an $m × n$-dimensional Jacobian matrix $J$, i.e.
\[x ↦ J⋅x\]
represents the action of a LinearModel on an $n$-dimensional vector $x$. If the input is a distribution $d$, then:
- if $d$ is a
FirstMomentdistribution with mean $μ$, then the output is aFirstMoment
with mean $J⋅μ$;
- $d$ is a
SecondMomentdistribution with mean $μ$ and covariance $Σ$, then the output
is a SecondMoment with mean $J⋅μ$, and covariance $J⋅P⋅Jᵀ$.
Opal.Linearity — Type
abstract type Linearity endA Model trait that allows certain optimizations during the evaluation of the models themselves.
Opal.LocalisationFilter — Type
struct LocalisationFilter{A<:KalmanFilter} <: KalmanFilterWraps an inner Kalman filter A and applies covariance localisation after each forecast step via a TaperModel.
Localisation suppresses spurious long-range correlations that arise in ensemble-based filters when the ensemble size is small relative to the state dimension. After the transition step the sample covariance (or anomaly matrix) is element-wise multiplied by a distance-decay taper function.
Fields:
filter: the underlyingKalmanFilter;taper: aTaperModelthat defines the taper function and the distance matrix;cache: pre-allocated workspace for the taper computation.
Construct via LocalisationFilter(filter; taper=GaspariCohn(), npoints=n) or by passing transition, observation, and prior directly.
Opal.MemoryModel — Type
struct MemoryModel{A<:Linearity} <: Model{A}A Model wrapper that pre-allocates and reuses the evaluation cache across calls.
Unlike a bare model — which allocates a fresh cache on every evaluate! call — a MemoryModel holds a persistent cache and prior that are reused. This makes it suitable for models (e.g. ODEModel) whose cache encapsulates integrator state that must be preserved between steps.
Fields:
model: the wrappedModel;prior: the input distribution, updated in-place on each call;cache: the persistent evaluation cache returned byreturn_cache(model, prior).
Construct via MemoryModel(model, prior).
Opal.Model — Type
abstract type Model{A<:Linearity} <: Map endType used for operator-like quantities, such as functions or Gridap Maps. For performance reasons, we distinguish models depending on their Linearity trait. To evaluate a Model a in a point $x$ — usually an $n$-dimensional vector or a scalar — simply call
a(x)
which automatically triggers the function evaluate(a,x), originally defined in Gridap, and overwritten here a few times. For in-place evaluations, use instead the syntax
evaluate!(cache,a,x)
where cache = return_cache(a,x) is a suitable cached object.
The main characteristic of a Model is that it may also be evaluated in a probability distribution. Given an input Law prior, the output
posteriori = a(priori)
returns another distribution posteriori, which should be thought of the propagation of priori through the model a. The type of Model and input Law determine the expression of posterior.
Opal.Modifier — Type
struct Modifier{A<:NormaliseStyle,B<:TransformStyle,C<:BiasStyle} <: DataTransformationComposable pre-processing pipeline applied to reservoir inputs or states. Sequentially applies normalisation → transformation → bias appending.
Construct via Modifier(; normalisation, transformation, bias) or use DoNotModify for the identity pipeline.
Opal.MultInflation — Type
struct MultInflation <: InflationModelConstant multiplicative covariance inflation. The forecast covariance is scaled by the fixed factor ρ at every analysis step.
Fields:
ρ: inflation factor (default1.0, i.e. no inflation).
Construct via MultInflation(ρ) or MultInflation() for the identity.
Opal.NLLInflation — Type
struct NLLInflation <: InflationModelAdaptive multiplicative covariance inflation that tunes the factor ρ at every analysis step by minimising the negative log-likelihood of the innovation.
The optimal ρ is found by a scalar line search over [lower, upper]. The iteration stops when the reduction in NLL falls below tolerance.
Fields:
bounds:(lower, upper)box constraint onρ(defaults:(1e-3, 10.0));tolerance: stopping criterion for the inner NLL optimisation (default1e-1);ρ: mutable reference to the current inflation factor (reset to-1.0each step).
Construct via NLLInflation(; lower=1e-3, upper=10.0, tolerance=1e-1).
Opal.NLLInflationKalmanFilter — Type
const NLLInflationKalmanFilter{A<:KalmanFilter} = InflationFilter{A,<:NLLInflation}Opal.NeuralNetwork — Type
abstract type NeuralNetwork <: Map endBase type for all neural-network models. Subtypes must implement get_parameters (returns the trainable weight matrices) and extend train / forecast. The main concrete subtype is RecurrentNeuralNetwork (and in particular EchoStateNetwork).
Opal.NoAugmentation — Type
struct NoAugmentation <: DataAugmentation endIdentity augmentation: returns the input unchanged.
Opal.NoBias — Type
struct NoBias <: BiasStyle endIdentity bias: returns the input unchanged (no extra component appended).
Opal.NoNormalisation — Type
struct NoNormalisation <: NormaliseStyle endIdentity normalisation: returns the input unchanged.
Opal.NoRegularisation — Type
struct NoRegularisation <: DataRegularisation endIdentity regularisation: returns the input unchanged.
Opal.NoTransformation — Type
struct NoTransformation <: TransformStyle endIdentity transformation: returns the input unchanged.
Opal.Nonlinear — Type
struct Nonlinear <: Linearity endTrait used by NonlinearModel.
Opal.NonlinearModel — Type
const NonlinearModel = Model{Nonlinear}Models that are in general characterised by either a function, or a Gridap Map. Denoting such function/Map by by f, the action of a NonlinearModel on an $n$-dimensional vector $x$ is simply defined by
\[x ↦ f(x)\]
where the output is an $m$-dimensional vector, or a scalar. If the input is a distribution $d$, then:
- if $d$ is a
FirstMomentdistribution with mean $μ$, then the output is aFirstMoment
with mean f(μ);
- $d$ is a
SecondMomentdistribution with mean $μ$ and covariance $Σ$, then the output
is a SecondMoment with mean f(μ), and covariance whose definition depends on the types of boht a and $d$.
Opal.NormalLaw — Type
struct NormalLaw{A<:AbstractVector,B<:AbstractMatrix} <: SecondMoment
mean::A
covariance::B
endNormal distribution of mean mean and covariance covariance; a SecondMoment distribution defaults to a NormalLaw.
Opal.Normalisation — Type
struct Normalisation{A<:AbstractVector} <: NormaliseStyleElement-wise normalisation: divides each component x[i] by factor[i].
Opal.NormaliseStyle — Type
abstract type NormaliseStyle endBase type for normalisation strategies within a Modifier pipeline. Concrete subtypes: NoNormalisation, Normalisation.
Opal.ODEAdjointProblem — Type
const ODEAdjointProblem = AdjointProblem{<:ODEStateMap}An AdjointProblem built from an ODE (ODEWrapper) state map; dispatches to the Optimization.jl/Fminbox(BFGS()) optimise method.
Opal.ODEModel — Type
struct ODEModel{A} <: DifferentialModelWraps an ODEWrapper (an ODE integrator) as a NonlinearModel.
Each call to evaluate! advances the integrator by one step from the current state, making it suitable as the transition model in a filter operating on ODE-governed systems. Construct via Model(sol::ODEWrapper).
Opal.PDEAdjointProblem — Type
const PDEAdjointProblem = AdjointProblem{<:PDEStateMap}An AdjointProblem built from a PDE (AffineFEStateMap/ NonlinearFEStateMap) state map; dispatches to the Optim.jl/Fminbox(LBFGS()) optimise method.
Opal.ParametricSphere — Type
struct ParametricSphere{N} <: VariogramModelParametric spherical variogram model with N free parameters, used inside KrigingCalibration to fit the spatial covariance structure of the observation errors from snapshot data.
ParametricSphere{1}(): unit-sill spherical model (one range parameter);ParametricSphere{2}(): two-parameter model (sill + range).
Opal.Particle — Type
struct Particle{A,B,C,D} <: FirstMomentWeighted particle cloud representing a probability distribution for use with ParticleFilter.
Fields:
particles: $n \times N_s$ matrix; each column is one particle;weights: $N_s$-vector of normalised importance weights;mean: $n$-vector of the particle mean;strategy:ResamplingStrategythat controls when and how resampling occurs.
Construct via:
Particle(particles, weights, ImportanceSampling()) # SIR
Particle(particles, weights, RegularisedSampling()) # RPF (default)
Particle(particles, weights) # same as RegularisedSamplingPass nthreshold as a keyword to override the effective-sample-size threshold.
Opal.ParticleFilter — Type
struct ParticleFilter{...} <: KalmanFilterSequential Monte Carlo filter using a particles approximation of the state distribution. The resampling strategy is determined by the ResamplingStrategy embedded in the Particle prior; by default this is RegularisedSampling, which runs the Regularised Particle Filter (RPF) of Berry & Sauer (2002).
Construct via the generic interface:
KalmanFilter(transition, observation, prior::Particle; Q, R, noise, obs_noise)Fields:
Opal.RTS — Type
struct RTS <: SmootherRauch–Tung–Striebel (RTS) smoother.
Given the sequence of filter posteriors produced by loop, runs a backward pass that refines each estimate using information from all future observations. For a linear-Gaussian model the RTS smoother is the exact fixed-interval smoother.
Use via smooth_loop to obtain smoothed histories directly, or call smoothen! on an existing filter history.
Opal.RecurrentNeuralNetwork — Type
abstract type RecurrentNeuralNetwork <: NeuralNetwork endBase type for recurrent neural networks. Subtypes must implement get_state (internal hidden state) and get_output (current readout). The main concrete subtype is EchoStateNetwork.
Opal.RecycleValidation — Type
struct RecycleValidation{A<:TrainMethod,B<:UpdateRule} <: TrainMethodTraining method that wraps another TrainMethod and tunes hyper-parameters via cross-validation on held-out forecast windows (the "recycle" trick).
For each candidate in updates the network is trained, then its closed-loop forecast error over each window in windows is evaluated with loss. The candidate with the lowest total loss is selected, and a final training pass is performed with it.
Fields:
method: inner training method (e.g.TrainRecurrentNeuralNetwork);updates: anUpdateRuleiterable of hyper-parameter candidates;windows: tuple of index ranges defining the validation forecast windows;loss: scoring function(true, predicted) -> Real(defaultlog10RMSE).iterations: number of iterations for local refinement step after the grid search.
Construct via RecycleValidation(method, ranges...; Nfolds, Ntrain, Nvalidation, loss, iterations).
Opal.RegularisedParticleMetadata — Type
struct RegularisedParticleMetadata <: ParticleMetadataPre-allocated scratch workspace for the Regularised Particle Filter resampling step.
Fields:
particles_scratch:n_x × n_sbuffer used for systematic resampling;Sk:n_x × n_xbuffer for the weighted empirical state covariance;Dk:n_x × n_xbuffer for the lower Cholesky factor ofSk;c:n_xbuffer for sampling from the Epanechnikov kernel.
Opal.RegularisedSampling — Type
struct RegularisedSampling <: ResamplingStyleResampling strategy for Particle filters that applies the optimal-bandwidth Epanechnikov kernel perturbation after systematic resampling (Regularised Particle Filter, RPF). This is the default resampling style and prevents particle collapse in low-noise settings while preserving the correct second moment.
Opal.RidgeRegression — Type
struct RidgeRegression <: GridapTypeTikhonov-regularised (ridge) least-squares solver.
Solves $\min_X \|AX - B\|^2 + \lambda \|X\|^2$ via the normal equations $(A A^\top + \lambda I) X = A B^\top$. The regularisation parameter λ is stored as a mutable reference so it can be updated by RecycleValidation during hyper-parameter search.
Construct via RidgeRegression(λ::Real).
Opal.SecondMoment — Type
const SecondMoment = Law{2}Type reserved for distributions characterised by their first two moments, i.e. mean and covariance, accessed via the functions mean and cov.
Opal.SecondOrderResultsTable — Type
mutable struct SecondOrderResultsTable <: ResultsTable
innovation_means::AbstractVector{<:AbstractVector{<:Real}}
innovation_stds::AbstractVector{<:AbstractVector{<:Real}}
innovation_nis::AbstractVector{<:Real}
innovation_rmse::AbstractVector{<:Real}
endStores innovation diagnostics collected step-by-step during loop. Access via result.table on the returned DAResults.
Fields:
innovation_means: mean innovation vector at each step (length-m vectors)innovation_stds: diagonal std of the observation prior at each stepinnovation_nis: Normalized Innovation Squared at each stepinnovation_rmse: RMS of the mean innovation at each step
Opal.SigmaPoints — Type
struct SigmaPoints{A<:AbstractVector,B<:AbstractMatrix,C<:AbstractMatrix,D<:AbstractVector,E<:Real} <: SecondMoment
mean::A
covariance::B
points::C
weights_mean::D
weights_cov::D
λ::E
endThis SecondMoment distribution represents the sigma points needed to run the UnscentedKalmanFilter. Fields:
points: $n × (2*L + 1)$-dimensional matrix storing the values of the sigma points;mean: $n$-dimensional vector representing the weighted mean ofpoints;covariance: $n × n$-dimensional matrix representing the weighted covariance ofpoints;weights_mean: $(2*L + 1)$-dimensional vector storing weights formean;weights_cov: $(2*L + 1)$-dimensional vector storing weights forcovariance;λ: real value used in the update of the sigma pointspoints.
In an Unscented Transformation, two things occur in an iterative fashion:
- the field
pointsis updated in-place via a call tosigma_points!; - the fields
meanandcovarianceare updated in-place via a call toupdate!.
Opal.StateToObservationMap — Type
struct StateToObservationMap{A<:Linearity} <: Model{A}
model::Model{A}
u_to_obs_ids::AbstractVector
endWraps a Model model (typically a LinearModel selection/observation operator) and scatters its output back into a state-sized vector, placing model(u)[k] at u_to_obs_ids[k] and zero everywhere else.
Two evaluation modes are supported:
evaluate(a,u): the raw scatter ofmodel(u);evaluate(a,u,obs,W): the scatter ofW*(model(u) - obs), i.e. a weighted residual against observationsobs– this is the formbuild_lossuses to assemble the parameter-identification loss.
Custom rrules are defined for both modes below; both linearise model (via jac) at the point of evaluation, consistent with how build_loss always uses it. u_to_obs_ids defaults to _find_u_to_obs_ids when omitted, which requires model::LinearModel and errors if it is not injective.
Opal.StencilArray — Type
struct StencilArray{A<:AbstractArray,B}Wraps an array together with a TimeStencils descriptor and a phase tag so that it can be re-indexed at a different phase (with automatic restriction or expansion).
Construct via to_stencil; index with a phase constant to extract or rephase the data:
sa = to_stencil(x, ts, TRAIN)
sa[DA] # restrict (or expand) x to the DA phaseOpal.TaperModel — Type
struct TaperModel <: NonlinearModelApplies element-wise covariance localisation to a sample covariance or ensemble anomaly.
Given a covariance matrix $\Sigma$, the localised matrix is
\[\Sigma_{ij}^{\text{loc}} = f\!\left(d_{ij}/r\right) \cdot \Sigma_{ij}\]
where $f$ is a TaperFunction, $d_{ij}$ is the pre-computed distance between indices $i$ and $j$, and $r$ is the localisation radius (mutable, may be optimised).
The result is projected back to the nearest positive-semidefinite matrix via SVD to ensure it remains a valid covariance.
Fields:
taper: aTaperFunctioninstance;distance: symmetric matrix of pairwise distances;radius: mutable reference to the localisation radius.
Construct via TaperModel(npoints; taper=GaspariCohn(), distance=ℓ2, radius=1.0).
Opal.TimeStencils — Type
struct TimeStencilsDescriptor of the time axis partitioned into named phases used by the RC/DA pipeline.
Fields:
dt: model integration time step;dt_obs: observation time step (defaults todt);all_window,warmup_window,train_window,washout_window,spread_window,da_window:(t_start, t_end)tuples for each phase.
Construct via keyword arguments:
ts = TimeStencils(dt=0.01, dt_obs=0.1, t_warmup=10.0, t_train=50.0, t_wash=5.0, t_spread=5.0, t_da=20.0)Index with phase constants to get the corresponding time stencil:
ts[DA] # time steps in the DA phase
ts[TRAIN] # time steps in the training phaseOpal.TrainRecurrentNeuralNetwork — Type
struct TrainRecurrentNeuralNetwork <: TrainMethodTraining strategy for RecurrentNeuralNetwork subtypes.
The readout weights are fitted by ridge regression on the reservoir states collected during an open-loop run. Optional data augmentation and regularisation are applied before fitting, and a forget period discards the initial transient.
Fields:
solver: aRidgeRegressionsolver (holds the Tikhonov parameterλ);augmentation: aDataAugmentationapplied to inputs before training;regularisation: aDataRegularisationapplied to reservoir states;forget: number of initial steps to discard before regression.
Construct via TrainRecurrentNeuralNetwork(; augmentation=..., regularisation=..., forget=0, λ=1e-16).
Opal.TransformStyle — Type
abstract type TransformStyle endBase type for nonlinear input-transformation strategies within a Modifier. Concrete subtypes: NoTransformation, T₁, T₂, T₃.
Opal.TransientPDEModel — Type
struct TransientPDEModel{A<:ODESolution} <: DifferentialModelWraps a Gridap/GridapROMs ODESolution (a parametric or non-parametric PDE solution object) as a NonlinearModel.
Each call to evaluate! advances the PDE solver by one time step, making it suitable as the transition model in a filter for PDE-governed dynamical systems. Construct via Model(sol::ODESolution).
Opal.TransientPDEStateMap — Type
TransientPDEStateMap(step,U,V,P,u0,grid,pspace,output_ids=eachindex(grid); p=nothing, kwargs...)Build a PDEStateMap for a transient PDE. p is only used when pspace is nothing (an unparameterised map): it is the fixed physical parameter combined with the varying u0 at each step (see evaluate) – the PDE analogue of ODEWrapper's prob.p in the ODEStateMap{Nothing} case. When pspace is an actual ParamSpace, p is unused (the physical parameter is the thing being varied instead) and should be left at its default.
Opal.UniformLaw — Type
struct UniformLaw{A<:AbstractVector,B<:AbstractMatrix} <: SecondMoment
mean::A
covariance::B
lower_bound::A
upper_bound::A
endUniform distribution of mean mean and covariance covariance.
Opal.UnscentedKalmanFilter — Type
struct UnscentedKalmanFilter{A<:Model,B<:Model,C<:Law,D<:Law,E<:Law,F<:Law} <: KalmanFilterImplements the unscented transform. This model is analogous to a Kalman filter procedure for nonlinear transition/observation models, handling nonlinearities via sigma points (see SigmaPoints). These are a set of interpolation points used to approximate the first and second moments of a transitioned/observed distribution via a weighted linear combination. In particular:
- for the forecasting step: we update the sigma points from the analysed distribution of the previous iteration; evaluate the transition model at each sigma point; update mean and covariance via weighted linear combinations (see
SigmaPoints); - for the analysis step: we evaluate the observation model at each sigma point; update mean and covariance; compute innovation, Kalman gain, and state posterior as in a standard Kalman filter.
The prior C and observation prior D must both be (or wrap) SigmaPoints. Construct via KalmanFilter(transition, observation, prior) with a SigmaPoints (or ConstrainedSigmaPoints) prior.
Opal.UpdateRule — Type
abstract type UpdateRule endBase type for hyper-parameter search strategies used by RecycleValidation. Concrete subtypes iterate over candidate parameter sets:
UpdateRule(stencils...): grid-search over Cartesian product of ranges (NetworkUpdate);UpdateRule(tikhonov, ranges...): joint grid over ridgeλand network parameters (NetworkAndTikhonovUpdate).
Opal.VariationalMethod — Type
struct VariationalMethod{A<:StateMap,B} <: DAMethodVariational data-assimilation method (4D-Var / weak-constraint 4D-Var style).
Minimises a cost function that balances fidelity to observations (obs_to_ℓ) against departure from the background (back_noise) over a time window defined by μ_to_u.
Fields:
μ_to_u:StateMapfrom control parameters to model state trajectories;u_to_obs:StateToObservationMapprojecting the trajectory to observation space;obs_to_ℓ: loss function(ỹ, μ) -> ℓmeasuring observation misfit;back_noise,obs_noise: background and observation errorSecondMomentdistributions.
Construct via:
VariationalMethod(μ_to_u, u_to_obs, obs_to_ℓ; B=..., R=...)Opal.DoNotModify — Method
DoNotModify() -> ModifierReturns the identity Modifier: no normalisation, no transformation, no bias.
Opal.InnovationACF — Method
InnovationACF(t::ResultsTable;maxlag=20) -> AbstractVectorAutocorrelation function of the innovation-norm time series from table. Under a well-specified filter innovations should be white noise, so ACF[lag > 0] ≈ 0.
Opal.NEES — Method
NEES(true_values::AbstractVector,d::Law) -> RealNormalized Estimation Error Squared. Under a well-calibrated filter, the expected value is 1. Values > 1 indicate underestimated uncertainty; < 1 indicate overestimated uncertainty.
NEES(true_values::AbstractMatrix,history::History) -> AbstractVectorOpal.NLL — Method
NLL(true_values::AbstractVector,d::Law) -> RealComputes the Negative Log Likelihood between the true data true_values and the first moment of the distribution d.
NLL(true_values::AbstractMatrix,history::History) -> AbstractVectorComputes the Negative Log Likelihood between the true data true_values and history, the historical distributions obtained by running the Kalman iterations.
Opal.NRMSE — Method
NRMSE(true_values::AbstractVector,d::Law) -> RealComputes the Normalised Root Mean Square Error between the true data true_values and the first moment of the distribution d. This is equal to the Root Mean Square Error divided by the standard deviation of d.
NRMSE(true_values::AbstractMatrix,history::History) -> AbstractVectorComputes the Normalised Root Mean Square Error between the true data true_values and history, the historical distributions obtained by running the Kalman iterations.
Opal.Noise — Method
Noise(Σ::AbstractMatrix) -> NormalLawConstructs a zero-mean NormalLaw with covariance Σ. Intended for specifying process noise $\theta$ and observation noise $\eta$ in a filter.
Opal.NovoaEchoStateNetwork — Method
NovoaEchoStateNetwork(args...; kwargs...) -> EchoStateNetworkVariant of EchoStateNetwork using the sparse reservoir initialisation from Novoa et al., with one non-zero entry per row in weights_in. Accepts the same arguments as EchoStateNetwork.
Opal.RMSE — Method
RMSE(true_values::AbstractVector,d::Law) -> RealComputes the Root Mean Square Error between the true data true_values and the first moment of the distribution d.
RMSE(true_values::AbstractMatrix,history::History) -> AbstractVectorComputes the Root Mean Square Error between the true data true_values and history, the historical distributions obtained by running the Kalman iterations.
Opal.RankHistogram — Method
RankHistogram(true_values::AbstractMatrix,history::AbstractVector{<:Ensemble}) -> AbstractVectorRank (Talagrand) histogram. For each time step and state variable, counts the rank of the true value within the sorted ensemble. A flat histogram indicates a well-calibrated ensemble; U-shaped indicates underdispersion; dome-shaped indicates overdispersion. Returns a normalised frequency vector of length ne + 1.
Opal.SpreadSkillRatio — Method
SpreadSkillRatio(true_values::AbstractVector,d::Law) -> RealRatio of mean ensemble spread to RMSE. Values ≈ 1 indicate a well-calibrated ensemble. Values < 1 indicate underdispersion; > 1 indicate overdispersion.
SpreadSkillRatio(true_values::AbstractMatrix,history::History) -> AbstractVectorOpal.ad_compatible — Method
ad_compatible(a) -> FunctionWraps a coefficient-building function a, where a(μ) returns a spatial closure x -> ... for a numeric parameter vector μ, so that the result also works when called with a parameter CellField μh (e.g. an FEFunction on a ConstantFESpace, or a dual-valued CellField produced internally by Gridap's automatic differentiation w.r.t. μh's DOFs). The returned function aμ(μh) builds a proper lazy CellField via Operation, evaluated at the true quadrature points of whichever Measure it ends up composed into – it never extracts μh into a raw numeric vector, which would break under AD (compare to test/AD.jl's equivalent, hand-written Operation-based pattern).
Example
a(μ) = x -> 1 + exp(-x[1]/sum(μ))
aμ = ad_compatible(a)
afe(u,v,μh) = ∫(aμ(μh)*∇(v)⋅∇(u))dΩOpal.analyse! — Method
analyse!(posterior::Law,f::Filter,args...) -> LawIn-place execution of the analysis step of a Kalman filter algorithm. This step consists of the following operations:
- Running the observation model on the forecasted distribution (see
observation!) - Computing the innovation (see
innovation!) - Computing the Kalman gain (see
kalman_gain!) - Updating the forecasted distribution by accounting for the Kalman gain (see
update!)
To run an iteration of the Kalman filter, one must run the forecasting step in forecast! prior to the analysis one. If no optional argument is provided, the analysis is not performed.
Opal.build_linear_observation_model — Function
build_linear_observation_model(
ids::AbstractVector,
obs_ids::AbstractVector = ids
) -> AlgebraicModelBuilds a linear observation model (selection matrix $H$) that extracts the components at indices obs_ids from a state vector of length length(ids).
obs_ids must already be indices into the full state vector (offset by the caller if the observed quantity is a sub-block of a larger vector). Returns an AlgebraicModel wrapping the sparse (length(obs_ids) × length(ids)) matrix.
Opal.build_observations — Method
build_observations(
a::Model,
x::AbstractMatrix,
[obs_noise::Law],
args::Function...
) -> AbstractMatrixApplies the observation model a column-by-column to the state matrix x (each column is one time step) and collects the results into an (m × T) observation matrix, where m = dimension(a(x[:,1])) and T = size(x, 2).
Optional positional Function arguments b are called as b(x[:,k]) and their output is added to the observation at step k (useful for adding a bias term). If obs_noise::Law is provided, a random draw from it is added to every column.
Opal.build_prior — Method
build_prior(state::AbstractVector; kwargs...) -> FirstMoment
build_prior(states::AbstractMatrix; nsamples=1, kwargs...) -> Ensemble
build_prior(state, noise::SecondMoment; nsamples=1, kwargs...) -> SecondMoment or Ensemble
build_prior(states, c::AbstractConstraint; kwargs...) -> ConstrainedLawConstructs the initial prior distribution from a state snapshot or ensemble matrix.
- A
Vectorwith no noise returns aFirstMoment; - a
Matrixreturns anEnsemble; - adding a
noise::SecondMomentdrawsnsamplesperturbations and sets the covariance; - adding a constraint
cwraps the result in aConstrainedLaw.
AbstractBlockVector/AbstractBlockMatrix inputs produce block-structured joint distributions.
Opal.dimension — Method
dimension(d::Law) -> IntDimension of the (vector) space on which the distribution is defined.
Opal.draw — Method
draw(d::SecondMoment) -> AbstractVector
draw(d::SecondMoment,nsamples::Int) -> AbstractMatrixDraws a $n$-dimensional random vector from the distribution d, where $n$ represents the dimension of d (see distribution). If an integer nsamples is also provided, the output will be an $n × nsamples$ - dimensional matrix. γ represents a scaling factor for the draw.
Opal.equispaced_windows — Method
equispaced_windows(nobs, nwindows=1) -> NTuple of UnitRange
equispaced_windows(grid, nwindows=1)
equispaced_windows(ts::TimeStencils, nwindows=1)Partition nobs observation indices (or the DA phase of ts) into nwindows nearly equal contiguous windows. Returns a tuple of UnitRanges.
Opal.execute — Method
execute(a::Model, prior::Law, stencil::AbstractVector) -> History
execute(f::Filter, stencil::AbstractVector) -> HistoryRuns the model a (or the transition model of filter f) forward for length(stencil) steps starting from prior, recording a copy of the distribution at each step. Returns the history as a vector of distributions.
Opal.forecast! — Method
forecast!(posterior::Law,f::Filter) -> LawIn-place execution of the forecast step of a Kalman filter algorithm. This step consists of the following operations:
- Running the transition model on the prior distribution (see
transition!)
To complete a single iteration of the Kalman filter, one must run the analysis step in analyse! following the forecast one.
Opal.forecast — Method
forecast(network::NeuralNetwork, stencil; kwargs...) -> AbstractArrayRuns network in closed-loop (autoregressive) mode for length(stencil) steps: the output at each step is fed back as the input for the next. Returns the sequence of outputs.
Opal.forecasted_history — Method
forecasted_history(args...) -> HistoryAlias for execute. Runs the model forward and returns the full history of distributions. Accepts the same arguments as execute.
Opal.forecasted_law — Method
forecasted_law(args...) -> LawReturns only the final distribution from forecasted_history.
Opal.geostrophic — Method
geostrophic(n::Int) -> AbstractMatrix
geostrophic(n::Dims{2}) -> AbstractMatrixReturns the pairwise Euclidean distance matrix for a 2-D Cartesian grid of shape (n, n) (or n when given as a Dims{2} tuple), laid out in column-major order. Intended for geophysical applications where the state is defined on a regular 2-D domain.
Opal.get_noise — Method
get_noise(f::Filter) -> LawFetches the transition noise from the filter f. This noise, denoted by $θ$, is such that
\[xₙ₊₁ := F(xₙ) + θ\]
where ${xₖ}ₖ$ is the state process, and $F$ is the transition model.
Opal.get_observation_model — Method
get_observation_model(f::Filter) -> ModelFetches the observation model from the filter f. This model, denoted by $H$, is such that
\[yₙ := H(xₙ) + η\]
where ${xₖ}ₖ$ is the state process, ${yₖ}ₖ$ is the observed process, and $η$ is a (usually Gaussian) random variable.
Opal.get_observation_noise — Method
get_observation_noise(f::Filter) -> LawFetches the observation noise from the filter f. This noise, denoted by $η$, is such that
\[yₙ := H(xₙ) + η\]
where ${xₖ}ₖ$ is the state process, ${yₖ}ₖ$ is the observed process, and $H$ is the observation model.
Opal.get_observation_prior — Method
get_observation_prior(f::Filter) -> LawFetches the distribution of the observation variable from the filter f.
Opal.get_prior — Method
get_prior(f::Filter) -> LawFetches the distribution of the state variable from the filter f.
Opal.get_transition_model — Method
get_transition_model(f::Filter) -> ModelFetches the transition model from the filter f. This model, denoted by $F$, is such that
\[xₙ₊₁ := F(xₙ) + θ\]
where ${xₖ}ₖ$ is the state process, and $θ$ is a (usually Gaussian) random variable.
Opal.identify_parameter — Method
identify_parameter(
ad::AdjointProblem,
obs::AbstractMatrix,
args...;
x0 = initial_condition(ad.μ_to_u),
iterations = 1000,
show_trace = true,
kwargs...
)Identify the vector μ that best explains observations obs, for an AdjointProblem built from an ODE (ODEWrapper) state map, by minimising the loss precomposed into ad.μ_obs_to_ℓ (see build_loss). μ is the physical parameter for a ParamSpace-attached ODEStateMap, or the initial condition for an unparameterised one – see initial_condition.
Gradients are obtained via Zygote AD (Optimization.AutoZygote()). Optimisation uses Fminbox(BFGS()) (via OptimizationOptimJL) with box constraints from bounds(ad.μ_to_u) passed as lb/ub ((nothing,nothing) for an unparameterised map, i.e. unconstrained) – OptimizationPolyalgorithms.PolyOpt() was tried first, but despite checking prob.lb/prob.ub internally, OptimizationBase rejects it outright as an algorithm that "does not support box constraints", so it can't be used here.
Arguments
obs: observed data, in the shape expected byad.μ_obs_to_ℓ;x0: initial guess (defaults toinitial_condition(ad.μ_to_u));iterations: forwarded toOptimization.solveasmaxiters;show_trace: iftrue, the loss value is displayed at every callback;kwargs...: additional keyword arguments forwarded toOptimization.solve.
Returns the minimiser as a plain Array. Also reachable as optimise(ad::ODEAdjointProblem, obs, args...; p=initial_condition(ad.μ_to_u), kwargs...), which forwards to this function as x0=p – the p spelling is what VariationalMethod's loop/optimise machinery passes.
Opal.innovation! — Method
innovation!(f::Filter,posterior::Law,z::InType) -> InTypeGiven a distribution posterior and an observation z, returns the innovation $ỹ$ such that
\[ỹ = z - yₙ = z - [H(xᶠₙ) + η]\]
where $yₙ$ represents the observation forecasted by the filter f, and $xᶠₙ$ is distributed according to posterior.
Opal.joint_law — Method
joint_law(d::Law...) -> LawGiven a list of marginal distributions d = (d1,...,dn), returns their joint distribution.
Opal.kalman_gain! — Method
kalman_gain!(f::Filter,posterior::Law) -> AbstractMatrixIn-place computation of the Kalman gain $K$ according to the formula
\[K = Σxy ⋅ Σy⁻¹\]
where $Σxy$ and $Σy$ are the state-observation and observation covariance matrices, respectively. $K$ is storede as a cached object in f, while the covariances $Σxy$ and $Σy$ can be computed by suitably accessing the transition and observation distributions via get_prior and get_observation_prior, respectively.
Opal.linearise — Method
linearise(a::Model,x::InType) -> LinearModelLinearizes a model a around $x$. If a is a LinearModel, it returns a itself.
Opal.loop — Method
loop(f::Filter,obs::AbstractArray) -> DAResultsGiven a filter f and observations obs, iteratively runs the forecast-analyse paradigm typical of a Kalman filter, producing a DAResults that acts as a vector of posterior distributions and also carries a ResultsTable of innovation diagnostics.
If a slice of obs along its last dimension is all-NaN, the analysis step is skipped (forecast only) and NaN entries are pushed to the table. Use expand to embed sparse observations into a fine grid before passing to loop.
Opal.mixed_cov! — Method
mixed_cov!(Σ::AbstractMatrix,f::Filter,posterior::Law) -> AbstractMatrixIn-place computation of the state-observation "mixed" covariance Σ.
Opal.mixed_cov! — Method
mixed_cov!(cache,a::SigmaPoints,b::SigmaPoints) -> AbstractMatrixIn-place computation of the covariance between the SigmaPoints distributions a and b. These two distributions should have the same $L$ (i.e. the same number of sigma points) and $λ$ parameters, which also implies that they share the same mean/covariance weights. The formula used here is:
\[Σ = ∑ᵢ₌₁²ᴸ⁺¹ w[i] ⋅ (χᵃ[:,i] - μᵃ) ⋅ (χᵇ[:,i] - μᵇ)\]
where $χᵃ$ and $μᵃ$ are the sigma points and their mean for a, $χᵇ$ and $μᵇ$ are the sigma points and their mean for b, and $w$ are the covariance weights of either a or b.
Opal.observation! — Method
observation!(f::Filter,posterior::Law) -> LawIn-place application of the observation model stored in f on the distribution posterior, which represents the posterior distribution of the state variable. In essence, denoting by $F$ the transition model, if posterior represents the forecasted distribution of the state variable xᶠₙ at the $n$th iteration, this step runs the observation model
\[yₙ := H(xᶠₙ) + η\]
overwriting the result yₙ in the distribution of the observed variable stored in f, and accessible through get_observation_prior. This function should be run during the analysis step in a Kalman filter algorithm.
Opal.observe — Method
observe(a::Model, d::Law) -> AbstractArrayApplies the model a to the state (mean or ensemble matrix) of the distribution d and returns the result without modifying d. Equivalent to a(get_state(d)).
Opal.optimise — Method
optimise(
ad::PDEAdjointProblem,
obs::AbstractVecOrMat,
args...;
p = initial_condition(ad.μ_to_u),
iterations = 1000,
x_abstol = 1e-12,
x_reltol = 1e-6,
show_trace = true,
kwargs...
) -> AbstractVectorIdentify the vector μ that best explains observations obs, for an AdjointProblem built from a PDE state map, by minimising the loss precomposed into ad.μ_obs_to_ℓ (see build_loss) – typically the weighted least-squares residual
\[\ell(\mu) = \|R^{-1/2}(\mathcal{H}(u(\mu)) - y)\|_{\Omega}^2\]
where $u(\mu)$ solves the parametric PDE, $\mathcal{H}$ is the observation operator supplied at construction, and the norm is the finite-element $L^2(\Omega)$ norm. μ is the physical parameter for a ParamSpace-attached PDEStateMap, or the initial condition for an unparameterised one – see initial_condition.
Gradients are obtained via Zygote AD, which differentiates through the custom rrules on AffineFEStateMap, StateParamMap, and LinearModel. Optimization uses Fminbox(LBFGS()) with box constraints from bounds(ad.μ_to_u), falling back to unconstrained LBFGS() when those bounds are (nothing,nothing) (the unparameterised case).
Arguments
obs: observed data in the observation space;p: initial guess (defaults toinitial_condition(ad.μ_to_u));iterations,x_abstol,x_reltol,show_trace: forwarded toOptim.Options;kwargs...: additional keyword arguments forwarded toOptim.Options.
Returns the minimiser (Optim.minimizer(res)) as a plain vector.
Opal.predicted_history — Method
predicted_history(args...) -> DAResultsAlias for loop. Runs the filter forward and returns the full assimilation history (posteriors + innovation table). Accepts the same arguments as loop.
Opal.predicted_law — Method
predicted_law(args...) -> LawReturns only the final posterior distribution from predicted_history.
Opal.sigma_points! — Method
sigma_points!(dcache::SigmaPoints,d::SigmaPoints;kwargs...) -> AbstractMatrixIn-place update of the sigma points according to the formula:
\[χₖ₊₁[:,1] = μₖ χₖ₊₁[:,2:L+1] = μₖ + √((L + λ)Pₖ) χₖ₊₁[:,L+2:2L+1] = μₖ - √((L + λ)Pₖ)\]
where $μₖ$ and $Pₖ$ are the previous mean and covariance fields. The output $χₖ₊₁$ overwrites the field points.
Opal.sigma_points — Method
sigma_points(d::SecondMoment;kwargs...) -> AbstractMatrixGiven an input distribution d, computes the sigma points $χ$ according to the formula:
\[χ[:,1] = μ χ[:,2:L+1] = μ + √((L + λ)Σ) χ[:,L+2:2L+1] = μ - √((L + λ)Σ)\]
where μ and Σ are the mean and covariance of d, respectively. The variables $L$ and $λ$ may be passed as keyword arguments, and assume the following default values:
\[L = dimension(d) λ = 3 - L\]
Opal.smooth_loop — Method
smooth_loop(f::Filter, obs::AbstractArray; smoother=RTS()) -> DAResultsCombined forward-filter and backward-smoother pass.
Runs loop on f with observations obs, then immediately applies smoothen! to refine the history. Returns a DAResults whose state_history contains the smoothed posteriors.
Opal.smoothen! — Method
smoothen!(
smooth_history::History,
smoother::Smoother,
filter::Filter,
history::History
)In-place backward smoothing pass. Given the forward-filter posteriors history (from loop), overwrites smooth_history with the smoothed distributions produced by smoother.
The two-argument form smoothen!(smooth_history, filter, history; smoother=RTS()) also works and defaults to the RTS smoother.
Opal.state_blocks — Method
state_blocks(d::Law) -> TupleSplits the state vector of d into its constituent blocks, as returned by BlockArrays.blocks. Used in variational methods to separate control parameters from physical-state components.
Opal.transition! — Method
transition!(posterior::Law,f::Filter) -> LawIn-place application of the transition model stored in f on the distribution posterior, which represents the posterior distribution of the state variable. In essence, denoting by $F$ the transition model, if posterior represents the distribution of the state variable $xₙ$ at the $n$th iteration, this step runs the transition model
\[xₙ₊₁ := F(xₙ) + θ\]
overwriting the result $xₙ₊₁$ in posterior. This function should be run during the forecast step in a Kalman filter algorithm.
Opal.update! — Method
update!(cache,d::SigmaPoints) -> SigmaPointsUpdate the mean and covariance of the sigma points d.
Opal.update! — Method
update!(d::Ensemble) -> EnsembleUpdate the mean and anomaly of the ensemble d.
Opal.update! — Method
update!(posterior::Law,f::Filter) -> LawIn-place update of the distribution posterior through the action of Kalman gain matrix cached in f. Denoting by $K$ the Kalman gain computed by running kalman_gain!, and by $ỹ$ the innovation computed by running innovation!, if posterior represents the forecasted distribution of the state variable $xᶠₙ$ at the $n$th iteration, this step runs the formula
\[xᵃₙ := xᶠₙ + K ⋅ ỹ\]
and overwrites the analysed distribution of the state variable $xᵃₙ$ in posterior.
Opal.update! — Method
update!(table::ResultsTable,f::Filter)Extracts the current innovation and observation-prior std from f and appends NIS, RMSE, mean and std to table. Called automatically inside loop.
Opal.warmup! — Method
warmup!(f::Filter, stencil::AbstractVector)
warmup!(a::MemoryModel, prior::Law, stencil::AbstractVector)Advances the model or filter forward for length(stencil) steps, updating the internal state in-place without recording the history. Used to spin up memory-based models (e.g. EchoStateNetwork, ODEModel) before the assimilation window.
ReservoirComputing.train — Method
train(method::TrainMethod, network::NeuralNetwork, x, y; kwargs...) -> statesFits network on training data (x, y) using method. Allocates the training cache, runs the open-loop pass, and solves for the readout weights in-place. Returns the collected reservoir states.