basic.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. """
  2. Discrete Fourier Transforms - basic.py
  3. """
  4. # Created by Pearu Peterson, August,September 2002
  5. from __future__ import division, print_function, absolute_import
  6. __all__ = ['fft','ifft','fftn','ifftn','rfft','irfft',
  7. 'fft2','ifft2']
  8. from numpy import swapaxes, zeros
  9. import numpy
  10. from . import _fftpack
  11. from scipy.fftpack.helper import _init_nd_shape_and_axes_sorted
  12. import atexit
  13. atexit.register(_fftpack.destroy_zfft_cache)
  14. atexit.register(_fftpack.destroy_zfftnd_cache)
  15. atexit.register(_fftpack.destroy_drfft_cache)
  16. atexit.register(_fftpack.destroy_cfft_cache)
  17. atexit.register(_fftpack.destroy_cfftnd_cache)
  18. atexit.register(_fftpack.destroy_rfft_cache)
  19. del atexit
  20. def istype(arr, typeclass):
  21. return issubclass(arr.dtype.type, typeclass)
  22. def _datacopied(arr, original):
  23. """
  24. Strict check for `arr` not sharing any data with `original`,
  25. under the assumption that arr = asarray(original)
  26. """
  27. if arr is original:
  28. return False
  29. if not isinstance(original, numpy.ndarray) and hasattr(original, '__array__'):
  30. return False
  31. return arr.base is None
  32. # XXX: single precision FFTs partially disabled due to accuracy issues
  33. # for large prime-sized inputs.
  34. #
  35. # See http://permalink.gmane.org/gmane.comp.python.scientific.devel/13834
  36. # ("fftpack test failures for 0.8.0b1", Ralf Gommers, 17 Jun 2010,
  37. # @ scipy-dev)
  38. #
  39. # These should be re-enabled once the problems are resolved
  40. def _is_safe_size(n):
  41. """
  42. Is the size of FFT such that FFTPACK can handle it in single precision
  43. with sufficient accuracy?
  44. Composite numbers of 2, 3, and 5 are accepted, as FFTPACK has those
  45. """
  46. n = int(n)
  47. if n == 0:
  48. return True
  49. # Divide by 3 until you can't, then by 5 until you can't
  50. for c in (3, 5):
  51. while n % c == 0:
  52. n //= c
  53. # Return True if the remainder is a power of 2
  54. return not n & (n-1)
  55. def _fake_crfft(x, n, *a, **kw):
  56. if _is_safe_size(n):
  57. return _fftpack.crfft(x, n, *a, **kw)
  58. else:
  59. return _fftpack.zrfft(x, n, *a, **kw).astype(numpy.complex64)
  60. def _fake_cfft(x, n, *a, **kw):
  61. if _is_safe_size(n):
  62. return _fftpack.cfft(x, n, *a, **kw)
  63. else:
  64. return _fftpack.zfft(x, n, *a, **kw).astype(numpy.complex64)
  65. def _fake_rfft(x, n, *a, **kw):
  66. if _is_safe_size(n):
  67. return _fftpack.rfft(x, n, *a, **kw)
  68. else:
  69. return _fftpack.drfft(x, n, *a, **kw).astype(numpy.float32)
  70. def _fake_cfftnd(x, shape, *a, **kw):
  71. if numpy.all(list(map(_is_safe_size, shape))):
  72. return _fftpack.cfftnd(x, shape, *a, **kw)
  73. else:
  74. return _fftpack.zfftnd(x, shape, *a, **kw).astype(numpy.complex64)
  75. _DTYPE_TO_FFT = {
  76. # numpy.dtype(numpy.float32): _fftpack.crfft,
  77. numpy.dtype(numpy.float32): _fake_crfft,
  78. numpy.dtype(numpy.float64): _fftpack.zrfft,
  79. # numpy.dtype(numpy.complex64): _fftpack.cfft,
  80. numpy.dtype(numpy.complex64): _fake_cfft,
  81. numpy.dtype(numpy.complex128): _fftpack.zfft,
  82. }
  83. _DTYPE_TO_RFFT = {
  84. # numpy.dtype(numpy.float32): _fftpack.rfft,
  85. numpy.dtype(numpy.float32): _fake_rfft,
  86. numpy.dtype(numpy.float64): _fftpack.drfft,
  87. }
  88. _DTYPE_TO_FFTN = {
  89. # numpy.dtype(numpy.complex64): _fftpack.cfftnd,
  90. numpy.dtype(numpy.complex64): _fake_cfftnd,
  91. numpy.dtype(numpy.complex128): _fftpack.zfftnd,
  92. # numpy.dtype(numpy.float32): _fftpack.cfftnd,
  93. numpy.dtype(numpy.float32): _fake_cfftnd,
  94. numpy.dtype(numpy.float64): _fftpack.zfftnd,
  95. }
  96. def _asfarray(x):
  97. """Like numpy asfarray, except that it does not modify x dtype if x is
  98. already an array with a float dtype, and do not cast complex types to
  99. real."""
  100. if hasattr(x, "dtype") and x.dtype.char in numpy.typecodes["AllFloat"]:
  101. # 'dtype' attribute does not ensure that the
  102. # object is an ndarray (e.g. Series class
  103. # from the pandas library)
  104. if x.dtype == numpy.half:
  105. # no half-precision routines, so convert to single precision
  106. return numpy.asarray(x, dtype=numpy.float32)
  107. return numpy.asarray(x, dtype=x.dtype)
  108. else:
  109. # We cannot use asfarray directly because it converts sequences of
  110. # complex to sequence of real
  111. ret = numpy.asarray(x)
  112. if ret.dtype == numpy.half:
  113. return numpy.asarray(ret, dtype=numpy.float32)
  114. elif ret.dtype.char not in numpy.typecodes["AllFloat"]:
  115. return numpy.asfarray(x)
  116. return ret
  117. def _fix_shape(x, n, axis):
  118. """ Internal auxiliary function for _raw_fft, _raw_fftnd."""
  119. s = list(x.shape)
  120. if s[axis] > n:
  121. index = [slice(None)]*len(s)
  122. index[axis] = slice(0,n)
  123. x = x[tuple(index)]
  124. return x, False
  125. else:
  126. index = [slice(None)]*len(s)
  127. index[axis] = slice(0,s[axis])
  128. s[axis] = n
  129. z = zeros(s,x.dtype.char)
  130. z[tuple(index)] = x
  131. return z, True
  132. def _raw_fft(x, n, axis, direction, overwrite_x, work_function):
  133. """ Internal auxiliary function for fft, ifft, rfft, irfft."""
  134. if n is None:
  135. n = x.shape[axis]
  136. elif n != x.shape[axis]:
  137. x, copy_made = _fix_shape(x,n,axis)
  138. overwrite_x = overwrite_x or copy_made
  139. if n < 1:
  140. raise ValueError("Invalid number of FFT data points "
  141. "(%d) specified." % n)
  142. if axis == -1 or axis == len(x.shape)-1:
  143. r = work_function(x,n,direction,overwrite_x=overwrite_x)
  144. else:
  145. x = swapaxes(x, axis, -1)
  146. r = work_function(x,n,direction,overwrite_x=overwrite_x)
  147. r = swapaxes(r, axis, -1)
  148. return r
  149. def fft(x, n=None, axis=-1, overwrite_x=False):
  150. """
  151. Return discrete Fourier transform of real or complex sequence.
  152. The returned complex array contains ``y(0), y(1),..., y(n-1)`` where
  153. ``y(j) = (x * exp(-2*pi*sqrt(-1)*j*np.arange(n)/n)).sum()``.
  154. Parameters
  155. ----------
  156. x : array_like
  157. Array to Fourier transform.
  158. n : int, optional
  159. Length of the Fourier transform. If ``n < x.shape[axis]``, `x` is
  160. truncated. If ``n > x.shape[axis]``, `x` is zero-padded. The
  161. default results in ``n = x.shape[axis]``.
  162. axis : int, optional
  163. Axis along which the fft's are computed; the default is over the
  164. last axis (i.e., ``axis=-1``).
  165. overwrite_x : bool, optional
  166. If True, the contents of `x` can be destroyed; the default is False.
  167. Returns
  168. -------
  169. z : complex ndarray
  170. with the elements::
  171. [y(0),y(1),..,y(n/2),y(1-n/2),...,y(-1)] if n is even
  172. [y(0),y(1),..,y((n-1)/2),y(-(n-1)/2),...,y(-1)] if n is odd
  173. where::
  174. y(j) = sum[k=0..n-1] x[k] * exp(-sqrt(-1)*j*k* 2*pi/n), j = 0..n-1
  175. See Also
  176. --------
  177. ifft : Inverse FFT
  178. rfft : FFT of a real sequence
  179. Notes
  180. -----
  181. The packing of the result is "standard": If ``A = fft(a, n)``, then
  182. ``A[0]`` contains the zero-frequency term, ``A[1:n/2]`` contains the
  183. positive-frequency terms, and ``A[n/2:]`` contains the negative-frequency
  184. terms, in order of decreasingly negative frequency. So for an 8-point
  185. transform, the frequencies of the result are [0, 1, 2, 3, -4, -3, -2, -1].
  186. To rearrange the fft output so that the zero-frequency component is
  187. centered, like [-4, -3, -2, -1, 0, 1, 2, 3], use `fftshift`.
  188. Both single and double precision routines are implemented. Half precision
  189. inputs will be converted to single precision. Non floating-point inputs
  190. will be converted to double precision. Long-double precision inputs are
  191. not supported.
  192. This function is most efficient when `n` is a power of two, and least
  193. efficient when `n` is prime.
  194. Note that if ``x`` is real-valued then ``A[j] == A[n-j].conjugate()``.
  195. If ``x`` is real-valued and ``n`` is even then ``A[n/2]`` is real.
  196. If the data type of `x` is real, a "real FFT" algorithm is automatically
  197. used, which roughly halves the computation time. To increase efficiency
  198. a little further, use `rfft`, which does the same calculation, but only
  199. outputs half of the symmetrical spectrum. If the data is both real and
  200. symmetrical, the `dct` can again double the efficiency, by generating
  201. half of the spectrum from half of the signal.
  202. Examples
  203. --------
  204. >>> from scipy.fftpack import fft, ifft
  205. >>> x = np.arange(5)
  206. >>> np.allclose(fft(ifft(x)), x, atol=1e-15) # within numerical accuracy.
  207. True
  208. """
  209. tmp = _asfarray(x)
  210. try:
  211. work_function = _DTYPE_TO_FFT[tmp.dtype]
  212. except KeyError:
  213. raise ValueError("type %s is not supported" % tmp.dtype)
  214. if not (istype(tmp, numpy.complex64) or istype(tmp, numpy.complex128)):
  215. overwrite_x = 1
  216. overwrite_x = overwrite_x or _datacopied(tmp, x)
  217. if n is None:
  218. n = tmp.shape[axis]
  219. elif n != tmp.shape[axis]:
  220. tmp, copy_made = _fix_shape(tmp,n,axis)
  221. overwrite_x = overwrite_x or copy_made
  222. if n < 1:
  223. raise ValueError("Invalid number of FFT data points "
  224. "(%d) specified." % n)
  225. if axis == -1 or axis == len(tmp.shape) - 1:
  226. return work_function(tmp,n,1,0,overwrite_x)
  227. tmp = swapaxes(tmp, axis, -1)
  228. tmp = work_function(tmp,n,1,0,overwrite_x)
  229. return swapaxes(tmp, axis, -1)
  230. def ifft(x, n=None, axis=-1, overwrite_x=False):
  231. """
  232. Return discrete inverse Fourier transform of real or complex sequence.
  233. The returned complex array contains ``y(0), y(1),..., y(n-1)`` where
  234. ``y(j) = (x * exp(2*pi*sqrt(-1)*j*np.arange(n)/n)).mean()``.
  235. Parameters
  236. ----------
  237. x : array_like
  238. Transformed data to invert.
  239. n : int, optional
  240. Length of the inverse Fourier transform. If ``n < x.shape[axis]``,
  241. `x` is truncated. If ``n > x.shape[axis]``, `x` is zero-padded.
  242. The default results in ``n = x.shape[axis]``.
  243. axis : int, optional
  244. Axis along which the ifft's are computed; the default is over the
  245. last axis (i.e., ``axis=-1``).
  246. overwrite_x : bool, optional
  247. If True, the contents of `x` can be destroyed; the default is False.
  248. Returns
  249. -------
  250. ifft : ndarray of floats
  251. The inverse discrete Fourier transform.
  252. See Also
  253. --------
  254. fft : Forward FFT
  255. Notes
  256. -----
  257. Both single and double precision routines are implemented. Half precision
  258. inputs will be converted to single precision. Non floating-point inputs
  259. will be converted to double precision. Long-double precision inputs are
  260. not supported.
  261. This function is most efficient when `n` is a power of two, and least
  262. efficient when `n` is prime.
  263. If the data type of `x` is real, a "real IFFT" algorithm is automatically
  264. used, which roughly halves the computation time.
  265. Examples
  266. --------
  267. >>> from scipy.fftpack import fft, ifft
  268. >>> import numpy as np
  269. >>> x = np.arange(5)
  270. >>> np.allclose(ifft(fft(x)), x, atol=1e-15) # within numerical accuracy.
  271. True
  272. """
  273. tmp = _asfarray(x)
  274. try:
  275. work_function = _DTYPE_TO_FFT[tmp.dtype]
  276. except KeyError:
  277. raise ValueError("type %s is not supported" % tmp.dtype)
  278. if not (istype(tmp, numpy.complex64) or istype(tmp, numpy.complex128)):
  279. overwrite_x = 1
  280. overwrite_x = overwrite_x or _datacopied(tmp, x)
  281. if n is None:
  282. n = tmp.shape[axis]
  283. elif n != tmp.shape[axis]:
  284. tmp, copy_made = _fix_shape(tmp,n,axis)
  285. overwrite_x = overwrite_x or copy_made
  286. if n < 1:
  287. raise ValueError("Invalid number of FFT data points "
  288. "(%d) specified." % n)
  289. if axis == -1 or axis == len(tmp.shape) - 1:
  290. return work_function(tmp,n,-1,1,overwrite_x)
  291. tmp = swapaxes(tmp, axis, -1)
  292. tmp = work_function(tmp,n,-1,1,overwrite_x)
  293. return swapaxes(tmp, axis, -1)
  294. def rfft(x, n=None, axis=-1, overwrite_x=False):
  295. """
  296. Discrete Fourier transform of a real sequence.
  297. Parameters
  298. ----------
  299. x : array_like, real-valued
  300. The data to transform.
  301. n : int, optional
  302. Defines the length of the Fourier transform. If `n` is not specified
  303. (the default) then ``n = x.shape[axis]``. If ``n < x.shape[axis]``,
  304. `x` is truncated, if ``n > x.shape[axis]``, `x` is zero-padded.
  305. axis : int, optional
  306. The axis along which the transform is applied. The default is the
  307. last axis.
  308. overwrite_x : bool, optional
  309. If set to true, the contents of `x` can be overwritten. Default is
  310. False.
  311. Returns
  312. -------
  313. z : real ndarray
  314. The returned real array contains::
  315. [y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2))] if n is even
  316. [y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2)),Im(y(n/2))] if n is odd
  317. where::
  318. y(j) = sum[k=0..n-1] x[k] * exp(-sqrt(-1)*j*k*2*pi/n)
  319. j = 0..n-1
  320. See Also
  321. --------
  322. fft, irfft, numpy.fft.rfft
  323. Notes
  324. -----
  325. Within numerical accuracy, ``y == rfft(irfft(y))``.
  326. Both single and double precision routines are implemented. Half precision
  327. inputs will be converted to single precision. Non floating-point inputs
  328. will be converted to double precision. Long-double precision inputs are
  329. not supported.
  330. To get an output with a complex datatype, consider using the related
  331. function `numpy.fft.rfft`.
  332. Examples
  333. --------
  334. >>> from scipy.fftpack import fft, rfft
  335. >>> a = [9, -9, 1, 3]
  336. >>> fft(a)
  337. array([ 4. +0.j, 8.+12.j, 16. +0.j, 8.-12.j])
  338. >>> rfft(a)
  339. array([ 4., 8., 12., 16.])
  340. """
  341. tmp = _asfarray(x)
  342. if not numpy.isrealobj(tmp):
  343. raise TypeError("1st argument must be real sequence")
  344. try:
  345. work_function = _DTYPE_TO_RFFT[tmp.dtype]
  346. except KeyError:
  347. raise ValueError("type %s is not supported" % tmp.dtype)
  348. overwrite_x = overwrite_x or _datacopied(tmp, x)
  349. return _raw_fft(tmp,n,axis,1,overwrite_x,work_function)
  350. def irfft(x, n=None, axis=-1, overwrite_x=False):
  351. """
  352. Return inverse discrete Fourier transform of real sequence x.
  353. The contents of `x` are interpreted as the output of the `rfft`
  354. function.
  355. Parameters
  356. ----------
  357. x : array_like
  358. Transformed data to invert.
  359. n : int, optional
  360. Length of the inverse Fourier transform.
  361. If n < x.shape[axis], x is truncated.
  362. If n > x.shape[axis], x is zero-padded.
  363. The default results in n = x.shape[axis].
  364. axis : int, optional
  365. Axis along which the ifft's are computed; the default is over
  366. the last axis (i.e., axis=-1).
  367. overwrite_x : bool, optional
  368. If True, the contents of `x` can be destroyed; the default is False.
  369. Returns
  370. -------
  371. irfft : ndarray of floats
  372. The inverse discrete Fourier transform.
  373. See Also
  374. --------
  375. rfft, ifft, numpy.fft.irfft
  376. Notes
  377. -----
  378. The returned real array contains::
  379. [y(0),y(1),...,y(n-1)]
  380. where for n is even::
  381. y(j) = 1/n (sum[k=1..n/2-1] (x[2*k-1]+sqrt(-1)*x[2*k])
  382. * exp(sqrt(-1)*j*k* 2*pi/n)
  383. + c.c. + x[0] + (-1)**(j) x[n-1])
  384. and for n is odd::
  385. y(j) = 1/n (sum[k=1..(n-1)/2] (x[2*k-1]+sqrt(-1)*x[2*k])
  386. * exp(sqrt(-1)*j*k* 2*pi/n)
  387. + c.c. + x[0])
  388. c.c. denotes complex conjugate of preceding expression.
  389. For details on input parameters, see `rfft`.
  390. To process (conjugate-symmetric) frequency-domain data with a complex
  391. datatype, consider using the related function `numpy.fft.irfft`.
  392. Examples
  393. --------
  394. >>> from scipy.fftpack import rfft, irfft
  395. >>> a = [1.0, 2.0, 3.0, 4.0, 5.0]
  396. >>> irfft(a)
  397. array([ 2.6 , -3.16405192, 1.24398433, -1.14955713, 1.46962473])
  398. >>> irfft(rfft(a))
  399. array([1., 2., 3., 4., 5.])
  400. """
  401. tmp = _asfarray(x)
  402. if not numpy.isrealobj(tmp):
  403. raise TypeError("1st argument must be real sequence")
  404. try:
  405. work_function = _DTYPE_TO_RFFT[tmp.dtype]
  406. except KeyError:
  407. raise ValueError("type %s is not supported" % tmp.dtype)
  408. overwrite_x = overwrite_x or _datacopied(tmp, x)
  409. return _raw_fft(tmp,n,axis,-1,overwrite_x,work_function)
  410. def _raw_fftnd(x, s, axes, direction, overwrite_x, work_function):
  411. """Internal auxiliary function for fftnd, ifftnd."""
  412. noaxes = axes is None
  413. s, axes = _init_nd_shape_and_axes_sorted(x, s, axes)
  414. # No need to swap axes, array is in C order
  415. if noaxes:
  416. for ax in axes:
  417. x, copy_made = _fix_shape(x, s[ax], ax)
  418. overwrite_x = overwrite_x or copy_made
  419. return work_function(x, s, direction, overwrite_x=overwrite_x)
  420. # Swap the request axes, last first (i.e. First swap the axis which ends up
  421. # at -1, then at -2, etc...), such as the request axes on which the
  422. # operation is carried become the last ones
  423. for i in range(1, axes.size+1):
  424. x = numpy.swapaxes(x, axes[-i], -i)
  425. # We can now operate on the axes waxes, the p last axes (p = len(axes)), by
  426. # fixing the shape of the input array to 1 for any axis the fft is not
  427. # carried upon.
  428. waxes = list(range(x.ndim - axes.size, x.ndim))
  429. shape = numpy.ones(x.ndim)
  430. shape[waxes] = s
  431. for i in range(len(waxes)):
  432. x, copy_made = _fix_shape(x, s[i], waxes[i])
  433. overwrite_x = overwrite_x or copy_made
  434. r = work_function(x, shape, direction, overwrite_x=overwrite_x)
  435. # reswap in the reverse order (first axis first, etc...) to get original
  436. # order
  437. for i in range(len(axes), 0, -1):
  438. r = numpy.swapaxes(r, -i, axes[-i])
  439. return r
  440. def fftn(x, shape=None, axes=None, overwrite_x=False):
  441. """
  442. Return multidimensional discrete Fourier transform.
  443. The returned array contains::
  444. y[j_1,..,j_d] = sum[k_1=0..n_1-1, ..., k_d=0..n_d-1]
  445. x[k_1,..,k_d] * prod[i=1..d] exp(-sqrt(-1)*2*pi/n_i * j_i * k_i)
  446. where d = len(x.shape) and n = x.shape.
  447. Parameters
  448. ----------
  449. x : array_like
  450. The (n-dimensional) array to transform.
  451. shape : int or array_like of ints or None, optional
  452. The shape of the result. If both `shape` and `axes` (see below) are
  453. None, `shape` is ``x.shape``; if `shape` is None but `axes` is
  454. not None, then `shape` is ``scipy.take(x.shape, axes, axis=0)``.
  455. If ``shape[i] > x.shape[i]``, the i-th dimension is padded with zeros.
  456. If ``shape[i] < x.shape[i]``, the i-th dimension is truncated to
  457. length ``shape[i]``.
  458. If any element of `shape` is -1, the size of the corresponding
  459. dimension of `x` is used.
  460. axes : int or array_like of ints or None, optional
  461. The axes of `x` (`y` if `shape` is not None) along which the
  462. transform is applied.
  463. The default is over all axes.
  464. overwrite_x : bool, optional
  465. If True, the contents of `x` can be destroyed. Default is False.
  466. Returns
  467. -------
  468. y : complex-valued n-dimensional numpy array
  469. The (n-dimensional) DFT of the input array.
  470. See Also
  471. --------
  472. ifftn
  473. Notes
  474. -----
  475. If ``x`` is real-valued, then
  476. ``y[..., j_i, ...] == y[..., n_i-j_i, ...].conjugate()``.
  477. Both single and double precision routines are implemented. Half precision
  478. inputs will be converted to single precision. Non floating-point inputs
  479. will be converted to double precision. Long-double precision inputs are
  480. not supported.
  481. Examples
  482. --------
  483. >>> from scipy.fftpack import fftn, ifftn
  484. >>> y = (-np.arange(16), 8 - np.arange(16), np.arange(16))
  485. >>> np.allclose(y, fftn(ifftn(y)))
  486. True
  487. """
  488. return _raw_fftn_dispatch(x, shape, axes, overwrite_x, 1)
  489. def _raw_fftn_dispatch(x, shape, axes, overwrite_x, direction):
  490. tmp = _asfarray(x)
  491. try:
  492. work_function = _DTYPE_TO_FFTN[tmp.dtype]
  493. except KeyError:
  494. raise ValueError("type %s is not supported" % tmp.dtype)
  495. if not (istype(tmp, numpy.complex64) or istype(tmp, numpy.complex128)):
  496. overwrite_x = 1
  497. overwrite_x = overwrite_x or _datacopied(tmp, x)
  498. return _raw_fftnd(tmp, shape, axes, direction, overwrite_x, work_function)
  499. def ifftn(x, shape=None, axes=None, overwrite_x=False):
  500. """
  501. Return inverse multi-dimensional discrete Fourier transform.
  502. The sequence can be of an arbitrary type.
  503. The returned array contains::
  504. y[j_1,..,j_d] = 1/p * sum[k_1=0..n_1-1, ..., k_d=0..n_d-1]
  505. x[k_1,..,k_d] * prod[i=1..d] exp(sqrt(-1)*2*pi/n_i * j_i * k_i)
  506. where ``d = len(x.shape)``, ``n = x.shape``, and ``p = prod[i=1..d] n_i``.
  507. For description of parameters see `fftn`.
  508. See Also
  509. --------
  510. fftn : for detailed information.
  511. Examples
  512. --------
  513. >>> from scipy.fftpack import fftn, ifftn
  514. >>> import numpy as np
  515. >>> y = (-np.arange(16), 8 - np.arange(16), np.arange(16))
  516. >>> np.allclose(y, ifftn(fftn(y)))
  517. True
  518. """
  519. return _raw_fftn_dispatch(x, shape, axes, overwrite_x, -1)
  520. def fft2(x, shape=None, axes=(-2,-1), overwrite_x=False):
  521. """
  522. 2-D discrete Fourier transform.
  523. Return the two-dimensional discrete Fourier transform of the 2-D argument
  524. `x`.
  525. See Also
  526. --------
  527. fftn : for detailed information.
  528. """
  529. return fftn(x,shape,axes,overwrite_x)
  530. def ifft2(x, shape=None, axes=(-2,-1), overwrite_x=False):
  531. """
  532. 2-D discrete inverse Fourier transform of real or complex sequence.
  533. Return inverse two-dimensional discrete Fourier transform of
  534. arbitrary type sequence x.
  535. See `ifft` for more information.
  536. See also
  537. --------
  538. fft2, ifft
  539. """
  540. return ifftn(x,shape,axes,overwrite_x)