exact_local_whittle#

cultivars.diagnostics.long_memory.exact_local_whittle(endog, *, f_bandwidth=None, exponent=_WHITTLE_EXPONENT)[source]#

Shimotsu-Phillips exact local Whittle estimate of \(d\), valid for any \(d\).

The local Whittle objective is evaluated not on the periodogram of the series but on that of its fractional difference,

\[R(d) = \log\Bigl(\frac{1}{m} \sum_{j = 1}^{m} I_{\Delta^d (y - \hat\mu(d))}(\lambda_j)\Bigr) - \frac{2d}{m} \sum_{j = 1}^{m} \log \lambda_j,\]

where \(\Delta^d = (1 - L)^d\) is applied inside the objective for each trial \(d\). Differencing the series to short memory before reading its periodogram is what removes the \(d < 3/4\) restriction of local_whittle(): the limit \(\sqrt{m}(\hat d - d) \to \mathcal{N}(0, 1/4)\) then holds across the stationary and nonstationary ranges alike (Shimotsu & Phillips 2005). The mean correction \(\hat\mu(d)\) is Shimotsu’s (2010) weighted estimate, the sample mean for \(d \le 1/2\) and the first observation for \(d \ge 3/4\) with a smooth blend between, so a random walk is anchored at its start rather than at a mean it does not have. The search runs over \((-1/2, 2)\). This is the estimator for the question the ADF test cannot answer: whether a series that rejects nothing is \(d = 1\) or merely \(d = 0.7\).

Parameters:
  • endog (ArrayLike) – The series, (T,), at least 64 observations.

  • f_bandwidth (int | None) – Fourier frequencies used, at least 2 and at most T // 2; None applies the rule.

  • exponent (float) – Exponent of the rule m = floor(T ** exponent), in (0, 1); 0.65 by default.

Return type:

LongMemoryEstimate

Returns:

The LongMemoryEstimate, with method="exact_local_whittle", standard error \(1 / (2\sqrt{m})\), and the test against \(d = 0\).

Raises:
  • SpecificationError – If the series is shorter than 64, the bandwidth is below 2 or above the available frequencies, or the exponent is outside (0, 1).

  • NumericalError – If a value is not finite.

Note

The mean correction switches regime between \(1/2\) and \(3/4\), and the finite-sample coverage of the asymptotic interval is weakest there, in the low 80s at 500 observations against a nominal 95. Each trial \(d\) fractionally differences the whole series, so the call is slower than local_whittle() by the cost of the optimizer’s evaluations.

See also

  • local_whittle() – the same objective on the raw periodogram, faster, valid for \(d < 3/4\).

  • adf() – the integer question this estimator refines.

  • ARFIMA – the parametric alternative once \(d\) is in the

    stationary range.

References

Shimotsu, K., & Phillips, P. C. B. (2005). Exact local Whittle estimation of fractional integration. Annals of Statistics, 33(4), 1890-1933.

Shimotsu, K. (2010). Exact local Whittle estimation of fractional integration with unknown mean and time trend. Econometric Theory, 26(2), 501-540.

Example

A random walk is \(d = 1\), and the estimate keeps that null while rejecting no long memory:

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> walk = np.cumsum(rng.standard_normal(500))
>>> est = exact_local_whittle(walk)
>>> bool(abs(est.d - 1.0) < 3 * est.se), est.test(1.0).reject(), est.reject()
(True, False, True)

Where local_whittle() stops at its bound, this one reads past it:

>>> round(local_whittle(walk).d, 3), bool(est.d > 1.0)
(1.0, True)