pypfda.filter

High-level particle filter orchestration.

The ParticleFilter class wires together the primitives in pypfda.weights and pypfda.resampling. Its ParticleFilter.assimilate() method takes one analysis step (weight + optional resampling) and returns the updated ensemble together with diagnostic information.

The filter is intentionally model-agnostic: it does not run the forward model itself. Callers are expected to integrate their own model between analysis steps and pass the resulting state and predicted observations back in.

Classes

AssimilationInfo(weights, log_weights, ess, ...)

Diagnostics returned by ParticleFilter.assimilate().

ParticleFilter([ess_threshold, resampling, ...])

Sequential importance resampling (SIR) particle filter.

class pypfda.filter.AssimilationInfo(weights, log_weights, ess, ess_fraction, entropy, resampled, indices)[source]

Bases: object

Diagnostics returned by ParticleFilter.assimilate().

Parameters:
weights

Normalized analysis weights.

Type:

ndarray, shape (n_members,)

log_weights

Unnormalized log-weights, useful for downstream log-domain ops.

Type:

ndarray, shape (n_members,)

ess

Effective sample size in particles.

Type:

float

ess_fraction

ess / n_members, in \([0, 1]\).

Type:

float

entropy

Shannon entropy of the weight distribution in nats.

Type:

float

resampled

Whether the ensemble was resampled this step.

Type:

bool

indices

Resampling indices, or None if no resampling occurred.

Type:

ndarray of int or None, shape (n_members,)

weights: ndarray[tuple[Any, ...], dtype[floating[Any]]]
log_weights: ndarray[tuple[Any, ...], dtype[floating[Any]]]
ess: float
ess_fraction: float
entropy: float
resampled: bool
indices: ndarray[tuple[Any, ...], dtype[int64]] | None
class pypfda.filter.ParticleFilter(ess_threshold=0.5, resampling='systematic', max_weight=None, rng=None)[source]

Bases: object

Sequential importance resampling (SIR) particle filter.

Parameters:
  • ess_threshold (float, default 0.5) – Resample whenever the effective sample size fraction drops below this value. Must lie in \((0, 1]\). Setting it to 1 forces resampling at every step; setting it close to 0 disables resampling almost entirely.

  • resampling ({'systematic', 'stratified', 'residual', 'multinomial'}, default 'systematic') – Resampling scheme to use when triggered.

  • max_weight (float, optional) – If given, the largest normalized weight is capped at this value and the surplus is redistributed among the remaining particles. Useful as a degeneracy-prevention safeguard. Must lie strictly above 1 / n_members and not exceed 1.

  • rng (numpy.random.Generator, optional) – Random number generator used for resampling. If omitted, a default generator is created and reused across calls.

Notes

The current implementation assumes a diagonal Gaussian observation error model; richer likelihoods can be obtained by passing pre-computed log-weights to assimilate_log_weights() instead.

assimilate(ensemble, ensemble_obs, observations, obs_err)[source]

Run one analysis (and possibly resampling) step.

Parameters:
  • ensemble (array_like, shape (n_members, ...)) – Ensemble state. Any trailing dimensions are preserved when resampling.

  • ensemble_obs (array_like, shape (n_members, n_obs)) – Predicted observations for each ensemble member.

  • observations (array_like, shape (n_obs,)) – Actual observations.

  • obs_err (float or array_like of shape (n_obs,)) – Observation-error standard deviations.

Returns:

  • ensemble_out (ndarray, shape (n_members, …)) – Resampled ensemble (or the input unchanged if no resampling occurred).

  • info (AssimilationInfo) – Diagnostics for this step.

Return type:

tuple[ndarray[tuple[Any, …], dtype[floating[Any]]], AssimilationInfo]

assimilate_log_weights(ensemble, log_weights)[source]

Like assimilate() but takes externally-computed log-weights.

Use this when you have a non-Gaussian likelihood, a custom proxy forward model, or pre-localized weights that do not factor as a single Gaussian product.

Parameters:
  • ensemble (array_like, shape (n_members, ...))

  • log_weights (array_like, shape (n_members,)) – Unnormalized log-weights.

Returns:

  • ensemble_out (ndarray, shape (n_members, …))

  • info (AssimilationInfo)

Return type:

tuple[ndarray[tuple[Any, …], dtype[floating[Any]]], AssimilationInfo]