Ensemble Kalman Filter
The EnKF treats the filtering distribution as Gaussian, but represents it with an ensemble of \(N\) members \(x^{(i)}\) instead of storing a mean and covariance and linearizing \(f\) or \(h\). The implied mean and covariance are the usual sample mean and sample covariance of the members.
Predict. Each member is advanced with the dynamics and process noise. Multiplicative inflation (optional) rescales deviations from the new ensemble mean by a factor \((1+\delta)\) to combat underspread ensembles.
Update. From deviations in state and observation space, form empirical cross-covariance \(C_{xy}\) and innovation covariance \(S\) in observation space (including observation noise). The Kalman gain \(K \approx C_{xy} S^{-1}\) gives a Kalman-like correction to each member (e.g. stochastic EnKF with random observation perturbations).
The EnKF allows for storing its predicted states, \(x_{t \mid t - 1}\), through the store_predicted_ensemble flag. This flag is required when the filtering outputs are to be used by an EnRTS smoother.
Large observation dimensions. Setting ensemble_subspace=True performs the analysis in the \(N\)-dimensional ensemble subspace via the Woodbury identity. It is algebraically exact and cheaper whenever \(N\) is much smaller than the observation dimension. This cost can be further reduced by passing scalar or diagonal chol_R. It is incompatible with both localization callbacks below. See the cuthbertlib filtering documentation for the details.
See Algorithm 2 in Appendix A in Calvello, Reich, and Stuart., Ensemble Kalman Methods: A Mean Field Perspective for the EnKF algorithm which accomodates non-linear observation functions \(h\). Note that this algorithm corresponds to the perturbed_obs = True (Default) option in the EnKF implementation. This boolean flag is represented by s in Algorithm 10.2 of Sanz-Alonso et al., Inverse Problems and Data Assimilation, which was only written for linear \(h\).
cuthbert.ensemble_kalman.ensemble_kalman_filter
Implements the high-level Ensemble Kalman Filter (EnKF).
See Algorithm 10.2, Sanz-Alonso et al., Inverse Problems and Data Assimilation. Based in part on the CD-Dynamax implementation.
EnKFState
Bases: NamedTuple
Ensemble Kalman filter state.
key
instance-attribute
ensemble
instance-attribute
model_inputs
instance-attribute
log_normalizing_constant
instance-attribute
predicted_ensemble = None
class-attribute
instance-attribute
n_particles
property
Number of particles.
mean
property
Ensemble mean.
chol_cov
property
Generalised Cholesky factor of the ensemble sample covariance.
no_covariance_modifier(cross_covariance, model_inputs)
build_filter(init_sample, get_dynamics, get_observations, n_particles, inflation=0.0, perturbed_obs=True, store_predicted_ensemble=False, modify_cross_covariance=no_covariance_modifier, construct_chol_innovation_covariance=None, ensemble_subspace=False)
Builds an Ensemble Kalman Filter object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
init_sample
|
InitSample
|
Function of a JAX random key only, generates a single sample from the initial distribution. |
required |
get_dynamics
|
GetEnKFDynamics
|
Function to get dynamics function (x_t, key) -> x_{t+1} ~ p(x_{t+1} | x_t) from model inputs. |
required |
get_observations
|
GetEnKFObservations
|
Function to get observation function, chol_R, and y from model inputs. |
required |
n_particles
|
int
|
Number of particles. |
required |
inflation
|
float
|
Multiplicative inflation factor for ensemble deviations, applied in the predict step. |
0.0
|
perturbed_obs
|
bool
|
If True, use perturbed observations (stochastic EnKF). |
True
|
store_predicted_ensemble
|
bool
|
Whether to store the incoming forecast ensemble in each filter state, as required by the EnRTS smoother. |
False
|
modify_cross_covariance
|
ModifyCrossCovariance
|
Function that modifies the empirical state-observation cross-covariance in the update step. Defaults to the identity. |
no_covariance_modifier
|
construct_chol_innovation_covariance
|
ConstructCholInnovationCovariance | None
|
Optional function that
constructs a generalized Cholesky factor of the localized innovation
covariance matrix. |
None
|
ensemble_subspace
|
bool
|
If True, perform the analysis in the n_particles-dimensional
ensemble subspace. Algebraically exact, and cheaper in the state dimension
whenever When using it, prefer to have |
False
|
Returns:
| Type | Description |
|---|---|
Filter
|
Filter object for the EnKF. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in cuthbert/ensemble_kalman/ensemble_kalman_filter.py
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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | |
init_prepare(init_sample, n_particles, store_predicted_ensemble=False, key=None)
Prepare the initial state for the EnKF.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
init_sample
|
InitSample
|
Function of a JAX random key only, generates a single sample from the initial distribution. |
required |
n_particles
|
int
|
Number of particles. |
required |
store_predicted_ensemble
|
bool
|
Whether to store incoming forecast ensembles. |
False
|
key
|
KeyArray | None
|
JAX random key. |
None
|
Returns:
| Type | Description |
|---|---|
EnKFState
|
Initial EnKF state. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If key is None. |
Source code in cuthbert/ensemble_kalman/ensemble_kalman_filter.py
filter_prepare(model_inputs, init_sample, n_particles, store_predicted_ensemble=False, key=None)
Prepare a state for an EnKF step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_inputs
|
ArrayTreeLike
|
Model inputs. |
required |
init_sample
|
InitSample
|
Function of a JAX random key only, sampling from the initial distribution. Bind initial parameters when building the filter. |
required |
n_particles
|
int
|
Number of particles. |
required |
store_predicted_ensemble
|
bool
|
Whether to store incoming forecast ensembles. |
False
|
key
|
KeyArray | None
|
JAX random key. |
None
|
Returns:
| Type | Description |
|---|---|
EnKFState
|
Prepared EnKF state with dummy ensemble. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If key is None. |
Source code in cuthbert/ensemble_kalman/ensemble_kalman_filter.py
filter_combine(state_1, state_2, get_dynamics, get_observations, inflation=0.0, perturbed_obs=True, store_predicted_ensemble=False, modify_cross_covariance=no_covariance_modifier, construct_chol_innovation_covariance=None, ensemble_subspace=False)
Combine previous EnKF state with prepared state for current step.
Implements the EnKF predict + update cycle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state_1
|
EnKFState
|
EnKF state from the previous time step. |
required |
state_2
|
EnKFState
|
EnKF state prepared for the current step. |
required |
get_dynamics
|
GetEnKFDynamics
|
Function to get dynamics function and chol_Q from model inputs. |
required |
get_observations
|
GetEnKFObservations
|
Function to get observation function, chol_R, and y from model inputs. |
required |
inflation
|
float
|
Multiplicative inflation factor. |
0.0
|
perturbed_obs
|
bool
|
If True, use perturbed observations. |
True
|
store_predicted_ensemble
|
bool
|
Whether to store the incoming forecast ensemble. |
False
|
modify_cross_covariance
|
ModifyCrossCovariance
|
Function that modifies the empirical state-observation cross-covariance using the current model inputs. Defaults to the identity. |
no_covariance_modifier
|
construct_chol_innovation_covariance
|
ConstructCholInnovationCovariance | None
|
Optional function that
constructs a generalized Cholesky factor of the localized innovation
covariance matrix. |
None
|
ensemble_subspace
|
bool
|
If True, perform the analysis in the ensemble subspace. |
False
|
Returns:
| Type | Description |
|---|---|
EnKFState
|
Updated EnKF state. |
Source code in cuthbert/ensemble_kalman/ensemble_kalman_filter.py
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | |