derivkit.forecasting.expansions module#
Utilities for evaluating Fisher and DALI likelihood expansions.
This module provides functional helpers to evaluate approximate likelihoods (or posterior) surfaces from forecast tensors.
Conventions#
This module uses a single convention throughout:
delta_chi2is defined from the displacementd = theta - theta0.The log posterior is returned (up to an additive constant) as:
log p(theta) = logprior(theta) - 0.5 * delta_chi2(theta)
When bias is provided, an additional systematic source term is included.
With the forecast tensors returned by derivkit.forecasting.get_forecast_tensors()
(using the introduced-at-order convention):
dali[1] == (F,)dali[2] == (D1, D2)dali[3] == (T1, T2, T3)dali[4] == (Qa1, Qa2, Qa3, Qa4)
the DALI delta_chi2 is:
order 1 (Fisher):
d.T @ F @ dorder 2 (doublet): add
D1[d^3] + (1/4) D2[d^4]order 3 (triplet): add
(1/3) T1[d^4] + (1/6) T2[d^5] + (1/36) T3[d^6]order 4 (quadruplet): add
(1/12) Qa1[d^5] + (1/24) Qa2[d^6] + (1/72) Qa3[d^7] + (1/576) Qa4[d^8]
GetDist convention#
GetDist expects loglikes to be the negative log posterior, up to a constant.
Since this module defines:
log p = logprior - 0.5 * delta_chi2 + const
a compatible choice for GetDist is:
loglikes = -logprior + 0.5 * delta_chi2 - systematic_source
(optionally shifted by an additive constant for numerical stability).
The systematic source is zero when bias=None.
- derivkit.forecasting.expansions.build_delta_chi2_dali(theta: NDArray[floating], theta0: NDArray[floating], dali: Any, *, forecast_order: int | None = 2) float#
Compute
delta_chi2under the DALI approximation.This evaluates a scalar
delta_chi2from the displacementd = theta - theta0using forecast tensors returned byderivkit.forecasting.get_forecast_tensors().The input must be the dict form using the introduced-at-order convention:
dali[1] == (F,)withFof shape(p, p)dali[2] == (D1, D2)with shapes(p, p, p)and(p, p, p, p)dali[3] == (T1, T2, T3)with shapes(p,)*4,(p,)*5,(p,)*6dali[4] == (Qa1, Qa2, Qa3, Qa4)with shapes(p,)*5, (p,)*6`,(p,)*7,(p,)*8
The evaluated quantity is:
order 2:
d.T @ F @ d + D1[d^3] + (1/4) D2[d^4]order 3: order 2 plus
(1/3) T1[d^4] + (1/6) T2[d^5] + (1/36) T3[d^6]order 4: order 3 plus
(1/12) Qa1[d^5] + (1/24) Qa2[d^6]+ (1/72) Qa3[d^7] + (1/576) Qa4[d^8]
- Parameters:
theta – Evaluation point in parameter space.
theta0 – Expansion point (fiducial parameters).
dali – Forecast tensors as a dict.
forecast_order – Maximum order to include. If
None, uses the highest key indaliand requires it to be at least 2.
- Returns:
Scalar
delta_chi2.- Raises:
TypeError – If
daliis not a dict.ValueError – If required tensor orders are missing or have incompatible shapes.
- derivkit.forecasting.expansions.build_delta_chi2_fisher(theta: NDArray[floating], theta0: NDArray[floating], fisher: NDArray[floating]) float#
Computes a displacement chi-squared under the Fisher approximation.
- Parameters:
theta – Evaluation point in parameter space. This is the trial parameter vector at which the Fisher expansion is evaluated.
theta0 – Expansion point (reference parameter vector). The Fisher matrix is assumed to have been computed at this point, and the expansion is taken in the displacement
theta - theta0.fisher – Fisher matrix with shape
(p, p)withpthe number of parameters.
- Returns:
The scalar delta chi-squared value between
thetaandtheta_0.
- derivkit.forecasting.expansions.build_logposterior_dali(theta: NDArray[floating], theta0: NDArray[floating], dali: Any, *, bias: dict[int, NDArray[floating]] | None = None, forecast_order: int | None = 2, prior_terms: Sequence[tuple[str, dict[str, Any]] | dict[str, Any]] | None = None, prior_bounds: Sequence[tuple[float | None, float | None]] | None = None, logprior: Callable[[NDArray[floating]], float] | None = None) float#
Computes the log posterior under the DALI approximation.
The log posterior combines the prior, the DALI likelihood expansion, and an optional systematic mismatch contribution.
The DALI contribution is evaluated using
build_delta_chi2_dali(). Whenbiasis provided, the mismatch tensors are contracted with the parameter displacement and weighted by the factorial of their order.The mismatch tensors can be obtained from
derivkit.forecasting.dali_bias.build_dali_bias_tensor().- Parameters:
theta – Evaluation point in parameter space.
theta0 – Expansion point (fiducial parameters).
dali – Forecast tensors as a dict in the introduced-at-order convention.
bias – Optional dictionary of systematic mismatch tensors returned by
derivkit.forecasting.dali_bias.build_dali_bias_tensor(). The dictionary maps derivative orders to parameter-space tensors. The tensors contribute to the log posterior through the requestedforecast_order. IfNone, no systematic mismatch is included.forecast_order – Maximum order to include in
delta_chi2. IfNone, uses the highest key indali.prior_terms – Prior term specification passed to
build_prior().prior_bounds – Global hard bounds passed to
build_prior().logprior – Optional custom log-prior callable.
- Returns:
Scalar log posterior value (up to an additive constant). If the prior evaluates to a non-finite value, returns
-np.inf.
- derivkit.forecasting.expansions.build_logposterior_fisher(theta: NDArray[floating], theta0: NDArray[floating], fisher: NDArray[floating], *, bias: NDArray[floating] | None = None, prior_terms: Sequence[tuple[str, dict[str, Any]] | dict[str, Any]] | None = None, prior_bounds: Sequence[tuple[float | None, float | None]] | None = None, logprior: Callable[[NDArray[floating]], float] | None = None) float#
Computes the log posterior under the Fisher approximation.
The returned value is defined up to an additive constant in log space. This corresponds to an overall multiplicative normalization of the posterior density in probability space.
If no prior is provided, this returns the Fisher log-likelihoods expansion with a flat prior and no hard cutoffs.
The Fisher approximation corresponds to a purely quadratic
delta_chi2surface:delta_chi2 = d.T @ F @ d
so the log posterior is:
log p = -0.5 * delta_chi2
The Fisher approximation describes a Gaussian likelihood through its quadratic form. The enclosed probability associated with a given
delta_chi2threshold depends on the number of parameters.The DALI approximation extends this quadratic form with higher-order terms, allowing the likelihood to depart from Gaussianity. See
build_delta_chi2_dali()for the corresponding DALI expansion.- Parameters:
theta – Evaluation point in parameter space. This is the trial parameter vector at which the Fisher/DALI expansion is evaluated.
theta0 – Expansion point (reference parameter vector). The Fisher matrix and any DALI tensors are assumed to have been computed at this point, and the expansion is taken in the displacement
theta - theta0.fisher – Fisher matrix with shape
(p, p)withpthe number of parameters.bias – Optional linear systematic-bias vector of shape
(p,). If provided, addsbias @ (theta - theta0)to the Fisher log posterior.prior_terms – prior term specification passed to
derivkit.forecasting.priors.core.build_prior().prior_bounds – Global hard bounds passed to
derivkit.forecasting.priors.core.build_prior().logprior – Optional custom log-prior callable. If it returns a non-finite value, the posterior is treated as zero at that point and the function returns
-np.inf.
- Returns:
Scalar log posterior value, defined up to an additive constant.
- derivkit.forecasting.expansions.build_subspace(idx: Sequence[int], *, theta0: NDArray[floating], fisher: NDArray[floating] | None = None, dali: dict[int, tuple[NDArray[floating], ...]] | None = None) dict[str, Any]#
Extracts a parameter subspace for Fisher or DALI expansions.
This returns a slice through parameter space: parameters not in
idxare held fixed at their expansion values. This is not a marginalization.Provide exactly one of
fisherordali:Fisher:
fisherhas shape(p, p)and the return dict contains{"theta0": theta0_sub, "fisher": fisher_sub}.DALI:
daliis the dict form returned byderivkit.forecasting.get_forecast_tensors()using the introduced-at-order convention, and the return dict contains{"theta0": theta0_sub, "dali": dali_sub}.
- Parameters:
idx – Parameter indices to extract.
theta0 – Expansion point of shape
(p,).fisher – Fisher matrix of shape
(p, p).dali – Forecast tensors as a dict mapping
order -> multiplet.
- Returns:
A dict containing the sliced objects. Always includes
"theta0". Includes"fisher"iffisherwas provided, or"dali"ifdaliwas provided.- Raises:
ValueError – If not exactly one of
fisherordaliis provided.TypeError – If
idxcontains non-integers, or ifdaliis not a dict.IndexError – If any index in
idxis out of bounds.ValueError – If the provided arrays have incompatible shapes.