sup_wald#
- cultivars.diagnostics.breaks.sup_wald(endog, exog=None, *, trend='c', trimming=0.15, n_draws=5000, grid=2000, seed=None)[source]#
Andrews’ sup-Wald test for one break at an unknown date, with exp- and ave-Wald.
The regression \(y_t = x_t^\top \beta + u_t\) is split at every date \(T_b\) in the trimmed window \([\pi_0 T, (1 - \pi_0) T]\), and the Wald statistic for equality of the two coefficient vectors, computed under a common error variance, is
\[W(T_b) = \frac{S_0 - S_1(T_b)}{S_1(T_b) / (T - 2q)},\]with \(S_0\) the full-sample and \(S_1(T_b)\) the split residual sum of squares. Three functionals of the path are taken: the sup, which is Andrews’ (1993) test and locates the break at its arg-max; and Andrews and Ploberger’s (1994) exp-Wald, \(\log \operatorname{mean} \exp(W / 2)\), and ave-Wald, \(\operatorname{mean} W\), which are the optimal tests against alternatives distant from and close to the null respectively and give up the location. Under the null all three converge to the same functionals of \(BB_q(\pi)^\top BB_q(\pi) / (\pi(1 - \pi))\) with \(BB_q\) a \(q\)-dimensional Brownian bridge, and the p-values and critical values come from
n_drawssimulated paths of that process on a grid ofgridpoints at the trimming actually used, rather than from a table at another trimming. The sup’s 5% value at \(q = 1\), \(\pi_0 = 0.15\) reproduces Andrews’ corrected 8.68 to within Monte Carlo error.- Parameters:
endog (
ArrayLike) – The target,(T,).exog (
ArrayLike|None) – Regressors(T, k)or(T,), orNone.trend (
str) – Deterministic terms,"n","c"or"ct", placed before the regressors in the design; withexog=Nonethe test is for a break in the mean or trend.trimming (
float) – Fraction of the sample excluded at each end, in(0, 0.5); the window also excludes the first and lastqobservations so that both segments are estimable.n_draws (
int) – Limit-process paths for the p-values, at least500.grid (
int) – Points on which each path is simulated, at least100.seed (
int|Generator|None) – Seed or generator for the limit simulation.
- Return type:
- Returns:
The sup-Wald
BreakTest, withbreak_indexat the arg-max, exp- and ave-Wald ascompanions, and the Wald path over candidate dates inpath(nanoutside the window).- Raises:
SpecificationError – If the trend is unknown,
trimmingis outside(0, 0.5),n_drawsorgridis too small, or the window leaves no candidate date.DimensionError – If the regressors do not align with the target.
NumericalError – If a value is not finite or the design is rank deficient.
Note
Every coefficient is allowed to break at once; a partial break in a subset of coefficients is not offered. The common error variance means the test is for the coefficients, not the variance, and serially correlated or heteroskedastic errors are not corrected for: include the lags the dynamics call for in
exog, or read the result as a diagnostic. The three statistics share one limit simulation, so their p-values are computed from the same draws and are not independent evidence.See also
BreakTest– the record, and therejectthat reads the simulated p-value.bai_perron()– when more than one break is possible, and for a selection between counts.cusum()– a boundary test without a limit simulation.zivot_andrews()– a unit-root test that allows one break under the alternative.
References
Andrews, D. W. K. (1993). Tests for parameter instability and structural change with unknown change point. Econometrica, 61(4), 821-856.
Andrews, D. W. K. (2003). Tests for parameter instability and structural change with unknown change point: A corrigendum. Econometrica, 71(1), 395-397.
Andrews, D. W. K., & Ploberger, W. (1994). Optimal tests when a nuisance parameter is present only under the alternative. Econometrica, 62(6), 1383-1414.
Hansen, B. E. (1997). Approximate asymptotic p values for structural-change tests. Journal of Business & Economic Statistics, 15(1), 60-67.
Example
A mean shift at observation 100 is dated exactly, and the 5% critical value is Andrews’ to Monte Carlo error:
>>> import numpy as np >>> rng = np.random.default_rng(0) >>> y = np.concatenate([rng.standard_normal(100), 2.0 + rng.standard_normal(100)]) >>> test = sup_wald(y, seed=0) >>> test BreakTest(name='sup-Wald', statistic=187.9089, pvalue=0, break_index=100, nobs=200) >>> round(test.critical_values["5%"], 1) 8.6 >>> [(c.name, c.pvalue) for c in test.companions] [('exp-Wald', 0.0), ('ave-Wald', 0.0)]
A break in a slope, with the intercept and slope both allowed to change:
>>> x = rng.standard_normal(200) >>> y = 0.5 * x + rng.standard_normal(200) >>> y[100:] += 1.5 * x[100:] >>> test = sup_wald(y, exog=x, seed=0) >>> test.n_restrictions, test.reject(), 95 <= test.break_index <= 105 (2, True, True)