Nonlinear inversion¶
The end-to-end coupled inversion over the emission rate (Gaussian or lognormal), source position, wind, background and per-instrument biases, through each instrument's averaging kernel or a JAX radiance operator. plumax builds the forward, the prior and the quality masks; vardax solves it (ThreeDVar with L-BFGS in the whitened control) and gives the Laplace posterior (LaplaceCovariance). Needs the assim extra. Tier IV.
inversion
¶
Nonlinear end-to-end coupled inversion on vardax (implementation in plumax.coupled._src.inversion).
CoupledPrior
dataclass
¶
CoupledPrior(mean: Mapping[str, Float[Array, '*shape']], covariance: Float[Array, ' param'] | Float[Array, 'param param'])
Gaussian prior N(μ_θ, Σ_θ) on the stacked control, by named block.
Attributes:
| Name | Type | Description |
|---|---|---|
mean |
Mapping[str, Float[Array, '*shape']]
|
Prior mean μ_θ of each block. Exactly one of |
covariance |
Float[Array, ' param'] | Float[Array, 'param param']
|
Σ_θ over the flattened control, in :attr: |
Raises:
| Type | Description |
|---|---|
ValueError
|
On an unknown or missing block, a mis-shaped block or a covariance that does not match the control. |
layout
property
¶
(block, length) pairs in the flattened order (sorted by name).
log_emission
property
¶
Whether the emission is lognormal (controlled through log Q).
from_std
classmethod
¶
from_std(mean: Mapping[str, Float[Array, '*shape'] | float], std: Mapping[str, Float[Array, '*shape'] | float]) -> CoupledPrior
A diagonal prior from per-block means and standard deviations.
Σ_θ = diag(σ²), each block's σ broadcast to the block's shape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mean
|
Mapping[str, Float[Array, '*shape'] | float]
|
Prior mean μ_θ of each block. |
required |
std
|
Mapping[str, Float[Array, '*shape'] | float]
|
Prior standard deviation σ of each block, same keys. |
required |
Returns:
| Type | Description |
|---|---|
CoupledPrior
|
The prior. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the keys differ or a deviation is not positive. |
Source code in src/plumax/coupled/_src/inversion.py
flatten
¶
μ_θ as one vector, and the map from such a vector back to blocks.
Source code in src/plumax/coupled/_src/inversion.py
cholesky
¶
L with Σ_θ = L Lᵀ (√σ² on the diagonal for a diagonal prior).
Source code in src/plumax/coupled/_src/inversion.py
row_operator
¶
Σ_θ on a (1, D_θ) control row, the shape vardax applies it to.
Source code in src/plumax/coupled/_src/inversion.py
CoupledProblem
dataclass
¶
CoupledProblem(forward: CoupledForward, prior: CoupledPrior, observations: Mapping[str, Float[Array, '*shape']], radiance_ops: Mapping[str, RadianceOperator] = dict(), radiance_variance: Mapping[str, Float[Array, '*shape'] | float] = dict())
The coupled forward, its prior and every instrument's observations.
Column instruments are observed through their averaging kernel (the
CoupledForward responses); an instrument named in radiance_ops is
observed through that operator instead, applied to its column (bias
included). Masks and variance inflation come from each instrument
(coupled.quality.apply_quality).
Attributes:
| Name | Type | Description |
|---|---|---|
forward |
CoupledForward
|
The coupled forward. |
prior |
CoupledPrior
|
Prior on the control. |
observations |
Mapping[str, Float[Array, '*shape']]
|
Observations by instrument name: |
radiance_ops |
Mapping[str, RadianceOperator]
|
JAX radiance operators by instrument name. |
radiance_variance |
Mapping[str, Float[Array, '*shape'] | float]
|
Radiance error variance by instrument name, a
scalar or |
Raises:
| Type | Description |
|---|---|
ValueError
|
On missing or extra observations, a met block without a
|
TypeError
|
For a |
responses
¶
Unit-emission response of each instrument at this control.
Source code in src/plumax/coupled/_src/inversion.py
predict
¶
h_i(θ) for every instrument, by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
control
|
Mapping[str, Array]
|
The control, by block (as :meth: |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Array]
|
Columns |
Source code in src/plumax/coupled/_src/inversion.py
predict_stacked
¶
Every instrument's prediction, flattened and stacked, shape (D_y,).
Source code in src/plumax/coupled/_src/inversion.py
stacked_observations
¶
Observations, masks and Σ_ε stacked like :meth:predict_stacked.
A radiance pixel's mask and variance inflation apply to all its channels. Masked values are zero (jejjohnson/vardax#147).
Source code in src/plumax/coupled/_src/inversion.py
CoupledResult
dataclass
¶
CoupledResult(map_estimate: dict[str, Array], std: dict[str, Array] | None, mean: Array, covariance: Array | None, emission_rate: Array, emission_std: Array, converged: bool, n_steps: int, cost: float, per_instrument_residuals: dict[str, Array], pixels_used: dict[str, int], prior: CoupledPrior | None = None)
MAP and Laplace posterior of the coupled inversion.
emission_rate and emission_std are the posterior mean and standard
deviation of Q (population.PerEventPosterior): for a lognormal Q the
lognormal moments of the Laplace marginal on log Q,
E[Q] = exp(μ + σ²/2) and sd[Q] = E[Q] √(exp(σ²) − 1).
Attributes:
| Name | Type | Description |
|---|---|---|
map_estimate |
dict[str, Array]
|
MAP θ* by block ( |
std |
dict[str, Array] | None
|
Laplace posterior standard deviation by block ( |
mean |
Array
|
MAP θ* flattened, in |
covariance |
Array | None
|
Laplace covariance Σ_θ|y, |
emission_rate |
Array
|
Posterior mean of Q. |
emission_std |
Array
|
Posterior standard deviation of Q (NaN without the posterior). |
converged |
bool
|
optimistix's success flag for the L-BFGS solve. |
n_steps |
int
|
Iterations taken. |
cost |
float
|
𝒥 at the MAP, in the whitened control. |
per_instrument_residuals |
dict[str, Array]
|
y_i − h_i(θ*) by instrument, NaN where masked. |
pixels_used |
dict[str, int]
|
Pixels each instrument contributed at full weight. |
prior |
CoupledPrior | None
|
The prior the solve used ( |
For a scalar Q it also carries the Tier V per-event payload
(population.PerEventPosterior): draws of Q from the Laplace marginal
of its block, N(Q, σ²) or log Q ~ N(log Q, σ²) for a lognormal Q, and the
log-density of that block's prior marginal, both exact for the Gaussian
laws on θ.
samples
¶
n draws of Q from the Laplace marginal of its block.
Raises:
| Type | Description |
|---|---|
PayloadError
|
Without the Laplace posterior, or for a vector Q. |
Source code in src/plumax/coupled/_src/inversion.py
prior_logpdf
¶
log π(Q) of the prior marginal of Q's block.
Raises:
| Type | Description |
|---|---|
PayloadError
|
Without the prior, or for a vector Q. |
Source code in src/plumax/coupled/_src/inversion.py
RadianceOperator
¶
Bases: Protocol
A JAX radiance operator: column enhancement → per-receptor channels.
LinearisedRadianceOperator and LayeredRadianceOperator qualify.
predict
¶
plume_response
¶
plume_response(source: PlumeSource, instrument: Instrument, location: Float[Array, ' 2'], wind: Float[Array, ' 2']) -> Float[Array, ' obs']
Tier I unit-emission column at a traced source position and wind.
coupled.column_response with the horizontal position and the wind
(speed, meteorological direction) as JAX arrays, so the coupled cost can
differentiate through them. The source height, stability class and levels
stay those of source.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
PlumeSource
|
The Tier I source (height, stability, levels). |
required |
instrument
|
Instrument
|
The observing instrument. |
required |
location
|
Float[Array, ' 2']
|
Source |
required |
wind
|
Float[Array, ' 2']
|
|
required |
Returns:
| Type | Description |
|---|---|
Float[Array, ' obs']
|
The unit-emission column through the averaging kernel. |
Source code in src/plumax/coupled/_src/inversion.py
solve_coupled
¶
solve_coupled(problem: CoupledProblem, *, method: Literal['lbfgs', 'gauss_newton'] = 'lbfgs', laplace: bool = True, rtol: float = 1e-08, atol: float = 1e-10, max_steps: int = 200) -> CoupledResult
MAP and Laplace posterior of the coupled problem, on vardax.
θ = argmin 𝒥(θ), Σ_θ|y = (Σ_θ⁻¹ + J_hᵀ Σ_ε⁻¹ J_h)⁻¹ at θ.
Algorithm
- Flatten the prior to μ_θ, factor Σ_θ = L Lᵀ.
- Stack observations, masks and Σ_ε over the instruments.
vardax.ThreeDVarwith the stacked forward as aCallableObsand the whitened control θ = μ_θ + L χ; minimise with L-BFGS.vardax.LaplaceCovarianceat θ*, materialised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
problem
|
CoupledProblem
|
The coupled problem. |
required |
method
|
Literal['lbfgs', 'gauss_newton']
|
|
'lbfgs'
|
laplace
|
bool
|
Also compute the Laplace posterior. |
True
|
rtol
|
float
|
L-BFGS relative tolerance. |
1e-08
|
atol
|
float
|
L-BFGS absolute tolerance. |
1e-10
|
max_steps
|
int
|
Iteration cap. |
200
|
Returns:
| Name | Type | Description |
|---|---|---|
The |
CoupledResult
|
class: |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
For |
ImportError
|
Without the |
Source code in src/plumax/coupled/_src/inversion.py
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 | |