fips.Problem#

class fips.Problem(prior, prior_cov, obs, obs_cov, forward, offset=None)[source]#

A linear inverse problem: what is known before the observations, and the observations.

The state is \(x \sim N(x_0, S_0)\) (the prior), and the observations are \(z = H x + c + e\) with \(e \sim N(0, S_z)\). Every input is labeled, and the labels are checked once, here, by an exact join: the forward operator, the covariances and the offset must have exactly the labels of the prior or of the observations, in any order. Each is then put in the order of the prior’s and the observations’ spaces. A problem is not changed after it is built; fips.solve() solves it.

The problem is the question: it holds what needs no solve and no m x m matrix, such as predict(), and it makes other questions from itself (aggregate(), restrict()). What depends on the solve, or on the m x m innovation covariance, is on the Posterior.

Parameters:
  • prior (Vector) – The prior state \(x_0\). Its space labels the state.

  • prior_cov (Covariance | CovarianceModel) – The prior error covariance \(S_0\). A covariance model (such as Kronecker(...).with_std(std)) is built on the prior’s space.

  • obs (Vector) – The observations \(z\). Its space labels the observations.

  • obs_cov (Covariance | CovarianceModel) – The model-data mismatch \(S_z\), the covariance of the observation error; a model is built on the observations’ space. It must be positive-definite.

  • forward (Operator) – The forward operator \(H\), from the state (its columns) to the observations (its rows).

  • offset (Vector | float | None) – The part of the observations the state does not explain, \(c\) (a background): a vector on the observations’ labels, or one value for all of them. None (the default) is no offset.

Raises:
  • TypeError – If an input is not of a type named above.

  • ValueError – If the forward operator, a covariance or the offset does not have exactly the labels of the space it is put on: a block or a label on one side and not the other. The message names them.

See also

fips.solve

Solve a problem; it returns a Posterior.

Notes

A forward operator that covers only part of the state (a transport Jacobian has columns only for the cells a footprint touched) is placed on the whole state by Operator.from_blocks, which puts a labeled block by its labels: a cell the Jacobian lacks is a column of zeros, and a label the space lacks raises. With J the labeled Jacobian (a DataFrame, dense or pandas-sparse, or a tuple (matrix, row_labels, col_labels)):

forward = Operator.from_blocks(
    {("co2", "flux"): J}, rows=obs.space, cols=prior.space
)

Examples

>>> import numpy as np
>>> import pandas as pd
>>> import fips
>>> cells = pd.Index(["a", "b"], name="cell")
>>> obs_id = pd.Index(["o1", "o2", "o3"], name="obs_id")
>>> prior = fips.Vector.from_series(pd.Series(0.0, index=cells), block="flux")
>>> obs = fips.Vector.from_series(
...     pd.Series([1.0, 2.0, 3.0], index=obs_id), block="co2"
... )
>>> problem = fips.Problem(
...     prior=prior,
...     prior_cov=fips.Independent().with_std(1.0),
...     obs=obs,
...     obs_cov=fips.Independent().with_std(np.sqrt(0.1)),
...     forward=fips.Operator(
...         np.array([[1.0, 0.0], [0.0, 1.0], [1.0, 1.0]]), obs.space, prior.space
...     ),
... )
>>> problem
Problem(state: Space(flux: 2 x ['cell']), obs: Space(co2: 3 x ['obs_id']))
>>> fips.solve(problem).estimate.values.round(3)
array([0.997, 1.906])

Attributes

forward

rows on the observations, columns on the prior.

obs

The observations, \(z\); their space labels the observations.

obs_cov

The model-data mismatch, \(S_z\), on the observations' space.

offset

The offset, \(c\), on the observations' space, or None.

prior

The prior state, \(x_0\); its space labels the state.

prior_cov

The prior error covariance, \(S_0\), on the prior's space.

Methods

aggregate(W)

Return the problem of aggregated observations.

predict(x)

Return the observations the state x models, \(H x + c\).

restrict(keep)

Return the problem on part of the state, the rest held at its prior.

simulate([rng, truth])

Return a truth and the observations it would give, \(H x + c + e\).