Strong-constraint 4DVar assumes the forward model is exact. In reality models carry biases, omit physics, and accumulate discretisation error. Weak-constraint 4DVar addresses this by treating model error itself as a control variable Trémolet, 2006: the dynamics are allowed to be wrong by an amount at each step, and the analysis estimates those errors alongside the initial state.
Notation follows the strong-constraint note: state , background , covariances / , free-run dynamics , observation operator — plus the model-error with covariance .
Cost Function¶
The state now evolves under noisy dynamics,
so the control vector expands from to the augmented . The cost gains a third, model-error term:
with the trajectory recovered by recursively stepping (1).
Why the Model-Error Term Matters¶
Letting absorb per-step errors improves the fit at every time without distorting . It fixes two failure modes of the strong constraint:
The free model’s climatology differs from reality. Over a long window drifts away from the observations regardless of the initial condition, forcing a strong-constraint analysis to distort to compensate. The model-error term lets the drift be corrected step by step.
A model may resolve slow dynamics but miss fast processes (cloud microphysics, turbulence). Strong 4DVar mis-attributes those errors to ; weak 4DVar charges them to where they belong.
Implementation¶
The augmented control is a PyTree; the gradient over it comes from autodiff, and a general optimiser (optimistix) handles the minimisation.
import jax
import jax.numpy as jnp
import einx
from jaxtyping import Array, Float
def weak_4dvar_cost(
u0: Float[Array, "N"], # initial state
eta: Float[Array, "T N"], # model-error trajectory η₁..η_T
ub: Float[Array, "N"], # background
ys: Float[Array, "T M"], # observations
M, # free-run step: u -> M^free(u)
H, # observation operator: u -> H(u)
apply_B_inv, # v -> B⁻¹ v
apply_R_inv, # v -> R⁻¹ v
apply_Q_inv, # v -> Q⁻¹ v
) -> Float[Array, ""]:
# roll the noisy trajectory: u_t = M(u_{t-1}) + η_t
def step(u_prev, eta_t):
u_t = M(u_prev) + eta_t
return u_t, u_t
_, traj = jax.lax.scan(step, u0, eta) # (T, N)
db = u0 - ub
Jb = 0.5 * einx.dot("N, N ->", db, apply_B_inv(db)) # background
res = ys - jax.vmap(H)(traj) # (T, M)
Jo = 0.5 * jnp.sum(jax.vmap(lambda r: einx.dot("M, M ->", r, apply_R_inv(r)))(res))
Jq = 0.5 * jnp.sum(jax.vmap(lambda e: einx.dot("N, N ->", e, apply_Q_inv(e)))(eta))
return Jb + Jo + Jq
# gradient over the augmented control (u0, η)
grad_J = jax.grad(weak_4dvar_cost, argnums=(0, 1))Choosing the model-error covariance ¶
Diagonal — white Gaussian model noise, . Simple, rarely realistic.
Matérn (spatial) — a structured covariance for spatially correlated model error (FFT-based matvecs).
Markovian (time-correlated) — an Ornstein–Uhlenbeck with correlation timescale ; error decorrelates over steps, with physical motivation.
Computational Cost¶
The control dimension grows with the window length ,
For and a 2D field with , that is control variables instead of 104 — a large jump in the minimisation cost. Two mitigations:
Low-rank model error — restrict to a low-dimensional subspace (POD modes, a learned latent space) via a custom reparameterisation.
Shorter sub-windows + cycling — run weak-constraint 4DVar over short sub-windows and chain them with a smoother cycle (the operational ECMWF pattern).
Limiting Cases¶
The model-error covariance interpolates a whole spectrum of methods:
| Limit | Behaviour | Reduces to |
|---|---|---|
| is empty | 3DVar / OI | |
| (tight) | strong-constraint 4DVar | |
| (loose) | observations dominate | trajectory ignores the dynamics |
That strong-constraint is the tight- limit is the cleanest way to see why weak 4DVar can only help (at the cost of more control variables) when the model genuinely has error.
Posterior¶
The Laplace posterior is Gaussian over the augmented control , with a block covariance over that joint space. Marginalising to the state trajectory means applying the linearised forward at each time and propagating the covariance — implementation-heavy and rarely needed. When full trajectory uncertainty matters, an ensemble smoother is usually preferable.
When Weak-Constraint 4DVar Is the Right Answer¶
Observations span multiple times.
The model has known biases (climatological drift, missing physics).
Long windows show obvious late-time misfits in a strong-constraint analysis.
A reasonable is available (from model-to-reanalysis comparison).
Model error is small (within observation noise) → strong-constraint 4DVar; the extra control variables aren’t worth the cost.
You prefer a learned prior over a parametric → a 4DVarNet-style model, where the learned prior absorbs model error without an explicit augmented control.
Full trajectory uncertainty is the goal → ensemble methods.
- Trémolet, Y. (2006). Accounting for an Imperfect Model in 4D-Var. Quarterly Journal of the Royal Meteorological Society, 132(621), 2483–2504. 10.1256/qj.05.224
- Fisher, M., Leutbecher, M., & Kelly, G. A. (2005). On the Equivalence between Kalman Smoothing and Weak-Constraint Four-Dimensional Variational Data Assimilation. Quarterly Journal of the Royal Meteorological Society, 131(613), 3235–3246. 10.1256/qj.04.142
- Daescu, D. N., & Todling, R. (2010). Adjoint Sensitivity of the Model Forecast to Data Assimilation System Error Covariance Parameters. Quarterly Journal of the Royal Meteorological Society, 136(653), 2000–2012. 10.1002/qj.693