Source code for min_ratio_cycle.analytics

"""
Statistical analysis utilities for solver results.
"""

from __future__ import annotations

from collections.abc import Iterable
from math import sqrt

import numpy as np


[docs] def confidence_interval( values: Iterable[float], alpha: float = 0.05 ) -> tuple[float, float]: """ Return a two-sided confidence interval for the sample mean. Parameters ---------- values : Iterable[float] Sequence of observations. alpha : float, optional Significance level of the interval, by default ``0.05`` which corresponds to a 95% confidence interval. Returns ------- Tuple[float, float] Lower and upper bounds of the interval. Raises ------ ValueError If fewer than two observations are provided. Notes ----- A normal approximation is used. For non-default ``alpha`` the critical value is estimated through Monte Carlo sampling. Examples -------- >>> confidence_interval([1.0, 2.0, 3.0, 4.0]) # doctest: +SKIP (1.0..., 3.9...) """ data = np.array(list(values), dtype=float) if data.size < 2: raise ValueError("At least two values are required") mean = float(data.mean()) std = float(data.std(ddof=1)) if alpha == 0.05: z = 1.96 else: z = abs( np.percentile(np.random.standard_normal(10_000), [100 * (1 - alpha / 2)])[0] ) margin = z * std / sqrt(data.size) return mean - margin, mean + margin
[docs] def convergence_rate(errors: Iterable[float]) -> float: """ Estimate the average ratio of successive errors. Parameters ---------- errors : Iterable[float] Ordered sequence of error magnitudes from an iterative algorithm. Returns ------- float Mean of ``errors[i+1] / errors[i]``. Raises ------ ValueError If fewer than two error values are supplied. """ data = np.array(list(errors), dtype=float) if data.size < 2: raise ValueError("Need at least two error values") ratios = data[1:] / data[:-1] return float(ratios.mean())
[docs] def compare_solutions(values1: Iterable[float], values2: Iterable[float]) -> float: """ Return Welch's t statistic comparing two samples. Parameters ---------- values1 : Iterable[float] First sequence of observations. values2 : Iterable[float] Second sequence of observations. Returns ------- float Welch's t statistic. ``math.inf`` is returned when the denominator is zero. Raises ------ ValueError If either sample contains fewer than two values. See Also -------- :func:`convergence_rate` : Estimate average convergence rate from errors. :func:`confidence_interval` : Compute a confidence interval for a sample. """ x = np.array(list(values1), dtype=float) y = np.array(list(values2), dtype=float) if x.size < 2 or y.size < 2: raise ValueError("Need at least two values in each sample") mean_diff = x.mean() - y.mean() var_x = x.var(ddof=1) var_y = y.var(ddof=1) denom = sqrt(var_x / x.size + var_y / y.size) if denom == 0: return float("inf") return float(mean_diff / denom)