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

1""" 

2Estimate autocovariances 

3 

4Barebones reimplementation of the `acovf` from `statsmodels.api.tsa.acovf`,  

5for use only with `scores.stats.test.diebold_mariano` 

6 

7Package: https://www.statsmodels.org/devel/ 

8 

9Code reference: https://github.com/statsmodels/statsmodels/blob/main/statsmodels/tsa/stattools.py 

10 

11Notes: 

12 All type checking and other features have been removed, as they aren't needed for the  

13 `diebold_mariano` function. 

14 

15Why: 

16 Reduce dependant packages 

17 

18## Source License 

19 

20Copyright (C) 2006, Jonathan E. Taylor 

21All rights reserved. 

22 

23Copyright (c) 2006-2008 Scipy Developers. 

24All rights reserved. 

25 

26Copyright (c) 2009-2018 statsmodels Developers. 

27All rights reserved. 

28 

29 

30Redistribution and use in source and binary forms, with or without 

31modification, are permitted provided that the following conditions are met: 

32 

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. 

41 

42 

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""" 

55 

56import numpy as np 

57 

58__all__ = ["acovf"] 

59 

60 

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. 

67 

68 Target must be a positive integer. 

69 """ 

70 if target <= 6: 

71 return target 

72 

73 # Quickly check if it's already a power of 2 

74 if not (target & (target - 1)): 

75 return target 

76 

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()) 

87 

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 

104 

105 

106def acovf(x): 

107 """ 

108 Estimate autocovariances. 

109 

110 Args: 

111 x (array_like): 

112 Time series data. Must be 1d. 

113 

114 Returns: 

115 (np.ndarray): 

116 The estimated autocovariances. 

117 

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 """ 

123 

124 xo = x - x.mean() 

125 

126 n = len(x) 

127 

128 d = n * np.ones(2 * n - 1) 

129 

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 

135 

136 return acov