Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" 

2Discrete Fourier Transforms - helper.py 

3 

4""" 

5from numpy.compat import integer_types 

6from numpy.core import integer, empty, arange, asarray, roll 

7from numpy.core.overrides import array_function_dispatch, set_module 

8 

9# Created by Pearu Peterson, September 2002 

10 

11__all__ = ['fftshift', 'ifftshift', 'fftfreq', 'rfftfreq'] 

12 

13integer_types = integer_types + (integer,) 

14 

15 

16def _fftshift_dispatcher(x, axes=None): 

17 return (x,) 

18 

19 

20@array_function_dispatch(_fftshift_dispatcher, module='numpy.fft') 

21def fftshift(x, axes=None): 

22 """ 

23 Shift the zero-frequency component to the center of the spectrum. 

24 

25 This function swaps half-spaces for all axes listed (defaults to all). 

26 Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even. 

27 

28 Parameters 

29 ---------- 

30 x : array_like 

31 Input array. 

32 axes : int or shape tuple, optional 

33 Axes over which to shift. Default is None, which shifts all axes. 

34 

35 Returns 

36 ------- 

37 y : ndarray 

38 The shifted array. 

39 

40 See Also 

41 -------- 

42 ifftshift : The inverse of `fftshift`. 

43 

44 Examples 

45 -------- 

46 >>> freqs = np.fft.fftfreq(10, 0.1) 

47 >>> freqs 

48 array([ 0., 1., 2., ..., -3., -2., -1.]) 

49 >>> np.fft.fftshift(freqs) 

50 array([-5., -4., -3., -2., -1., 0., 1., 2., 3., 4.]) 

51 

52 Shift the zero-frequency component only along the second axis: 

53 

54 >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3) 

55 >>> freqs 

56 array([[ 0., 1., 2.], 

57 [ 3., 4., -4.], 

58 [-3., -2., -1.]]) 

59 >>> np.fft.fftshift(freqs, axes=(1,)) 

60 array([[ 2., 0., 1.], 

61 [-4., 3., 4.], 

62 [-1., -3., -2.]]) 

63 

64 """ 

65 x = asarray(x) 

66 if axes is None: 

67 axes = tuple(range(x.ndim)) 

68 shift = [dim // 2 for dim in x.shape] 

69 elif isinstance(axes, integer_types): 

70 shift = x.shape[axes] // 2 

71 else: 

72 shift = [x.shape[ax] // 2 for ax in axes] 

73 

74 return roll(x, shift, axes) 

75 

76 

77@array_function_dispatch(_fftshift_dispatcher, module='numpy.fft') 

78def ifftshift(x, axes=None): 

79 """ 

80 The inverse of `fftshift`. Although identical for even-length `x`, the 

81 functions differ by one sample for odd-length `x`. 

82 

83 Parameters 

84 ---------- 

85 x : array_like 

86 Input array. 

87 axes : int or shape tuple, optional 

88 Axes over which to calculate. Defaults to None, which shifts all axes. 

89 

90 Returns 

91 ------- 

92 y : ndarray 

93 The shifted array. 

94 

95 See Also 

96 -------- 

97 fftshift : Shift zero-frequency component to the center of the spectrum. 

98 

99 Examples 

100 -------- 

101 >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3) 

102 >>> freqs 

103 array([[ 0., 1., 2.], 

104 [ 3., 4., -4.], 

105 [-3., -2., -1.]]) 

106 >>> np.fft.ifftshift(np.fft.fftshift(freqs)) 

107 array([[ 0., 1., 2.], 

108 [ 3., 4., -4.], 

109 [-3., -2., -1.]]) 

110 

111 """ 

112 x = asarray(x) 

113 if axes is None: 

114 axes = tuple(range(x.ndim)) 

115 shift = [-(dim // 2) for dim in x.shape] 

116 elif isinstance(axes, integer_types): 

117 shift = -(x.shape[axes] // 2) 

118 else: 

119 shift = [-(x.shape[ax] // 2) for ax in axes] 

120 

121 return roll(x, shift, axes) 

122 

123 

124@set_module('numpy.fft') 

125def fftfreq(n, d=1.0): 

126 """ 

127 Return the Discrete Fourier Transform sample frequencies. 

128 

129 The returned float array `f` contains the frequency bin centers in cycles 

130 per unit of the sample spacing (with zero at the start). For instance, if 

131 the sample spacing is in seconds, then the frequency unit is cycles/second. 

132 

133 Given a window length `n` and a sample spacing `d`:: 

134 

135 f = [0, 1, ..., n/2-1, -n/2, ..., -1] / (d*n) if n is even 

136 f = [0, 1, ..., (n-1)/2, -(n-1)/2, ..., -1] / (d*n) if n is odd 

137 

138 Parameters 

139 ---------- 

140 n : int 

141 Window length. 

142 d : scalar, optional 

143 Sample spacing (inverse of the sampling rate). Defaults to 1. 

144 

145 Returns 

146 ------- 

147 f : ndarray 

148 Array of length `n` containing the sample frequencies. 

149 

150 Examples 

151 -------- 

152 >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float) 

153 >>> fourier = np.fft.fft(signal) 

154 >>> n = signal.size 

155 >>> timestep = 0.1 

156 >>> freq = np.fft.fftfreq(n, d=timestep) 

157 >>> freq 

158 array([ 0. , 1.25, 2.5 , ..., -3.75, -2.5 , -1.25]) 

159 

160 """ 

161 if not isinstance(n, integer_types): 

162 raise ValueError("n should be an integer") 

163 val = 1.0 / (n * d) 

164 results = empty(n, int) 

165 N = (n-1)//2 + 1 

166 p1 = arange(0, N, dtype=int) 

167 results[:N] = p1 

168 p2 = arange(-(n//2), 0, dtype=int) 

169 results[N:] = p2 

170 return results * val 

171 

172 

173@set_module('numpy.fft') 

174def rfftfreq(n, d=1.0): 

175 """ 

176 Return the Discrete Fourier Transform sample frequencies 

177 (for usage with rfft, irfft). 

178 

179 The returned float array `f` contains the frequency bin centers in cycles 

180 per unit of the sample spacing (with zero at the start). For instance, if 

181 the sample spacing is in seconds, then the frequency unit is cycles/second. 

182 

183 Given a window length `n` and a sample spacing `d`:: 

184 

185 f = [0, 1, ..., n/2-1, n/2] / (d*n) if n is even 

186 f = [0, 1, ..., (n-1)/2-1, (n-1)/2] / (d*n) if n is odd 

187 

188 Unlike `fftfreq` (but like `scipy.fftpack.rfftfreq`) 

189 the Nyquist frequency component is considered to be positive. 

190 

191 Parameters 

192 ---------- 

193 n : int 

194 Window length. 

195 d : scalar, optional 

196 Sample spacing (inverse of the sampling rate). Defaults to 1. 

197 

198 Returns 

199 ------- 

200 f : ndarray 

201 Array of length ``n//2 + 1`` containing the sample frequencies. 

202 

203 Examples 

204 -------- 

205 >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5, -3, 4], dtype=float) 

206 >>> fourier = np.fft.rfft(signal) 

207 >>> n = signal.size 

208 >>> sample_rate = 100 

209 >>> freq = np.fft.fftfreq(n, d=1./sample_rate) 

210 >>> freq 

211 array([ 0., 10., 20., ..., -30., -20., -10.]) 

212 >>> freq = np.fft.rfftfreq(n, d=1./sample_rate) 

213 >>> freq 

214 array([ 0., 10., 20., 30., 40., 50.]) 

215 

216 """ 

217 if not isinstance(n, integer_types): 

218 raise ValueError("n should be an integer") 

219 val = 1.0/(n*d) 

220 N = n//2 + 1 

221 results = arange(0, N, dtype=int) 

222 return results * val