coarse-grained-forecasting-benchmark's picture
Add anonymous reproduction code
41dd7e0 verified
Raw History Blame Contribute Delete
1.62 kB
"""Distributional metrics in state space.
``energy_distance`` is the validation metric of the paper's model selection (a V-statistic: ``md(X, X)`` and
``md(Y, Y)`` average over all pairs including self-pairs; ``2 md(X, Y) - md(X, X) - md(Y, Y)``).
"""
from __future__ import annotations
import numpy as np
def _mean_pairwise_dist(A: np.ndarray, B: np.ndarray) -> float:
return np.mean(np.linalg.norm(A[:, None] - B[None, :], axis=-1))
def energy_distance(X: np.ndarray, Y: np.ndarray) -> float:
md = _mean_pairwise_dist
return float(2 * md(X, Y) - md(X, X) - md(Y, Y))
def energy_distance_cached_self(X: np.ndarray, Y: np.ndarray, md_yy: float) -> float:
"""``energy_distance`` with the truth-self term ``md(Y, Y)`` supplied (it does not depend on X)."""
md = _mean_pairwise_dist
return float(2 * md(X, Y) - md(X, X) - float(md_yy))
def energy_distance_u(X: np.ndarray, Y: np.ndarray) -> float:
"""The unbiased U-statistic: the self terms exclude the diagonal, ``ED_U = ED_V - md(X,X)/(M-1) - md(Y,Y)/(N-1)``."""
md = _mean_pairwise_dist
mxx, myy = md(X, X), md(Y, Y)
M, N = X.shape[0], Y.shape[0]
return float(2 * md(X, Y) - mxx - myy - (mxx / (M - 1) if M > 1 else 0.0) - (myy / (N - 1) if N > 1 else 0.0))
def effective_rank(X: np.ndarray) -> float:
"""Effective rank of the sample covariance, tr(S)^2 / ||S||_F^2; NaN for fewer than 2 samples."""
X = np.asarray(X, dtype=np.float64)
if X.shape[0] < 2:
return float("nan")
S = np.cov(X.T)
fro2 = float((S * S).sum())
return float(S.trace() ** 2 / fro2) if fro2 > 0 else float("nan")