Coverage for src/scores/stats/statistical_tests/acovf.py: 100%
40 statements
« prev ^ index » next coverage.py v7.3.2, created at 2024-02-28 12:51 +1100
« prev ^ index » next coverage.py v7.3.2, created at 2024-02-28 12:51 +1100
1"""
2Estimate autocovariances
4Barebones reimplementation of the `acovf` from `statsmodels.api.tsa.acovf`,
5for use only with `scores.stats.test.diebold_mariano`
7Package: https://www.statsmodels.org/devel/
9Code reference: https://github.com/statsmodels/statsmodels/blob/main/statsmodels/tsa/stattools.py
11Notes:
12 All type checking and other features have been removed, as they aren't needed for the
13 `diebold_mariano` function.
15Why:
16 Reduce dependant packages
18## Source License
20Copyright (C) 2006, Jonathan E. Taylor
21All rights reserved.
23Copyright (c) 2006-2008 Scipy Developers.
24All rights reserved.
26Copyright (c) 2009-2018 statsmodels Developers.
27All rights reserved.
30Redistribution and use in source and binary forms, with or without
31modification, are permitted provided that the following conditions are met:
33 a. Redistributions of source code must retain the above copyright notice,
34 this list of conditions and the following disclaimer.
35 b. Redistributions in binary form must reproduce the above copyright
36 notice, this list of conditions and the following disclaimer in the
37 documentation and/or other materials provided with the distribution.
38 c. Neither the name of statsmodels nor the names of its contributors
39 may be used to endorse or promote products derived from this software
40 without specific prior written permission.
43THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
44AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46ARE DISCLAIMED. IN NO EVENT SHALL STATSMODELS OR CONTRIBUTORS BE LIABLE FOR
47ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
49SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
50CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
53DAMAGE.
54"""
56import numpy as np
58__all__ = ["acovf"]
61def _next_regular(target):
62 """
63 Find the next regular number greater than or equal to target.
64 Regular numbers are composites of the prime factors 2, 3, and 5.
65 Also known as 5-smooth numbers or Hamming numbers, these are the optimal
66 size for inputs to FFTPACK.
68 Target must be a positive integer.
69 """
70 if target <= 6:
71 return target
73 # Quickly check if it's already a power of 2
74 if not (target & (target - 1)):
75 return target
77 match = float("inf") # Anything found will be smaller
78 p5 = 1
79 while p5 < target:
80 p35 = p5
81 while p35 < target:
82 # Ceiling integer division, avoiding conversion to float
83 # (quotient = ceil(target / p35))
84 quotient = -(-target // p35)
85 # Quickly find next power of 2 >= quotient
86 p2 = 2 ** ((quotient - 1).bit_length())
88 N = p2 * p35
89 if N == target:
90 return N
91 elif N < match:
92 match = N
93 p35 *= 3
94 if p35 == target:
95 return p35
96 if p35 < match:
97 match = p35
98 p5 *= 5
99 if p5 == target:
100 return p5
101 if p5 < match:
102 match = p5
103 return match
106def acovf(x):
107 """
108 Estimate autocovariances.
110 Args:
111 x (array_like):
112 Time series data. Must be 1d.
114 Returns:
115 (np.ndarray):
116 The estimated autocovariances.
118 References:
119 [1] Parzen, E., 1963. On spectral analysis with missing observations
120 and amplitude modulation. Sankhya: The Indian Journal of
121 Statistics, Series A, pp.383-392.
122 """
124 xo = x - x.mean()
126 n = len(x)
128 d = n * np.ones(2 * n - 1)
130 nobs = len(xo)
131 n = _next_regular(2 * nobs + 1)
132 Frf = np.fft.fft(xo, n=n)
133 acov = np.fft.ifft(Frf * np.conjugate(Frf))[:nobs] / d[nobs - 1 :]
134 acov = acov.real
136 return acov