Skip to content

Tolerance Bands

Tolerance bands define a region that is expected to contain a specified proportion of future functional observations. They are the functional analogue of prediction intervals and are widely used in quality control, clinical trials, and environmental monitoring.

fdars provides three complementary approaches plus a functional equivalence test.


FPCA bootstrap tolerance band

This method uses the FPCA representation of the sample to generate bootstrap replicates, from which a simultaneous tolerance band is constructed.

import numpy as np
from fdars import Fdata
from fdars.simulation import simulate
from fdars.tolerance import fpca_tolerance_band

argvals = np.linspace(0, 1, 100)
fd = Fdata(simulate(60, argvals, n_basis=5, seed=1), argvals=argvals)

band = fpca_tolerance_band(fd.data, ncomp=3, nb=1000, coverage=0.95, seed=42)

Parameters

Parameter Type Default Description
data ndarray (n, m) -- Observed functional data
ncomp int 3 Number of FPC components to retain
nb int 1000 Number of bootstrap replicates
coverage float 0.95 Desired coverage probability
seed int 42 Random seed

Returns a dictionary:

Key Shape Description
upper (m,) Upper boundary of the band
lower (m,) Lower boundary of the band
center (m,) Pointwise center (mean)
half_width (m,) Half-width at each grid point

Conformal prediction band

A distribution-free alternative that splits the data into a proper training set and a calibration set, then uses the calibration residuals to determine the band width.

from fdars.tolerance import conformal_prediction_band

band_cp = conformal_prediction_band(fd.data, coverage=0.95, cal_fraction=0.25, seed=42)

Parameters

Parameter Type Default Description
data ndarray (n, m) -- Observed functional data
coverage float 0.95 Target coverage
cal_fraction float 0.25 Fraction of data reserved for calibration
seed int 42 Random seed

Returns a dictionary with the same keys as the FPCA band (upper, lower, center, half_width).

When to prefer conformal bands

Conformal bands make no distributional assumptions. They are especially useful when the underlying process is non-Gaussian or when the sample size is small enough that the FPCA bootstrap may be unreliable.


Simultaneous confidence band (Degras)

Constructs a simultaneous confidence band for the mean function using the Gaussian multiplier bootstrap method of Degras (2011).

from fdars.tolerance import scb_mean_degras

band_scb = scb_mean_degras(fd.data, fd.argvals, bandwidth=0.0, nb=1000, confidence=0.95)

Setting bandwidth=0.0 enables automatic bandwidth selection.

Parameters

Parameter Type Default Description
data ndarray (n, m) -- Observed data
argvals ndarray (m,) -- Evaluation grid
bandwidth float 0.0 Kernel bandwidth (0.0 = auto)
nb int 1000 Number of bootstrap samples
confidence float 0.95 Confidence level

Returns the same dictionary structure (upper, lower, center, half_width).

Tolerance band vs. confidence band

A tolerance band targets individual future curves (analogous to a prediction interval). A confidence band targets the mean function (analogous to a confidence interval). Use fpca_tolerance_band or conformal_prediction_band for the former, and scb_mean_degras for the latter.


Equivalence test

Test whether two groups of functional observations are equivalent -- i.e., their mean functions differ by no more than a margin \(\delta\) -- using a functional TOST (two one-sided tests) procedure.

from fdars.tolerance import equivalence_test

# Two groups with similar means
fd_a = Fdata(simulate(40, argvals, n_basis=5, seed=10), argvals=argvals)
fd_b = Fdata(simulate(40, argvals, n_basis=5, seed=20) + 0.1, argvals=argvals)  # small shift

result = equivalence_test(fd_a.data, fd_b.data, delta=0.5, alpha=0.05, nb=1000, seed=42)
print(f"Equivalent: {result['equivalent']}")
print(f"p-value:    {result['p_value']:.4f}")
print(f"Test stat:  {result['test_statistic']:.4f}")

Parameters

Parameter Type Default Description
data1 ndarray (n1, m) -- First group
data2 ndarray (n2, m) -- Second group
delta float -- Equivalence margin
alpha float 0.05 Significance level
nb int 1000 Bootstrap replicates
seed int 42 Random seed

Returns a dictionary:

Key Type Description
equivalent bool True if equivalence is established at level \(\alpha\)
p_value float Bootstrap p-value
test_statistic float Observed test statistic

Full example -- comparing all three band methods

import numpy as np
from fdars import Fdata
from fdars.simulation import simulate
from fdars.tolerance import (
    fpca_tolerance_band,
    conformal_prediction_band,
    scb_mean_degras,
)

# ── Data ──────────────────────────────────────────────────────
argvals = np.linspace(0, 1, 100)
fd = Fdata(simulate(80, argvals, n_basis=5, seed=7), argvals=argvals)

# ── Bands ─────────────────────────────────────────────────────
tol_fpca = fpca_tolerance_band(fd.data, ncomp=3, nb=2000, coverage=0.95, seed=1)
tol_conf = conformal_prediction_band(fd.data, coverage=0.95, cal_fraction=0.25, seed=1)
scb      = scb_mean_degras(fd.data, fd.argvals, bandwidth=0.0, nb=2000, confidence=0.95)

# ── Visualize (optional) ─────────────────────────────────────
try:
    import matplotlib.pyplot as plt

    fig, axes = plt.subplots(1, 3, figsize=(15, 4), sharey=True)
    titles = ["FPCA tolerance", "Conformal prediction", "Degras SCB (mean)"]
    bands  = [tol_fpca, tol_conf, scb]

    for ax, title, b in zip(axes, titles, bands):
        ax.plot(fd.argvals, fd.data.T, color="0.85", linewidth=0.5)
        ax.fill_between(fd.argvals, b["lower"], b["upper"], alpha=0.25, label="band")
        ax.plot(fd.argvals, b["center"], "k-", linewidth=1.5, label="center")
        ax.set_title(title)
        ax.legend(fontsize=8)

    plt.tight_layout()
    plt.savefig("tolerance_bands.png", dpi=150)
    plt.show()
except ImportError:
    pass