"""Machine-readable metadata for every method, keyed by spec type.
This is the introspection surface that ``diagnose()`` and tooling read to reason
about which method fits a series and what each guarantees. It is data, not a
string factory: dispatch keys off the concrete spec type, not a name.
"""
from __future__ import annotations
from dataclasses import dataclass
from tsbootstrap.methods import (
IID,
CircularBlock,
MovingBlock,
NonOverlappingBlock,
ResidualBootstrap,
SieveAR,
StationaryBlock,
TaperedBlock,
)
METHODS: dict[type, MethodMetadata] = {
IID: MethodMetadata(
name="iid",
assumptions=("exchangeability (no serial dependence)",),
supports_multivariate=True,
supports_exog=False,
supports_indices=True,
supports_oob=True,
preserves_temporal_dependence=False,
references=("Efron 1979",),
complexity="O(B*n)",
failure_modes=("invalid under serial dependence; baseline only",),
),
MovingBlock: MethodMetadata(
name="moving_block",
assumptions=("stationarity", "weak dependence"),
supports_multivariate=True,
supports_exog=False,
supports_indices=True,
supports_oob=True,
preserves_temporal_dependence=True,
references=("Kunsch 1989", "Liu-Singh 1992"),
complexity="O(B*n)",
failure_modes=("sensitive to block length", "edge effects"),
),
CircularBlock: MethodMetadata(
name="circular_block",
assumptions=("stationarity", "weak dependence"),
supports_multivariate=True,
supports_exog=False,
supports_indices=True,
supports_oob=True,
preserves_temporal_dependence=True,
references=("Politis-Romano 1992",),
complexity="O(B*n)",
failure_modes=("sensitive to block length",),
),
StationaryBlock: MethodMetadata(
name="stationary_block",
assumptions=("stationarity", "weak dependence"),
supports_multivariate=True,
supports_exog=False,
supports_indices=True,
supports_oob=True,
preserves_temporal_dependence=True,
references=("Politis-Romano 1994",),
complexity="O(B*n)",
failure_modes=("sensitive to expected block length",),
),
NonOverlappingBlock: MethodMetadata(
name="non_overlapping_block",
assumptions=("stationarity", "weak dependence"),
supports_multivariate=True,
supports_exog=False,
supports_indices=True,
supports_oob=True,
preserves_temporal_dependence=True,
references=("Carlstein 1986",),
complexity="O(B*n)",
failure_modes=("higher variance than overlapping blocks",),
),
TaperedBlock: MethodMetadata(
name="tapered_block",
assumptions=("stationarity", "weak dependence"),
supports_multivariate=True,
supports_exog=False,
supports_indices=True,
supports_oob=True,
preserves_temporal_dependence=True,
references=("Paparoditis-Politis 2001",),
complexity="O(B*n)",
failure_modes=("requires correct window energy normalization",),
),
ResidualBootstrap: MethodMetadata(
name="residual",
assumptions=("correctly specified AR/ARIMA/VAR model", "stable (non-explosive) dynamics"),
supports_multivariate=True,
supports_exog=False,
supports_indices=False,
supports_oob=False,
preserves_temporal_dependence=True,
references=(
"Efron-Tibshirani 1993",
"Kreiss-Lahiri 2012",
"Wu 1986 (wild innovations)",
"Mammen 1993 (wild innovations)",
"Davidson-Flachaire 2008 (Rademacher default)",
"Shao 2010 (block-wild innovations)",
),
complexity="O(B*n*p) AR; O(B*n*p*d^2) VAR",
failure_modes=("model misspecification", "near-unit-root instability"),
),
SieveAR: MethodMetadata(
name="sieve_ar",
assumptions=("linear process admitting an AR(inf) representation",),
supports_multivariate=False,
supports_exog=False,
supports_indices=False,
supports_oob=False,
preserves_temporal_dependence=True,
references=("Buhlmann 1997", "Kreiss 1992"),
complexity="O(B*n*p_hat)",
failure_modes=("poor order selection", "near-unit-root instability"),
),
}
__all__ = ["MethodMetadata", "METHODS", "metadata_for"]