Cycle Integration¶
Sequential assimilation — forecast, observe, analyse, repeat — is
orchestrated by pipekit-cycle, not
reimplemented here. The two factories on this page are thin wrappers that
assemble a pipekit_cycle.DACycle (filtering) or
pipekit_cycle.SmootherCycle (fixed-lag smoothing) from vardax parts: any
model's .as_analysis_step(), any
observation operator, and a forward model satisfying
the ForwardModel Protocol.
Because the coupling is purely structural (runtime-checkable Protocols, no
inheritance), the same cycle accepts every vardax method interchangeably —
swapping 3DVar for
strong-constraint 4DVar inside a cycle is a
one-argument change. The full forecast/analysis loop is worked through in
Six-Step Inference Cycle. Both factories are also
accessible via the vardax.cycle submodule namespace.
Factories¶
vardax — Modular variational data assimilation with learned components.
All public symbols are re-exported from the private _src subpackage so
that user code imports from the top-level namespace:
VarDACycle
¶
VarDACycle(
forward: Any,
obs_op: Any,
model: Any,
*,
obs_source: Any | None = None,
n_steps: int = 1,
save_history: bool = True,
) -> DACycle
Build a pipekit_cycle.DACycle from a vardax model.
Pulls model.as_analysis_step() and hands it to pipekit-cycle.
The same orchestration code works for any of the seven Layer 2
classes — OptimalInterpolation, ThreeDVar, StrongFourDVar,
WeakFourDVar, IncrementalFourDVar, FourDVarNet,
AmortizedPosterior. Each call alternates forecast and analysis,
Algorithm
- Check that
modelexposesas_analysis_step. - Take the analysis step from the model.
- Return a
DACyclethat forecasts withforwardand analyses with that step,n_stepstimes per call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
forward
|
Any
|
Forward model satisfying |
required |
obs_op
|
Any
|
Observation operator satisfying
|
required |
model
|
Any
|
Vardax Layer 2 model exposing |
required |
obs_source
|
Any | None
|
Optional |
None
|
n_steps
|
int
|
Number of forecast-analysis cycles per call. |
1
|
save_history
|
bool
|
Append |
True
|
Returns:
| Type | Description |
|---|---|
DACycle
|
Configured |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If |
Examples:
>>> import equinox as eqx
>>> import jax, jax.numpy as jnp, lineax as lx
>>> import vardax as vdx
>>> class IdentityForward(eqx.Module):
... dt: float = 1.0
... state_signature: None = None
...
... def step(self, state, dt):
... return state
>>> eye = lx.IdentityLinearOperator(jax.ShapeDtypeStruct((1, 4), jnp.float32))
>>> oi = vdx.OptimalInterpolation(
... obs_op=vdx.LinearObs(operator=eye),
... prior_mean=jnp.zeros((1, 4)),
... prior_cov_op=eye,
... obs_cov_op=eye,
... )
>>> cycle = vdx.VarDACycle(
... forward=IdentityForward(),
... obs_op=vdx.MaskedIdentity(),
... model=oi,
... n_steps=1,
... )
>>> type(cycle).__name__
'DACycle'
With no obs_source the analysis is skipped and the forecast
propagates; the factory records its settings.
A model without as_analysis_step is rejected.
>>> vdx.VarDACycle(
... forward=IdentityForward(), obs_op=vdx.MaskedIdentity(), model=object()
... )
Traceback (most recent call last):
...
AttributeError: VarDACycle requires a model exposing `.as_analysis_step()`
Source code in src/vardax/_src/cycle/da_cycle.py
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | |
VarSmootherCycle
¶
VarSmootherCycle(
forward: Any,
obs_op: Any,
model: Any,
*,
window: int,
stride: int = 1,
obs_source: Any | None = None,
) -> SmootherCycle
Build a pipekit_cycle.SmootherCycle from a vardax model.
Retrospective windowed smoothing: each call processes stride
consecutive window-step windows back to back, analysing each one
once all of its observations are in.
Algorithm
- Check that
modelexposesas_analysis_step. - Take the analysis step from the model.
- Return a
SmootherCyclethat, per window ofwindowforecast steps, analyses once all observations are in.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
forward
|
Any
|
Forward model. |
required |
obs_op
|
Any
|
Observation operator. |
required |
model
|
Any
|
Vardax Layer 2 model exposing |
required |
window
|
int
|
Number of forecast steps per smoother window. |
required |
stride
|
int
|
Number of consecutive windows processed per call (the
windows are adjacent, not overlapping; this mirrors
|
1
|
obs_source
|
Any | None
|
Optional observation loader. |
None
|
Returns:
| Type | Description |
|---|---|
SmootherCycle
|
Configured |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If |
Examples:
>>> import equinox as eqx
>>> import jax, jax.numpy as jnp, lineax as lx
>>> import vardax as vdx
>>> class IdentityForward(eqx.Module):
... dt: float = 1.0
... state_signature: None = None
...
... def step(self, state, dt):
... return state
>>> eye = lx.IdentityLinearOperator(jax.ShapeDtypeStruct((1, 4), jnp.float32))
>>> oi = vdx.OptimalInterpolation(
... obs_op=vdx.LinearObs(operator=eye),
... prior_mean=jnp.zeros((1, 4)),
... prior_cov_op=eye,
... obs_cov_op=eye,
... )
>>> smoother = vdx.VarSmootherCycle(
... forward=IdentityForward(),
... obs_op=vdx.MaskedIdentity(),
... model=oi,
... window=3,
... )
>>> type(smoother).__name__
'SmootherCycle'
A model without as_analysis_step is rejected.
>>> vdx.VarSmootherCycle(
... forward=IdentityForward(),
... obs_op=vdx.MaskedIdentity(),
... model=object(),
... window=3,
... )
Traceback (most recent call last):
...
AttributeError: VarSmootherCycle requires a model exposing `.as_analysis_step()`
Source code in src/vardax/_src/cycle/da_cycle.py
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | |