fips.Problem.restrict#
- Problem.restrict(keep)[source]#
Return the problem on part of the state, the rest held at its prior.
Use it to solve for some of the state only, such as the cells the observations see well, and keep every other element at its prior value. Which elements to keep is your choice: for example, the cells whose total sensitivity is above a percentile of all cells’ (
fips.aggregate.sum()of the forward operator’s absolute column sums, grouped by cell, gives that total).The dropped elements still add to the observations, at their prior values: \(H_r x_{0,r}\) (the forward operator’s columns for them times their prior) is added to the offset. The prior, the prior covariance and the forward operator are cut to the kept labels; the covariance keeps its form, so a Kronecker covariance stays as its factors. The dropped elements’ prior uncertainty is not added to the model-data mismatch: they are held exactly at the prior.
After solving,
post.estimate.combine_first(problem.prior)puts the estimate back on the whole state, with the prior for the dropped elements (Vector.combine_first()).- Parameters:
keep (
Space) – The state of the new problem: blocks of the prior’s space, each with some of its labels (in any order; the new problem has them in this order). A block of the prior not in keep is held at the prior whole.- Returns:
The restricted problem (of the same class). The observations and their covariance are unchanged; its offset is this problem’s offset (zero if none) plus the contribution of the elements left out.
- Return type:
- Raises:
ValueError – If keep has a block or a label that the prior lacks.
See also
Vector.combine_firstThe estimate put back on the whole state.
Examples
>>> import numpy as np >>> import pandas as pd >>> import fips >>> cells = pd.Index(["a", "b", "c"], name="cell") >>> obs_id = pd.Index(["o1", "o2"], name="obs_id") >>> prior = fips.Vector.from_series( ... pd.Series([1.0, 2.0, 3.0], index=cells), block="flux" ... ) >>> obs = fips.Vector.from_series( ... pd.Series([4.0, 5.0], index=obs_id), block="co2" ... ) >>> H = np.array([[1.0, 1.0, 1e-6], [0.0, 1.0, 1e-6]]) >>> problem = fips.Problem( ... prior=prior, ... prior_cov=fips.Independent().with_std(1.0), ... obs=obs, ... obs_cov=fips.Independent().with_std(0.5), ... forward=fips.Operator(H, obs.space, prior.space), ... ) >>> small = problem.restrict(fips.Space({"flux": cells[:2]})) >>> small.offset.values array([3.e-06, 3.e-06]) >>> post = fips.solve(small) >>> post.estimate.combine_first(problem.prior).values.round(3) array([0.034, 4.207, 3. ])