Skip to content

API reference / Evaluation

tsdive.eval.martingale_alarm

martingale_alarm(
    log_values: Iterable[float], delta: float
) -> int | None

First index where the log martingale reaches log(1 / delta), else None.

Ville's inequality: under exchangeability of the calibration and stream scores, the probability that the martingale ever reaches 1 / delta is at most delta, so the bound covers the whole record and not each window separately. The bound rests on that exchangeability; any fitted centre and scale that produce the scores must come from a fit set disjoint from the calibration and stream. delta must lie in (0, 1), else ValueError.

Examples:

>>> from tsdive.eval import martingale_alarm
>>> martingale_alarm([0.0, 1.5, 3.2], delta=0.05)  # log(1 / 0.05) is 2.996
2
>>> martingale_alarm([0.0, 1.5], delta=0.05) is None
True