vardax Tutorial Master List
A reconciled, exhaustive curriculum for learning data assimilation through vardax β JAX-native variational DA shipping seven peer pipekit_cycle.AnalysisStep methods (OI / 3DVar / strong / weak / incremental 4DVar / FourDVarNet / AmortizedPosterior) on a single set of eqx.Module primitives.
Ensemble-DA tutorials live in the sister list TUTORIAL_MASTER_LIST_FILTER.md ; GP / SVI tutorials live in ../../gaussian_processes/TUTORIAL_MASTER_LIST.md . Cross-listed items (Bayesian update, structured covariances, sigma points, validation gates, latent-space generative priors) are flagged π.
Legend β Source columns:
V = exists in vardax (docs/notebooks/<name>)G = exists in gaussx (docs/notebooks/<name>)K = exists in pipekit (docs/notebooks/<name>)R = exists in research_notebook (projects/assimilation/notebooks/<path>)β = does not exist yet (gap)Scope tag : π§± fundamental Β· π¬ research Β· π bridge Β· π cross-listed (filterax / GP master list)
Refs column : gh#N = open GitHub issue Β· dd:path = vardax docs/design/<path> Β· math:N = vardax docs/0N_<chapter>.md Β· api:foo = vardax exported symbol.
Math policy : every sectionβs first notebook (00_*) ports the relevant math chapter from vardax/docs/ directly into the tutorial, so each part is self-contained for someone learning DA from scratch. Subsequent notebooks in the section are API-driven.
Curriculum at a glance ΒΆ Part 0 β Foundations (learning DA from scratch) 0.A β The Bayesian update 0.B β Linear-Gaussian closed form (BLUE / Kalman) 0.C β Variational reformulation (cost β posterior) 0.D β pipekit-cycle protocols (the vardax shape) 0.E β Your first assimilation Part 1 β Observation operators 1.A β MaskedIdentity and the symmetric-masking invariant 1.B β LinearObs with explicit H 1.C β AveragingKernel (satellite footprints, RTM intuition) 1.D β MultiInstrumentFusion and heterogeneous obs 1.E β Writing a custom ObservationOperator Part 2 β Forward models 2.A β The pipekit_cycle.ForwardModel protocol 2.B β Lorenz family wrappers (L63, L96, L96-2L) 2.C β Shallow water (somax) 2.D β Quasi-geostrophic (somax) 2.E β Plume models (plumax) 2.F β Writing your own forward Part 3 β Static priors & covariances 3.A β Diagonal B (the simplest case) 3.B β Structured priors via gaussx (MatΓ©rn, Kronecker) 3.C β Dynamical priors (forward-as-Ο) Part 4 β Encoders & decoders (latent-space DA) 4.A β AE priors overview (BilinAE, ConvAE, MLP) 4.B β Pretraining an AE prior 4.C β Latent-space DA (assimilate in z, decode to x) 4.D β Observation encoders for amortized inference Part 5 β Optimal Interpolation (BLUE) 5.A β BLUE derivation (closed-form Kalman update) 5.B β OptimalInterpolation API walkthrough 5.C β OI with structured B Part 6 β 3DVar 6.A β The 3DVar cost 6.B β ThreeDVar API + minimiser choice 6.C β Nonlinear H with 3DVar Part 7 β Strong-constraint 4DVar 7.A β The 4DVar cost (adjoint of M) 7.B β StrongFourDVar API 7.C β forward_adjoint choices (diffrax variants) 7.D β Lorenz demo (deep dive, links to assimilation/) Part 8 β Weak-constraint 4DVar 8.A β Model-error term 8.B β WeakFourDVar API 8.C β Imbalance failure modes Part 9 β Incremental 4DVar 9.A β GN outer + CG inner 9.B β IncrementalFourDVar API 9.C β Control-variable transform (gaussx βB preconditioning) Part 10 β FourDVarNet (learned solvers) 10.A β Unrolled iteration math 10.B β FourDVarNet1D / FourDVarNet2D API 10.C β Training loop (train_step composition) 10.D β solver_adjoint dispatch (D15) Part 11 β Amortized posterior 11.A β Simulation-based inference framing 11.B β Regression head 11.C β Conditional-flow head (stub β pending gauss_flows) 11.D β Score-diffusion head (stub β pending diffrax reverse-SDE) Part 12 β Adjoints deep dive 12.A β What is an adjoint? 12.B β diffrax adjoint variants 12.C β optimistix adjoint variants 12.D β Writing your own AbstractAdjoint Part 13 β Posterior uncertainty 13.A β Laplace at MAP 13.B β Gauss-Newton Hessian 13.C β Ensemble covariances 13.D β GaussianMarkLikelihood serialisation Part 14 β Validation gates (six-step cycle) 14.A β Six-step cycle motivation (D12) 14.B β assert_posterior_agreement 14.C β assert_adjoint_calibrated 14.D β simulation_based_calibration (Talts et al.) Part 15 β Orchestration (pipekit composition) 15.A β VarDACycle for sequential DA 15.B β VarSmootherCycle for retrospective windows 15.C β obs_source operators 15.D β Composing with pipekit.Sequential Part 16 β Training at scale (pipekit-train) 16.A β train_step / amortized_train_step primitives 16.B β pipekit_train.Loss adapter 16.C β TrainingLoop integration 16.D β Checkpoints & sweeps Part 17 β Performance 17.A β jit basics 17.B β eqx.filter_vmap batching 17.C β Memory profiling adjoint variants 17.D β When to unroll vs scan Part 18 β Debugging 18.A β Cost decomposition (decomposed_loss) 18.B β Inspecting residuals 18.C β Common failure modes Part 19 β Extending vardax 19.A β Writing your own AnalysisStep 19.B β Protocol-conformance tests 19.C β Publishing as a plugin Part 20 β Applied (cross-link to applied projects) 20.A β Lorenz benchmarks (β projects/assimilation/) 20.B β SSH satellite interpolation 20.C β Methane single-overpass retrieval 20.D β Multi-instrument atmospheric fusion Part 0 β Foundations ΒΆ 0.A β The Bayesian update ΒΆ Key equations / models:
Prior, likelihood, posterior: p ( x β£ y ) β p ( y β£ x ) β p ( x ) p(x \mid y) \propto p(y \mid x)\,p(x) p ( x β£ y ) β p ( y β£ x ) p ( x ) Gaussian-Gaussian closure: p ( x ) = N ( x b , B ) p(x) = \mathcal{N}(x_b, B) p ( x ) = N ( x b β , B ) , p ( y β£ x ) = N ( H x , R ) p(y \mid x) = \mathcal{N}(Hx, R) p ( y β£ x ) = N ( H x , R ) Posterior in information form: Ξ a = B β 1 + H β€ R β 1 H \Lambda^a = B^{-1} + H^\top R^{-1} H Ξ a = B β 1 + H β€ R β 1 H , Ξ· a = B β 1 x b + H β€ R β 1 y \eta^a = B^{-1} x_b + H^\top R^{-1} y Ξ· a = B β 1 x b β + H β€ R β 1 y # Tutorial Source Scope Refs / Notes 0.1 The DA problem from scratch β prior + likelihood β posterior β π§± π math:01_problem_setting; graphical-model diagram; pairs with filterax 0.1 / GP 0.6 0.2 The Gaussian-Gaussian closure β covariance form vs information form β π§± π math:04_oi_blue Β§1; cross-listed with filterax 0.9
Key equations / models:
Kalman gain: K = B H β€ ( H B H β€ + R ) β 1 K = B H^\top (H B H^\top + R)^{-1} K = B H β€ ( H B H β€ + R ) β 1 Update: x a = x b + K ( y β H x b ) x^a = x_b + K(y - H x_b) x a = x b β + K ( y β H x b β ) Posterior cov: P a = ( I β K H ) B P^a = (I - K H) B P a = ( I β KH ) B (or Joseph form) # Tutorial Source Scope Refs / Notes 0.3 BLUE from scratch β the Kalman update derivation β π§± π math:04_oi_blue; pairs with filterax 0.3; covariance-ellipse diagram
0.C β Variational reformulation (cost β posterior) ΒΆ Key equations / models:
3DVar cost: J ( x ) = 1 2 β₯ x β x b β₯ B β 1 2 + 1 2 β₯ y β H x β₯ R β 1 2 J(x) = \tfrac{1}{2}\|x - x_b\|^2_{B^{-1}} + \tfrac{1}{2}\|y - H x\|^2_{R^{-1}} J ( x ) = 2 1 β β₯ x β x b β β₯ B β 1 2 β + 2 1 β β₯ y β H x β₯ R β 1 2 β Argmin β posterior mean equivalence (linear-Gaussian) Why we minimise: nonlinear H H H , structured B B B , large state dim # Tutorial Source Scope Refs / Notes 0.4 The variational reformulation β argmin = posterior mean in the LG case β π§± math:05_threedvar Β§1; show 3DVar reduces to BLUE on linear H
0.D β pipekit-cycle protocols (the vardax shape) ΒΆ Key equations / models:
ForwardModel: step(state, dt) β state, dt propertyObservationOperator: __call__(state, mask=...) β obs, linearize(x)AnalysisStep: __call__(forecast, obs, *, obs_op, obs_err_cov) β analysis# Tutorial Source Scope Refs / Notes 0.5 The pipekit-cycle protocol family β ForwardModel / ObservationOperator / AnalysisStep β π§± dd:pipekit_composition.md; api:vardax.protocols; class-diagram with conformance examples
0.E β Your first assimilation ΒΆ # Tutorial Source Scope Refs / Notes 0.6 Five-line BLUE on a 1-D toy β vdx.OptimalInterpolation end-to-end β π§± api:OptimalInterpolation; minimal Batch1D; bridge to Part 5
Part 1 β Observation operators ΒΆ Every method in vardax accepts an ObservationOperator. This part walks through the shipped catalogue and the protocol.
1.A β MaskedIdentity and the symmetric-masking invariant ΒΆ Key equations / models:
H ( x ) = m β x H(x) = m \odot x H ( x ) = m β x , l i n e a r i z e ( x ) = d i a g ( m ) \mathrm{linearize}(x) = \mathrm{diag}(m) linearize ( x ) = diag ( m ) Symmetric masking: r = m β ( y β H ( x ) ) r = m \odot (y - H(x)) r = m β ( y β H ( x )) β both sides masked Why naive m \odot y - H(x) biases the analysis (PR #41 review story) # Tutorial Source Scope Refs / Notes 1.1 MaskedIdentity β the dense-but-sparse-observed primitiveβ π§± api:MaskedIdentity; math:11_observation_operators Β§2; symmetric-masking gotcha
1.B β LinearObs with explicit H ΒΆ Key equations / models:
H β R N y Γ N x H \in \mathbb{R}^{N_y \times N_x} H β R N y β Γ N x β as a lineax.AbstractLinearOperatorStructured H via gaussx operators (Toeplitz, block-diagonal) # Tutorial Source Scope Refs / Notes 1.2 LinearObs β explicit H, structured H, computational dispatchβ π§± π api:LinearObs; cross-listed with filterax 1.5 (structured R)
Key equations / models:
H ( x ) = A ( h β x + ( 1 β h ) x a ) H(x) = A(h \odot x + (1 - h) x_a) H ( x ) = A ( h β x + ( 1 β h ) x a β ) Smoothing-kernel + a-priori interpretation (Rodgers 2000) Why l i n e a r i z e \mathrm{linearize} linearize gives a structured Jacobian # Tutorial Source Scope Refs / Notes 1.3 AveragingKernel β satellite retrievals, A A A + prior contributionβ π§± api:AveragingKernel; math:02_observation_model Β§3; adjoint sanity-check pattern
1.D β MultiInstrumentFusion and heterogeneous obs ΒΆ Key equations / models:
Per-instrument H i H_i H i β , R i R_i R i β ; output = dict[str, Array] InstrumentRegistry / InstrumentSpec plumbing# Tutorial Source Scope Refs / Notes 1.4 MultiInstrumentFusion β combining heterogeneous instrumentsβ π api:MultiInstrumentFusion, InstrumentRegistry, InstrumentSpec; design D9
1.E β Writing a custom ObservationOperator ΒΆ # Tutorial Source Scope Refs / Notes 1.5 Writing a custom obs op β protocol conformance + adjoint test β π§± dd:pipekit_composition.md Β§ObservationOperator; reuses tests/test_pipekit_protocols.py pattern
Part 2 β Forward models ΒΆ 2.A β The pipekit_cycle.ForwardModel protocol ΒΆ Key equations / models:
step(state, dt) β state β one integration stepstate_signature β JAX shape/dtype declarationOne-step + jax.lax.scan for rollouts # Tutorial Source Scope Refs / Notes 2.1 ForwardModel protocol β what makes a forward and how vardax uses itβ π§± dd:pipekit_composition.md Β§ForwardModel; identity / linear / nonlinear examples
2.B β Lorenz family wrappers (L63, L96, L96-2L) ΒΆ # Tutorial Source Scope Refs / Notes 2.2 Lorenz wrappers β RK4 + ForwardModel interface R π§± source: projects/assimilation/src/assimilation/{lorenz63,lorenz96,lorenz96_2l}.py; one-paragraph derivation per system
2.C β Shallow water (somax) ΒΆ Key equations / models:
β t h + β β
( h v ) = 0 \partial_t h + \nabla \cdot (hv) = 0 β t β h + β β
( h v ) = 0 , β t v + v β
β v + g β h = β f k Γ v + Ξ½ Ξ v \partial_t v + v \cdot \nabla v + g \nabla h = -fk \times v + \nu \Delta v β t β v + v β
β v + g β h = β f k Γ v + Ξ½ Ξ v Arakawa C-grid via finitevolx # Tutorial Source Scope Refs / Notes 2.3 Shallow water on a sphere β somax.ShallowWaterModel as a ForwardModel β π external: somax; pair with strong-4DVar in Part 7
2.D β Quasi-geostrophic (somax) ΒΆ Key equations / models:
QG potential vorticity: q = β 2 Ο + Ξ² y β F Ο q = \nabla^2 \psi + \beta y - F\psi q = β 2 Ο + Ξ² y β F Ο Layered QG for ocean / atmosphere # Tutorial Source Scope Refs / Notes 2.4 Quasi-geostrophic β classic oceanographic DA testbed β π external: somax; pair with IncrementalFourDVar in Part 9
2.E β Plume models (plumax) ΒΆ Key equations / models:
Gaussian plume: C ( x , y , z ) = Q 2 Ο u Ο y Ο z exp β‘ ( β¦ ) C(x, y, z) = \frac{Q}{2\pi u \sigma_y \sigma_z} \exp(\ldots) C ( x , y , z ) = 2 Ο u Ο y β Ο z β Q β exp ( β¦ ) Gaussian puff (time-resolved): superposed instantaneous releases # Tutorial Source Scope Refs / Notes 2.5 Gaussian-puff atmospheric dispersion as a ForwardModel β π external: plumax; pair with AmortizedPosterior in Part 11 (methane single-overpass)
2.F β Writing your own forward ΒΆ # Tutorial Source Scope Refs / Notes 2.6 Writing a custom ForwardModel β 1-D advection-diffusion worked example β π§± dd:pipekit_composition.md Β§ForwardModel; diffrax integration recipes
Part 3 β Static priors & covariances ΒΆ 3.A β Diagonal B (the simplest case) ΒΆ Key equations / models:
B = Ο b 2 I B = \sigma_b^2 I B = Ο b 2 β I The PSD-tag requirement for lineax.CG consumers Why lx.DiagonalLinearOperator must be wrapped in TaggedLinearOperator # Tutorial Source Scope Refs / Notes 3.1 Diagonal B β the simplest case, with the tagged-operator gotcha β π§± math:01_problem_setting Β§3; api:lx.DiagonalLinearOperator; positive_semidefinite_tag
3.B β Structured priors via gaussx (MatΓ©rn, Kronecker) ΒΆ Key equations / models:
MatΓ©rn-Ξ½ covariance with length-scale β \ell β Kronecker structure for space Γ time Half-operator B \sqrt{B} B β for control-variable transform # Tutorial Source Scope Refs / Notes 3.2 Structured B via gaussx β MatΓ©rn, Kronecker, B \sqrt{B} B β G π§± π external: gaussx; cross-listed with GP 1.B / filterax 1.5
3.C β Dynamical priors (forward-as-Ο) ΒΆ Key equations / models:
Ο ( x ) = M ( x ) \varphi(x) = M(x) Ο ( x ) = M ( x ) β N applications of the forwardDynamicalPrior(forward, n_steps, forward_adjoint)# Tutorial Source Scope Refs / Notes 3.3 Dynamical priors β forward as Ο, gradient flow choice β π api:DynamicalPrior; dd:pipekit_composition.md; bridge to Part 10
Part 4 β Encoders & decoders (latent-space DA) ΒΆ The βlatent-spaceβ angle on vardax β autoencoder priors as a regulariser, latent-space assimilation, and observation encoders for the amortized head.
4.A β AE priors overview (BilinAE, ConvAE, MLP) ΒΆ Key equations / models:
Ο ΞΈ ( x ) = D ΞΈ ( E ΞΈ ( x ) ) \varphi_\theta(x) = D_\theta(E_\theta(x)) Ο ΞΈ β ( x ) = D ΞΈ β ( E ΞΈ β ( x )) β encode-then-decodeBottleneck dim βͺ N x \ll N_x βͺ N x β enforces a manifold prior Bilinear, conv, MLP architectures shipped in vardax.priors # Tutorial Source Scope Refs / Notes 4.1 AE prior architectures β BilinAEPrior, ConvAEPrior, MLPAEPrior β π§± π api:BilinAEPrior1D, ConvAEPrior1D, MLPAEPrior1D, BilinAEPrior2D, BilinAEPrior2DMultivar; cross-listed with GP 6.A (deep kernels)
4.B β Pretraining an AE prior ΒΆ Key equations / models:
Reconstruction loss: L = E x β₯ x β Ο ΞΈ ( x ) β₯ 2 \mathcal{L} = \mathbb{E}_x\|x - \varphi_\theta(x)\|^2 L = E x β β₯ x β Ο ΞΈ β ( x ) β₯ 2 Simulation-based pretraining via vmapβd generate_problem # Tutorial Source Scope Refs / Notes 4.2 Pretraining an AE prior on simulated trajectories β π§± api:train_step; pre-training schedule for L96
4.C β Latent-space DA (assimilate in z, decode to x) ΒΆ Key equations / models:
Latent posterior: q ( z β£ y ) β p ( y β£ D ( z ) ) β p ( z ) q(z \mid y) \propto p(y \mid D(z))\,p(z) q ( z β£ y ) β p ( y β£ D ( z )) p ( z ) Decode-then-observe: H β D H \circ D H β D as the effective obs op Why this conditions the problem (lower-dim z = better-posed) # Tutorial Source Scope Refs / Notes 4.3 Latent-space DA β assimilate in z z z , decode to x x x β π¬ π math:09_4dvarnet Β§4; cross-listed with GP latent-variable models; ill-conditioning recipe
4.D β Observation encoders for amortized inference ΒΆ Key equations / models:
Context encoder c Ο ( y , m ) c_\psi(y, m) c Ο β ( y , m ) for AmortizedPosterior Different role from prior encoder: maps obs not state IdentityObsEncoder vs MLPObsEncoder# Tutorial Source Scope Refs / Notes 4.4 Observation encoders for AmortizedPosterior β π§± api:IdentityObsEncoder, MLPObsEncoder; bridge to Part 11
Part 5 β Optimal Interpolation (BLUE) ΒΆ # Tutorial Source Scope Refs / Notes 5.1 BLUE β closed-form Kalman update derivation, ported from math:04_oi_blue β π§± π math:04_oi_blue; cross-listed with filterax 0.3
5.B β OptimalInterpolation API walkthrough ΒΆ # Tutorial Source Scope Refs / Notes 5.2 OptimalInterpolation API β lineax.CG inner solve, mask_aware dispatchR π§± api:OptimalInterpolation; source: projects/assimilation/notebooks/01_optimal_interpolation.ipynb
5.C β OI with structured B ΒΆ # Tutorial Source Scope Refs / Notes 5.3 OI with a MatΓ©rn B β observed β unobserved coupling via prior cross-cov β π¬ π api:OptimalInterpolation; uses gaussx-backed B; cross-listed with GP 1.B
Part 6 β 3DVar ΒΆ 6.A β The 3DVar cost ΒΆ # Tutorial Source Scope Refs / Notes 6.1 The 3DVar cost β derivation + β BLUE equivalence (Decision D14) β π§± math:05_threedvar; D14 invariant verified empirically
6.B β ThreeDVar API + minimiser choice ΒΆ # Tutorial Source Scope Refs / Notes 6.2 ThreeDVar β choosing the minimiser (BFGS / NonlinearCG / GaussNewton)R π§± api:ThreeDVar; optimistix.AbstractMinimiser choice; source: projects/assimilation/notebooks/02_threedvar.ipynb
6.C β Nonlinear H with 3DVar ΒΆ # Tutorial Source Scope Refs / Notes 6.3 3DVar with AveragingKernel β when iterative pays off β π api:ThreeDVar, AveragingKernel; satellite-retrieval example
Part 7 β Strong-constraint 4DVar ΒΆ 7.A β The 4DVar cost (adjoint of M) ΒΆ # Tutorial Source Scope Refs / Notes 7.1 The 4DVar cost β control = x 0 x_0 x 0 β , perfect-model assumption β π§± π math:06_strong_4dvar; cross-listed with filterax 0.8 (4D-Var contrast)
7.B β StrongFourDVar API ΒΆ # Tutorial Source Scope Refs / Notes 7.2 StrongFourDVar end-to-end β Lorenz-63 long-window forecastR π§± api:StrongFourDVar; source: projects/assimilation/notebooks/03_strong_4dvar.ipynb
7.C β forward_adjoint choices (diffrax variants) ΒΆ # Tutorial Source Scope Refs / Notes 7.3 forward_adjoint β RecursiveCheckpointAdjoint vs BacksolveAdjoint vs ForwardModeβ π§± dd:decisions.md (D15); memory / time table; sets up Part 12
7.D β Lorenz demo (deep dive, links to assimilation/) ΒΆ # Tutorial Source Scope Refs / Notes 7.4 L96 strong-4DVar β partial obs, what dynamics buy you R π§± source: projects/assimilation/notebooks/10_lorenz96_benchmark.ipynb
Part 8 β Weak-constraint 4DVar ΒΆ 8.A β Model-error term ΒΆ Key equations / models:
x t = M ( x t β 1 ) + Ξ· t x_t = M(x_{t-1}) + \eta_t x t β = M ( x t β 1 β ) + Ξ· t β , Ξ· t βΌ N ( 0 , Q ) \eta_t \sim \mathcal{N}(0, Q) Ξ· t β βΌ N ( 0 , Q ) Augmented control ( x 0 , Ξ· 1 , β¦ , Ξ· T ) (x_0, \eta_1, \ldots, \eta_T) ( x 0 β , Ξ· 1 β , β¦ , Ξ· T β ) in R N + T N \mathbb{R}^{N + TN} R N + TN # Tutorial Source Scope Refs / Notes 8.1 Weak-4DVar cost β the model-error term, Q Q Q vs B B B vs R R R β π§± math:07_weak_4dvar
8.B β WeakFourDVar API ΒΆ # Tutorial Source Scope Refs / Notes 8.2 WeakFourDVar β running it; convergence pitfalls on long windowsR π§± api:WeakFourDVar; source: projects/assimilation/notebooks/04_weak_4dvar.ipynb
8.C β Imbalance failure modes ΒΆ # Tutorial Source Scope Refs / Notes 8.3 Imbalance failure modes β when augmented control diverges β π¬ known L63 long-window failure (PR #73 discussion); when to lower Q Q Q
Part 9 β Incremental 4DVar ΒΆ 9.A β GN outer + CG inner ΒΆ Key equations / models:
Linearise M M M , H H H at x b ( k ) x_b^{(k)} x b ( k ) β GN Hessian: J G N β² β² = B β 1 + β t ( H t β² M t β² ) β€ R β 1 ( H t β² M t β² ) J''_{GN} = B^{-1} + \sum_t (H'_t M'_t)^\top R^{-1} (H'_t M'_t) J GN β²β² β = B β 1 + β t β ( H t β² β M t β² β ) β€ R β 1 ( H t β² β M t β² β ) Solve J G N β² β² β Ξ΄ x β = β β J J''_{GN}\,\delta x^* = -\nabla J J GN β²β² β Ξ΄ x β = β β J by lineax.CG # Tutorial Source Scope Refs / Notes 9.1 Incremental idea β GN outer + CG inner, why the linearised quadratic β π§± π math:08_incremental_4dvar; cross-listed with filterax 5.3 (GNKI)
9.B β IncrementalFourDVar API ΒΆ # Tutorial Source Scope Refs / Notes 9.2 IncrementalFourDVar β tuning (n_outer, n_inner, cg_tol)R π§± api:IncrementalFourDVar, IncrementalConfig; source: projects/assimilation/notebooks/05_incremental_4dvar.ipynb
# Tutorial Source Scope Refs / Notes 9.3 CVT preconditioning β Ο = B β 1 / 2 Ξ΄ x \chi = B^{-1/2}\delta x Ο = B β 1/2 Ξ΄ x via gaussx.sqrt(B) β π¬ π math:08_incremental_4dvar Β§4; cross-listed with GP 1.B (root decompositions)
Part 10 β FourDVarNet (learned solvers) ΒΆ 10.A β Unrolled iteration math ΒΆ Key equations / models:
x ( k + 1 ) = x ( k ) β Ξ± β Ξ¦ Ο ( β J ( x ( k ) ) , x ( k ) , h ( k ) ) x^{(k+1)} = x^{(k)} - \alpha\,\Phi_\phi(\nabla J(x^{(k)}), x^{(k)}, h^{(k)}) x ( k + 1 ) = x ( k ) β Ξ± Ξ¦ Ο β ( β J ( x ( k ) ) , x ( k ) , h ( k ) ) Learned ConvLSTM modulator Ξ¦ Ο \Phi_\phi Ξ¦ Ο β Learned prior Ο ΞΈ \varphi_\theta Ο ΞΈ β inside J J J # Tutorial Source Scope Refs / Notes 10.1 Unrolled-iteration math β learned solver as a K K K -step net β π§± π math:09_4dvarnet; bridges to filterax Part 8 (differentiable DA)
10.B β FourDVarNet1D / FourDVarNet2D API ΒΆ # Tutorial Source Scope Refs / Notes 10.2 FourDVarNet1D / FourDVarNet2D walkthroughR π§± api:FourDVarNet1D, FourDVarNet2D; source: projects/assimilation/notebooks/06_fourdvarnet.ipynb
10.C β Training loop (train_step composition) ΒΆ # Tutorial Source Scope Refs / Notes 10.3 Training a FourDVarNet β simulation-based + reconstruction loss β π§± api:train_step, reconstruction_loss; bridge to Part 16
10.D β solver_adjoint dispatch (D15) ΒΆ # Tutorial Source Scope Refs / Notes 10.4 solver_adjoint dispatch β RecursiveCheckpoint vs OneStep vs Implicitβ π¬ dd:decisions.md (D15); api:OneStepAdjoint; bridge to Part 12
Part 11 β Amortized posterior ΒΆ 11.A β Simulation-based inference framing ΒΆ # Tutorial Source Scope Refs / Notes 11.1 SBI framing β when amortization wins β π§± π math:10_amortized_inference Β§1; cross-listed with filterax 10.E (amortised inference)
11.B β Regression head ΒΆ # Tutorial Source Scope Refs / Notes 11.2 RegressionHead β diagonal-Gaussian head, training via NLL R π§± api:AmortizedPosterior, RegressionHead, amortized_train_step; source: projects/assimilation/notebooks/07_amortized_posterior.ipynb
11.C β Conditional-flow head (stub β pending gauss_flows) ΒΆ # Tutorial Source Scope Refs / Notes 11.3 ConditionalFlowHead β exact density via change-of-variables (stub) β π¬ π api:ConditionalFlowHead; cross-listed with GP normalising-flow tutorials; documents NotImplementedError until gauss_flows lands
11.D β Score-diffusion head (stub β pending diffrax reverse-SDE) ΒΆ # Tutorial Source Scope Refs / Notes 11.4 ScoreDiffusionHead β sampling via reverse SDE (stub) β π¬ api:ScoreDiffusionHead; documents NotImplementedError until diffrax reverse-SDE lands
Part 12 β Adjoints deep dive ΒΆ 12.A β What is an adjoint? ΒΆ # Tutorial Source Scope Refs / Notes 12.1 What is an adjoint? β VJP vs hand-coded adjoint model β π§± π math:12_adjoint_methods; cross-listed with filterax Part 8
12.B β diffrax adjoint variants ΒΆ # Tutorial Source Scope Refs / Notes 12.2 diffrax.RecursiveCheckpointAdjoint vs BacksolveAdjoint vs ForwardModeβ π§± dd:decisions.md (D15); api:RecursiveCheckpointAdjoint; memory / time table on Lorenz windows
12.C β optimistix adjoint variants ΒΆ # Tutorial Source Scope Refs / Notes 12.3 optimistix.ImplicitAdjoint vs RecursiveCheckpointAdjoint for the inner solverβ π§± api:ImplicitAdjoint, OneStepAdjoint; when implicit applies (fixed-point)
12.D β Writing your own AbstractAdjoint ΒΆ # Tutorial Source Scope Refs / Notes 12.4 Writing your own optx.AbstractAdjoint β OneStepAdjoint as the template β π¬ api:OneStepAdjoint (Bolte 2023); upstream-contribution arc
Part 13 β Posterior uncertainty ΒΆ 13.A β Laplace at MAP ΒΆ Key equations / models:
P β β ( ( H β² ) β€ R β 1 H β² + B β 1 ) β 1 P^* \approx \bigl((H')^\top R^{-1} H' + B^{-1}\bigr)^{-1} P β β ( ( H β² ) β€ R β 1 H β² + B β 1 ) β 1 Returned as lineax.AbstractLinearOperator (lazy CG-backed inverse) # Tutorial Source Scope Refs / Notes 13.1 LaplaceCovariance β Gauss-Newton Hessian at MAP, lazy inverseβ π§± π math:13_posterior_covariance Β§2; api:LaplaceCovariance; cross-listed with GP 0.C (variational Laplace)
13.B β Gauss-Newton Hessian ΒΆ # Tutorial Source Scope Refs / Notes 13.2 GaussNewtonHessian β reuse the incremental Hessian as posterior covβ π¬ api:GaussNewtonHessian; ties to Part 9
13.C β Ensemble covariances ΒΆ # Tutorial Source Scope Refs / Notes 13.3 EnsembleCovariance β sample covariance from M analysesβ π π api:EnsembleCovariance; cross-listed with filterax Part 1 (ensemble stats)
13.D β GaussianMarkLikelihood serialisation ΒΆ # Tutorial Source Scope Refs / Notes 13.4 GaussianMarkLikelihood β Posterior β dict for downstream population modelsβ π api:GaussianMarkLikelihood; dd:posterior.md
Part 14 β Validation gates (six-step cycle) ΒΆ 14.A β Six-step cycle motivation (D12) ΒΆ # Tutorial Source Scope Refs / Notes 14.1 The six-step cycle β why amortized heads need calibration gates β π§± π math:14_six_step_cycle; dd:decisions.md (D12); cross-listed with filterax Part 7
14.B β assert_posterior_agreement ΒΆ # Tutorial Source Scope Refs / Notes 14.2 assert_posterior_agreement β marginal z-score check against an oracleβ π§± api:assert_posterior_agreement; pair amortized with strong-4DVar oracle
14.C β assert_adjoint_calibrated ΒΆ # Tutorial Source Scope Refs / Notes 14.3 assert_adjoint_calibrated β random-vector JVP probe of β x β / β y \partial x^* / \partial y β x β / β y β π¬ api:assert_adjoint_calibrated; Hutchinson-style
14.D β simulation_based_calibration (Talts et al.) ΒΆ # Tutorial Source Scope Refs / Notes 14.4 simulation_based_calibration β rank histograms (Talts 2018)β π§± π api:simulation_based_calibration; cross-listed with GP / SVI calibration tutorials
Part 15 β Orchestration (pipekit composition) ΒΆ 15.A β VarDACycle for sequential DA ΒΆ # Tutorial Source Scope Refs / Notes 15.1 VarDACycle β chaining many forecast β analyse windowsβ π§± π api:VarDACycle; dd:pipekit_composition.md; cross-listed with filterax Part 3
15.B β VarSmootherCycle for retrospective windows ΒΆ # Tutorial Source Scope Refs / Notes 15.2 VarSmootherCycle β windowed retrospective analysisβ π¬ π api:VarSmootherCycle; cross-listed with filterax Part 4 (smoothers)
15.C β obs_source operators ΒΆ # Tutorial Source Scope Refs / Notes 15.3 obs_source operators β loading obs per cycle from a stream / catalogueβ π§± dd:pipekit_composition.md; xarray / georeader recipes
15.D β Composing with pipekit.Sequential ΒΆ # Tutorial Source Scope Refs / Notes 15.4 Composing vardax in a pipekit.Sequential pipeline β π dd:pipekit_composition.md Β§5; pk.Lambda wrap; JaxModelOp (when shipped)
Part 16 β Training at scale (pipekit-train) ΒΆ 16.A β train_step / amortized_train_step primitives ΒΆ # Tutorial Source Scope Refs / Notes 16.1 The train_step primitive β eqx.filter_value_and_grad + optax β π§± api:train_step, amortized_train_step; dd:decisions.md (D5)
16.B β pipekit_train.Loss adapter ΒΆ # Tutorial Source Scope Refs / Notes 16.2 pipekit_train.Loss adapter β VardaxReconLoss over train_stepβ π§± api:vardax.adapters.pipekit_train.VardaxReconLoss
16.C β TrainingLoop integration ΒΆ # Tutorial Source Scope Refs / Notes 16.3 pipekit_train.TrainingLoop end-to-end for FourDVarNetβ π external: pipekit_train; checkpointing + early stopping
16.D β Checkpoints & sweeps ΒΆ # Tutorial Source Scope Refs / Notes 16.4 pipekit_train.HyperSweep for FourDVarNet hyperparametersβ π¬ external: pipekit_train.HyperSweep; grid over (n_solver_steps, hidden_dim)
17.A β jit basics ΒΆ # Tutorial Source Scope Refs / Notes 17.1 eqx.filter_jit β what gets traced, what stays staticβ π§± Batch1D shape stability; static=True field pitfalls
17.B β eqx.filter_vmap batching ΒΆ # Tutorial Source Scope Refs / Notes 17.2 eqx.filter_vmap over batches and over methodsβ π§± source: assimilation/benchmark.py patterns
17.C β Memory profiling adjoint variants ΒΆ # Tutorial Source Scope Refs / Notes 17.3 Memory profiling β adjoint variant comparison on long L96 windows β π¬ jax.profiler; ties to Part 12
17.D β When to unroll vs scan ΒΆ # Tutorial Source Scope Refs / Notes 17.4 Unroll vs jax.lax.scan β when each pays off β π rollout pattern; FourDVarNet n_solver_steps choice
Part 18 β Debugging ΒΆ 18.A β Cost decomposition (decomposed_loss) ΒΆ # Tutorial Source Scope Refs / Notes 18.1 decomposed_loss β splitting prior / obs cost for inspectionβ π§± api:decomposed_loss, obs_cost_1d, prior_cost; sanity-check recipes
18.B β Inspecting residuals ΒΆ # Tutorial Source Scope Refs / Notes 18.2 Residual diagnostics β what a healthy assim window looks like β π§± innovation y β H ( x β ) y - H(x^*) y β H ( x β ) , masked-vs-unmasked stats
18.C β Common failure modes ΒΆ # Tutorial Source Scope Refs / Notes 18.3 Common failure modes β Weak div, GN NaN, untagged operators, etc. β π lineax.CG tag requirement; PRs #41 #42 #73 lessons distilled
Part 19 β Extending vardax ΒΆ 19.A β Writing your own AnalysisStep ΒΆ # Tutorial Source Scope Refs / Notes 19.1 Writing your own AnalysisStep β protocol conformance + .as_analysis_step() β π§± dd:pipekit_composition.md Β§AnalysisStep; eqx.Module template
# Tutorial Source Scope Refs / Notes 19.2 Protocol-conformance tests β tests/test_pipekit_protocols.py template V π§± source: vardax/tests/test_pipekit_protocols.py; isinstance-check pattern
19.C β Publishing as a plugin ΒΆ # Tutorial Source Scope Refs / Notes 19.3 Publishing your method as a vardax-compatible plugin β π¬ packaging recipe; entry-points pattern
Part 20 β Applied (cross-link) ΒΆ 20.A β Lorenz benchmarks (β projects/assimilation/) ΒΆ # Tutorial Source Scope Refs / Notes 20.1 Lorenz-63, Lorenz-96 (1L + 2L) benchmarks R π§± source: projects/assimilation/notebooks/; analysis-then-forecast view across all seven methods
20.B β SSH satellite interpolation ΒΆ # Tutorial Source Scope Refs / Notes 20.2 SSH satellite interpolation β FourDVarNet2D on OceanBench-style data β π math:16_ssh_example; bridges to oceanography use case
20.C β Methane single-overpass retrieval ΒΆ # Tutorial Source Scope Refs / Notes 20.3 Methane single-overpass β AveragingKernel + plumax Gaussian puff β π math:17_methane_example; pair with Part 11 amortized head
20.D β Multi-instrument atmospheric fusion ΒΆ # Tutorial Source Scope Refs / Notes 20.4 Multi-instrument atmospheric fusion β TROPOMI + EMI T + GHGSat β π¬ api:MultiInstrumentFusion; design D9; ties to Part 1.D
Status snapshot ΒΆ This is a curriculum scaffold. Each rowβs Source column reflects what already exists:
R rows are notebooks that already live in projects/assimilation/notebooks/ (the L63 / L96 / L96-2L tutorials shipped with the assimilation project).V / G / K rows are notebooks that exist upstream in the vardax / gaussx / pipekit repos (none at the time of writing β every such row currently reads β, but the legend documents what those tags mean when upstream notebooks land).β rows are gaps to be filled by follow-up PRs.Follow-up PRs will populate projects/assimilation/notebooks/vardax/<section>/<name>.ipynb (a new vardax/ subdirectory under the existing notebooks tree, alongside 00_lorenz63_setup.md and friends) and flip the Source column from β to R. Pure-prose chapters that port math may land as .md instead of .ipynb.
v1 priority (~6 sessions, ~35 notebooks): Parts 0β6 + 13 + 14 + 16 + the L63 entries that already exist in projects/assimilation/. Foundations + components + half the seven methods + posterior + validation + training.
v2 priority : Parts 7β12 dynamics + adjoints depth; Parts 15 cycling demo; Part 17 performance; Part 19 extension; Part 20 applied demos.
v3 priority : stub heads (11.C, 11.D) flipped to real when gauss_flows / diffrax reverse-SDE land; Part 9.C CVT depending on gaussx.sqrt; somax / plumax forwards (2.C / 2.D / 2.E).