Skip to content

Commit

Permalink
add covariance (#184)
Browse files Browse the repository at this point in the history
Adds `bootstrap.covariance` in addition to `bootstrap.variance`. The
former computes the full covariance matrix if the function returns a
vector, while the latter computes the variance element-wise.

The docstring of `bootstrap.variance` was clarified with respect to this
point.
  • Loading branch information
HDembinski authored Apr 19, 2024
1 parent 149d975 commit dcf2488
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/resample/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ def variance(
"""
Calculate bootstrap estimate of variance.
If the function returns a vector, the variance is computed elementwise.
Parameters
----------
fn : callable
Expand Down Expand Up @@ -327,6 +329,51 @@ def variance(
return np.var(thetas, ddof=1, axis=0)


def covariance(
fn: Callable[..., np.ndarray],
sample: "ArrayLike",
*args: "ArrayLike",
**kwargs: Any,
) -> np.ndarray:
"""
Calculate bootstrap estimate of covariance.
Parameters
----------
fn : callable
Estimator. Can be any mapping ℝⁿ → ℝᵏ, where n is the sample size
and k is the length of the output array.
sample : array-like
Original sample.
*args : array-like
Optional additional arrays of the same length to resample.
**kwargs
Keyword arguments forwarded to :func:`resample`.
Returns
-------
ndarray
Bootstrap estimate of covariance. In general, this is a matrix, but if the
function maps to a scalar, it is scalar as well.
Examples
--------
Compute variance of arithmetic mean.
>>> from resample.bootstrap import variance
>>> import numpy as np
>>> x = np.arange(10)
>>> def fn(x):
... return np.mean(x), np.var(x)
>>> np.round(covariance(fn, x, size=10000, random_state=1), 1)
array([[0.8, 0. ],
[0. , 5.5]])
"""
thetas = bootstrap(fn, sample, *args, **kwargs)
return np.cov(thetas, rowvar=False, ddof=1)


def confidence_interval(
fn: Callable[..., np.ndarray],
sample: "ArrayLike",
Expand Down
12 changes: 12 additions & 0 deletions tests/test_bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
confidence_interval,
resample,
variance,
covariance,
)

PARAMETRIC_CONTINUOUS = {
Expand Down Expand Up @@ -295,6 +296,17 @@ def test_variance(method, rng):
assert r == pytest.approx(v, rel=0.05)


@pytest.mark.parametrize("method", NON_PARAMETRIC)
def test_covariance(method, rng):
cov = np.array([[1.0, 0.1], [0.1, 2.0]])
data = rng.multivariate_normal([0.1, 0.2], cov, size=1000)

r = covariance(
lambda x: np.mean(x, axis=0), data, size=1000, method=method, random_state=rng
)
assert_allclose(r, cov / len(data), atol=1e-3)


def test_resample_deprecation(rng):
data = [1, 2, 3]
from numpy import VisibleDeprecationWarning
Expand Down

0 comments on commit dcf2488

Please sign in to comment.