cleverly.inference.delta_method#

cleverly.inference.delta_method(function: Callable[[ndarray[tuple[Any, ...], dtype[float64]]], float], estimates: Sequence[float], influence_curves: Sequence[ndarray[tuple[Any, ...], dtype[float64]]], *, gradient: Callable[[ndarray[tuple[Any, ...], dtype[float64]]], ndarray[tuple[Any, ...], dtype[float64]]] | None = None, step: float = 1e-06) → tuple[float, ndarray[tuple[Any, ...], dtype[float64]]][source]#

Influence curve of function applied to several estimands.

Returns (value, influence_curve) where the influence curve is \(\nabla f(\hat\psi)^\top \mathrm{IC}\). With gradient=None the gradient is obtained by central differences, which is accurate enough here because the functions of interest are smooth and low-dimensional.

Parameters:
functioncallable()

Maps the vector of estimates to the scalar of interest.

estimatessequence of float

The point estimates, in the order function reads.

influence_curvessequence of ndarray

One (n,) influence curve per estimate, in the same order.

gradientcallable() or None

Gradient of function. None takes central differences.

stepfloat

Relative step size for those differences.

Returns:
valuefloat

function at the estimates.

influence_curvendarray

(n,) influence curve of that value, carrying the correlation between the inputs.

Examples

A ratio of two estimands, with the correlation between their influence curves carried through:

>>> import numpy as np
>>> from cleverly.inference import delta_method
>>> rng = np.random.default_rng(0)
>>> ic_a = rng.normal(size=4)
>>> ic_b = rng.normal(size=4)
>>> value, ic = delta_method(lambda p: p[0] / p[1], [2.0, 4.0], [ic_a, ic_b])
>>> round(value, 6)
0.5
>>> ic.shape
(4,)