Solvers
Solving a state-space problem is as simple as calling solve(prob), which automatically selects an appropriate algorithm. You can also pass an algorithm explicitly via solve(prob, alg).
DifferenceEquations.DirectIteration — Type
DirectIteration()Forward iteration algorithm for state-space problems. Iterates the state transition equation forward in time, computing the state trajectory u, observations z, noise history W, and (if observables are provided) the joint log-likelihood logpdf.
This is the default algorithm for all problem types.
See also: KalmanFilter.
DifferenceEquations.KalmanFilter — Type
KalmanFilter()Kalman filter algorithm for LinearStateSpaceProblem. Computes filtered state estimates, posterior covariances, and the marginal log-likelihood.
Automatically selected when the problem provides:
u0_prior_meanandu0_prior_var(Gaussian prior),observables(observed data),observables_noise(observation noise covariance),noise = nothing(latent noise is not fixed).
The solution contains filtered means in sol.u, posterior covariances in sol.P, predicted observations in sol.z, and the marginal log-likelihood in sol.logpdf.
See also: DirectIteration.
DifferenceEquations.ConditionalLikelihood — Type
ConditionalLikelihood()Conditional likelihood (prediction error decomposition) algorithm for fully-observed state-space models. At each step, predicts the next observation from the observed current state using the transition equation, and accumulates the Gaussian log-likelihood of the innovation.
Works with all problem types (LinearStateSpaceProblem, StateSpaceProblem, QuadraticStateSpaceProblem, PrunedQuadraticStateSpaceProblem). The only requirement is additive Gaussian observation noise.
Requires:
observables(observed data y₁, …, y_T),observables_noise(innovation covariance R).
The solution contains predicted observations in sol.z (when an observation equation is present), the conditional log-likelihood in sol.logpdf, and the state trajectory (clamped to observables) in sol.u.
See also: DirectIteration, KalmanFilter.
Default Algorithm Selection
When no algorithm is specified, solve(prob) selects the algorithm based on the problem type and its fields:
DirectIterationis the default for all problem types. It simulates the state-space model forward in time, generating states and observations directly. Ifobservablesare provided, it computes the joint log-likelihood of the observed data given the noise sequence.KalmanFilteris auto-selected forLinearStateSpaceProblemwhen all of the following conditions hold:u0_prior_varis anAbstractMatrix(prior covariance is specified)noiseisnothing(noise is not fixed)observablesis anAbstractVector(observed data is provided)observables_noiseis anAbstractMatrix(observation noise covariance is specified)A,B, andCare allAbstractMatrix(notnothing)
The Kalman filter computes the filtered state estimates and the marginal log-likelihood of the observations, integrating over the unknown noise sequence.
ConditionalLikelihoodis never auto-selected. You must pass it explicitly viasolve(prob, ConditionalLikelihood()). Use it for fully-observed state-space models (AR, VAR, nonlinear) where the state is directly observed and you want the prediction error decomposition log-likelihood. Works with all problem types.
If any of the KalmanFilter conditions are not met, DirectIteration is silently selected instead. For example, forgetting to pass C or u0_prior_var will produce a DirectIteration solve with logpdf = 0.0 rather than the expected Kalman filter result.
save_everystep Keyword
All algorithms support save_everystep=false, which stores only the initial and final states instead of the full trajectory:
sol = solve(prob; save_everystep=false) # 2-element sol.u
sol = solve(prob, ConditionalLikelihood(); save_everystep=false)
sol = solve(prob, KalmanFilter(); save_everystep=false)When save_everystep=false:
sol.ucontains[u_initial, u_final](2 entries instead of T+1)sol.zcontains[z_initial, z_final](if observations are present)sol.Pcontains[P_initial, P_final](KalmanFilter only)sol.logpdfis identical — computed on the fly, not from stored trajectory
This is useful when you only need the final state or the log-likelihood (e.g., in optimization loops). It dramatically reduces memory allocation, which benefits ForwardDiff gradient computation:
| Scenario | Typical speedup | Allocation reduction |
|---|---|---|
| ForwardDiff + StaticArrays (KF, N=5) | 7x | 4,288 → 175 |
| ForwardDiff + StaticArrays (CL, N=5) | 3.4x | 805 → 190 |
| ForwardDiff + mutable (KF, N=30) | 1.5x | 342k → 8k |
The workspace API also supports it:
ws = init(prob, alg; save_everystep=false)
sol = solve!(ws) # reads save_everystep from workspace