helper.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. """
  2. Discrete Fourier Transforms - helper.py
  3. """
  4. from numpy.core import integer, empty, arange, asarray, roll
  5. from numpy.core.overrides import array_function_dispatch, set_module
  6. # Created by Pearu Peterson, September 2002
  7. __all__ = ['fftshift', 'ifftshift', 'fftfreq', 'rfftfreq']
  8. integer_types = (int, integer)
  9. def _fftshift_dispatcher(x, axes=None):
  10. return (x,)
  11. @array_function_dispatch(_fftshift_dispatcher, module='numpy.fft')
  12. def fftshift(x, axes=None):
  13. """
  14. Shift the zero-frequency component to the center of the spectrum.
  15. This function swaps half-spaces for all axes listed (defaults to all).
  16. Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even.
  17. Parameters
  18. ----------
  19. x : array_like
  20. Input array.
  21. axes : int or shape tuple, optional
  22. Axes over which to shift. Default is None, which shifts all axes.
  23. Returns
  24. -------
  25. y : ndarray
  26. The shifted array.
  27. See Also
  28. --------
  29. ifftshift : The inverse of `fftshift`.
  30. Examples
  31. --------
  32. >>> freqs = np.fft.fftfreq(10, 0.1)
  33. >>> freqs
  34. array([ 0., 1., 2., ..., -3., -2., -1.])
  35. >>> np.fft.fftshift(freqs)
  36. array([-5., -4., -3., -2., -1., 0., 1., 2., 3., 4.])
  37. Shift the zero-frequency component only along the second axis:
  38. >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
  39. >>> freqs
  40. array([[ 0., 1., 2.],
  41. [ 3., 4., -4.],
  42. [-3., -2., -1.]])
  43. >>> np.fft.fftshift(freqs, axes=(1,))
  44. array([[ 2., 0., 1.],
  45. [-4., 3., 4.],
  46. [-1., -3., -2.]])
  47. """
  48. x = asarray(x)
  49. if axes is None:
  50. axes = tuple(range(x.ndim))
  51. shift = [dim // 2 for dim in x.shape]
  52. elif isinstance(axes, integer_types):
  53. shift = x.shape[axes] // 2
  54. else:
  55. shift = [x.shape[ax] // 2 for ax in axes]
  56. return roll(x, shift, axes)
  57. @array_function_dispatch(_fftshift_dispatcher, module='numpy.fft')
  58. def ifftshift(x, axes=None):
  59. """
  60. The inverse of `fftshift`. Although identical for even-length `x`, the
  61. functions differ by one sample for odd-length `x`.
  62. Parameters
  63. ----------
  64. x : array_like
  65. Input array.
  66. axes : int or shape tuple, optional
  67. Axes over which to calculate. Defaults to None, which shifts all axes.
  68. Returns
  69. -------
  70. y : ndarray
  71. The shifted array.
  72. See Also
  73. --------
  74. fftshift : Shift zero-frequency component to the center of the spectrum.
  75. Examples
  76. --------
  77. >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
  78. >>> freqs
  79. array([[ 0., 1., 2.],
  80. [ 3., 4., -4.],
  81. [-3., -2., -1.]])
  82. >>> np.fft.ifftshift(np.fft.fftshift(freqs))
  83. array([[ 0., 1., 2.],
  84. [ 3., 4., -4.],
  85. [-3., -2., -1.]])
  86. """
  87. x = asarray(x)
  88. if axes is None:
  89. axes = tuple(range(x.ndim))
  90. shift = [-(dim // 2) for dim in x.shape]
  91. elif isinstance(axes, integer_types):
  92. shift = -(x.shape[axes] // 2)
  93. else:
  94. shift = [-(x.shape[ax] // 2) for ax in axes]
  95. return roll(x, shift, axes)
  96. @set_module('numpy.fft')
  97. def fftfreq(n, d=1.0):
  98. """
  99. Return the Discrete Fourier Transform sample frequencies.
  100. The returned float array `f` contains the frequency bin centers in cycles
  101. per unit of the sample spacing (with zero at the start). For instance, if
  102. the sample spacing is in seconds, then the frequency unit is cycles/second.
  103. Given a window length `n` and a sample spacing `d`::
  104. f = [0, 1, ..., n/2-1, -n/2, ..., -1] / (d*n) if n is even
  105. f = [0, 1, ..., (n-1)/2, -(n-1)/2, ..., -1] / (d*n) if n is odd
  106. Parameters
  107. ----------
  108. n : int
  109. Window length.
  110. d : scalar, optional
  111. Sample spacing (inverse of the sampling rate). Defaults to 1.
  112. Returns
  113. -------
  114. f : ndarray
  115. Array of length `n` containing the sample frequencies.
  116. Examples
  117. --------
  118. >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float)
  119. >>> fourier = np.fft.fft(signal)
  120. >>> n = signal.size
  121. >>> timestep = 0.1
  122. >>> freq = np.fft.fftfreq(n, d=timestep)
  123. >>> freq
  124. array([ 0. , 1.25, 2.5 , ..., -3.75, -2.5 , -1.25])
  125. """
  126. if not isinstance(n, integer_types):
  127. raise ValueError("n should be an integer")
  128. val = 1.0 / (n * d)
  129. results = empty(n, int)
  130. N = (n-1)//2 + 1
  131. p1 = arange(0, N, dtype=int)
  132. results[:N] = p1
  133. p2 = arange(-(n//2), 0, dtype=int)
  134. results[N:] = p2
  135. return results * val
  136. @set_module('numpy.fft')
  137. def rfftfreq(n, d=1.0):
  138. """
  139. Return the Discrete Fourier Transform sample frequencies
  140. (for usage with rfft, irfft).
  141. The returned float array `f` contains the frequency bin centers in cycles
  142. per unit of the sample spacing (with zero at the start). For instance, if
  143. the sample spacing is in seconds, then the frequency unit is cycles/second.
  144. Given a window length `n` and a sample spacing `d`::
  145. f = [0, 1, ..., n/2-1, n/2] / (d*n) if n is even
  146. f = [0, 1, ..., (n-1)/2-1, (n-1)/2] / (d*n) if n is odd
  147. Unlike `fftfreq` (but like `scipy.fftpack.rfftfreq`)
  148. the Nyquist frequency component is considered to be positive.
  149. Parameters
  150. ----------
  151. n : int
  152. Window length.
  153. d : scalar, optional
  154. Sample spacing (inverse of the sampling rate). Defaults to 1.
  155. Returns
  156. -------
  157. f : ndarray
  158. Array of length ``n//2 + 1`` containing the sample frequencies.
  159. Examples
  160. --------
  161. >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5, -3, 4], dtype=float)
  162. >>> fourier = np.fft.rfft(signal)
  163. >>> n = signal.size
  164. >>> sample_rate = 100
  165. >>> freq = np.fft.fftfreq(n, d=1./sample_rate)
  166. >>> freq
  167. array([ 0., 10., 20., ..., -30., -20., -10.])
  168. >>> freq = np.fft.rfftfreq(n, d=1./sample_rate)
  169. >>> freq
  170. array([ 0., 10., 20., 30., 40., 50.])
  171. """
  172. if not isinstance(n, integer_types):
  173. raise ValueError("n should be an integer")
  174. val = 1.0/(n*d)
  175. N = n//2 + 1
  176. results = arange(0, N, dtype=int)
  177. return results * val