fft.py 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669
  1. # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from typing import Sequence
  15. import numpy as np
  16. import paddle
  17. from . import _C_ops
  18. from .base.data_feeder import check_variable_and_dtype
  19. from .base.layer_helper import LayerHelper
  20. from .framework import in_dynamic_or_pir_mode
  21. from .tensor.attribute import is_floating_point, is_integer
  22. from .tensor.creation import _complex_to_real_dtype, _real_to_complex_dtype
  23. __all__ = [
  24. 'fft',
  25. 'ifft',
  26. 'rfft',
  27. 'irfft',
  28. 'hfft',
  29. 'ihfft',
  30. 'fft2',
  31. 'ifft2',
  32. 'rfft2',
  33. 'irfft2',
  34. 'hfft2',
  35. 'ihfft2',
  36. 'fftn',
  37. 'ifftn',
  38. 'rfftn',
  39. 'irfftn',
  40. 'hfftn',
  41. 'ihfftn',
  42. 'fftfreq',
  43. 'rfftfreq',
  44. 'fftshift',
  45. 'ifftshift',
  46. ]
  47. def _check_normalization(norm):
  48. if norm not in ['forward', 'backward', 'ortho']:
  49. raise ValueError(
  50. f"Unexpected norm: {norm}. Norm should be forward, backward or ortho"
  51. )
  52. def _check_fft_n(n):
  53. if not isinstance(n, int):
  54. raise ValueError(
  55. f"Invalid FFT argument n({n}), it should be an integer."
  56. )
  57. if n <= 0:
  58. raise ValueError(f"Invalid FFT argument n({n}), it should be positive.")
  59. def _check_fft_shape(x, s):
  60. ndim = x.ndim
  61. if not isinstance(s, Sequence):
  62. raise ValueError(
  63. "Invalid FFT argument s({}), it should be a sequence of integers."
  64. )
  65. if len(s) > ndim:
  66. raise ValueError(
  67. "Length of FFT argument s should not be larger than the rank of input. "
  68. f"Received s: {s}, rank of x: {ndim}"
  69. )
  70. for size in s:
  71. if not isinstance(size, int) or size <= 0:
  72. raise ValueError(f"FFT sizes {s} contains invalid value ({size})")
  73. def _check_fft_axis(x, axis):
  74. ndim = x.ndim
  75. if not isinstance(axis, int):
  76. raise ValueError(f"Invalid FFT axis ({axis}), it should be an integer.")
  77. if axis < -ndim or axis >= ndim:
  78. raise ValueError(
  79. f"Invalid FFT axis ({axis}), it should be in range [-{ndim}, {ndim})"
  80. )
  81. def _check_fft_axes(x, axes):
  82. ndim = x.ndim
  83. if not isinstance(axes, Sequence):
  84. raise ValueError(
  85. f"Invalid FFT axes ({axes}), it should be a sequence of integers."
  86. )
  87. if len(axes) > ndim:
  88. raise ValueError(
  89. "Length of fft axes should not be larger than the rank of input. "
  90. f"Received, len of axes: {len(axes)}, rank of x: {ndim}"
  91. )
  92. for axis in axes:
  93. if not isinstance(axis, int) or axis < -ndim or axis >= ndim:
  94. raise ValueError(
  95. f"FFT axes {axes} contains invalid value ({axis}), it should be in range [-{ndim}, {ndim})"
  96. )
  97. def _resize_fft_input(x, s, axes):
  98. if len(s) != len(axes):
  99. raise ValueError("length of `s` should equals length of `axes`.")
  100. shape = x.shape
  101. ndim = x.ndim
  102. axes_to_pad = []
  103. paddings = []
  104. axes_to_slice = []
  105. slices = []
  106. for i, axis in enumerate(axes):
  107. if shape[axis] < s[i]:
  108. axes_to_pad.append(axis)
  109. paddings.append(s[i] - shape[axis])
  110. elif shape[axis] > s[i]:
  111. axes_to_slice.append(axis)
  112. slices.append((0, s[i]))
  113. if axes_to_slice:
  114. x = paddle.slice(
  115. x,
  116. axes_to_slice,
  117. starts=[item[0] for item in slices],
  118. ends=[item[1] for item in slices],
  119. )
  120. if axes_to_pad:
  121. padding_widths = [0] * (2 * ndim)
  122. for axis, pad in zip(axes_to_pad, paddings):
  123. padding_widths[2 * axis + 1] = pad
  124. x = paddle.nn.functional.pad(x, padding_widths)
  125. return x
  126. def _normalize_axes(x, axes):
  127. ndim = x.ndim
  128. return [item if item >= 0 else (item + ndim) for item in axes]
  129. def _check_at_least_ndim(x, rank):
  130. if x.ndim < rank:
  131. raise ValueError(f"The rank of the input ({x.ndim}) should >= {rank}")
  132. # public APIs 1d
  133. def fft(x, n=None, axis=-1, norm="backward", name=None):
  134. """
  135. Calculate one-dimensional discrete Fourier transform.
  136. This function uses the efficient fast Fourier transform (FFT) algorithm [1] to
  137. calculate the 1-D * n * point discrete Fourier transform (DFT).
  138. Args:
  139. x (Tensor): The input data. It's a Tensor type. It's a complex.
  140. n (int, optional): The length of the output transform axis. If `n` is less than
  141. the length input, the input will be cropped. If larger, the input is filled
  142. with zeros. If `n` is not given, the input length along the axis specified
  143. by `axis` is used.
  144. axis (int, optional): Axis used to calculate FFT. If not specified, the last axis
  145. is used by default.
  146. norm (str, optional): Indicates which direction to scale the `forward` or `backward` transform
  147. pair and what normalization factor to use. The parameter value must be one
  148. of "forward" or "backward" or "ortho". Default is "backward", meaning no normalization on
  149. the forward transforms and scaling by ``1/n`` on the `ifft`. "forward" instead applies
  150. the ``1/n`` factor on the forward transform. For ``norm="ortho"``, both directions are
  151. scaled by ``1/sqrt(n)``.
  152. name (str, optional): The default value is None. Normally there is no need for user to set
  153. this property. For more information, please refer to :ref:`api_guide_Name`.
  154. Returns:
  155. complex tensor. The truncated or zero-padded input, transformed along the axis indicated
  156. by `axis`, or the last one if `axis` is not specified.
  157. Examples:
  158. .. code-block:: python
  159. >>> import numpy as np
  160. >>> import paddle
  161. >>> x = np.exp(3j * np.pi * np.arange(7) / 7)
  162. >>> xp = paddle.to_tensor(x)
  163. >>> fft_xp = paddle.fft.fft(xp).numpy().round(3)
  164. >>> print(fft_xp)
  165. [1.+1.254j 1.+4.381j 1.-4.381j 1.-1.254j 1.-0.482j 1.+0.j 1.+0.482j]
  166. """
  167. if is_integer(x) or is_floating_point(x):
  168. return fft_r2c(
  169. x, n, axis, norm, forward=True, onesided=False, name=name
  170. )
  171. else:
  172. return fft_c2c(x, n, axis, norm, forward=True, name=name)
  173. def ifft(x, n=None, axis=-1, norm="backward", name=None):
  174. """
  175. Compute the 1-D inverse discrete Fourier Transform.
  176. This function computes the inverse of the 1-D *n*-point discrete Fourier transform
  177. computed by `fft`. In other words, ``ifft(fft(x)) == x`` to within numerical accuracy.
  178. The input should be ordered in the same way as is returned by `fft`,
  179. i.e.,
  180. * ``x[0]`` should contain the zero frequency term,
  181. * ``x[1:n//2]`` should contain the positive-frequency terms,
  182. * ``x[n//2 + 1:]`` should contain the negative-frequency terms, in
  183. increasing order starting from the most negative frequency.
  184. For an even number of input points, ``x[n//2]`` represents the sum of
  185. the values at the positive and negative Nyquist frequencies, as the two
  186. are aliased together.
  187. Args:
  188. x (Tensor): The input data. It's a Tensor type. It's a complex.
  189. n (int, optional): The length of the output transform axis. If `n` is less than
  190. the length input, the input will be cropped. If larger, the input is filled
  191. with zeros. If `n` is not given, the input length along the axis specified
  192. by `axis` is used.
  193. axis (int, optional): Axis used to calculate FFT. If not specified, the last axis
  194. is used by default.
  195. norm (str, optional): Indicates which direction to scale the `forward` or `backward` transform
  196. pair and what normalization factor to use. The parameter value must be one
  197. of "forward" or "backward" or "ortho". Default is "backward", meaning no normalization on
  198. the forward transforms and scaling by ``1/n`` on the `ifft`. "forward" instead applies
  199. the ``1/n`` factor on the forward transform. For ``norm="ortho"``, both directions are
  200. scaled by ``1/sqrt(n)``.
  201. name (str, optional): The default value is None. Normally there is no need for user to set
  202. this property. For more information, please refer to :ref:`api_guide_Name`.
  203. Returns:
  204. complex tensor. The truncated or zero-padded input, transformed along the axis indicated
  205. by `axis`, or the last one if `axis` is not specified.
  206. Examples:
  207. .. code-block:: python
  208. >>> import numpy as np
  209. >>> import paddle
  210. >>> x = np.exp(3j * np.pi * np.arange(7) / 7)
  211. >>> xp = paddle.to_tensor(x)
  212. >>> ifft_xp = paddle.fft.ifft(xp).numpy().round(3)
  213. >>> print(ifft_xp)
  214. [0.143+0.179j 0.143+0.069j 0.143+0.j 0.143-0.069j 0.143-0.179j 0.143-0.626j 0.143+0.626j]
  215. """
  216. if is_integer(x) or is_floating_point(x):
  217. return fft_r2c(
  218. x, n, axis, norm, forward=False, onesided=False, name=name
  219. )
  220. else:
  221. return fft_c2c(x, n, axis, norm, forward=False, name=name)
  222. def rfft(x, n=None, axis=-1, norm="backward", name=None):
  223. """
  224. The one dimensional FFT for real input.
  225. This function computes the one dimensional *n*-point discrete Fourier
  226. Transform (DFT) of a real-valued tensor by means of an efficient algorithm
  227. called the Fast Fourier Transform (FFT).
  228. When the DFT is computed for purely real input, the output is
  229. Hermitian-symmetric. This function does not compute the negative frequency
  230. terms, and the length of the transformed axis of the output is therefore
  231. ``n//2 + 1``.
  232. Args:
  233. x(Tensor) : Real-valued input tensor
  234. n(int, optional): Number of points along transformation axis in the
  235. input to use. If `n` is smaller than the length of the input, the
  236. input is cropped. If it is larger, the input is padded with zeros.
  237. If `n` is not given, the length of the input along the axis
  238. specified by `axis` is used.
  239. axis(int, optional): Axis over which to compute the FFT. Default value
  240. is last axis.
  241. norm(str, optional) : Normalization mode, indicates which direction of
  242. the forward/backward pair of transforms is scaled and with what
  243. normalization factor. Include {"backward", "ortho", "forward"},
  244. default value is "backward".
  245. - "backward": The factor of forward direction and backward direction are ``1`` and ``1/n`` respectively;
  246. - "forward": The factor of forward direction and backward direction are ``1/n`` and ``1`` respectively;
  247. - "ortho": The factor of forward direction and backward direction are both ``1/sqrt(n)``.
  248. Where ``n`` is the multiplication of each element in ``s`` .
  249. name(str, optional): The default value is None. Normally there is no
  250. need for user to set this property. For more information, please
  251. refer to :ref:`api_guide_Name` .
  252. Returns:
  253. out(Tensor) : complex tensor
  254. Examples:
  255. .. code-block:: python
  256. >>> import paddle
  257. >>> x = paddle.to_tensor([0.0, 1.0, 0.0, 0.0])
  258. >>> print(paddle.fft.rfft(x))
  259. Tensor(shape=[3], dtype=complex64, place=Place(cpu), stop_gradient=True,
  260. [(1+0j), -1j, (-1+0j)])
  261. """
  262. return fft_r2c(x, n, axis, norm, forward=True, onesided=True, name=name)
  263. def irfft(x, n=None, axis=-1, norm="backward", name=None):
  264. """
  265. Computes the inverse of `rfft`.
  266. This function calculates the inverse of the one-dimensional *n* point discrete
  267. Fourier transform of the actual input calculated by "rfft". In other words,
  268. ``irfft(rfft(a),len(a)) == a`` is within the numerical accuracy range.
  269. The input shall be in the form of "rfft", i.e. the actual zero frequency term,
  270. followed by the complex positive frequency term, in the order of increasing frequency.
  271. Because the discrete Fourier transform of the actual input is Hermite symmetric,
  272. the negative frequency term is regarded as the complex conjugate term of the corresponding
  273. positive frequency term.
  274. Args:
  275. x (Tensor): The input data. It's a Tensor type. It's a complex.
  276. n (int, optional): The length of the output transform axis. For `n` output
  277. points, ``n//2 + 1``input points are necessary. If the length of the input tensor is greater
  278. than `n`, it will be cropped, if it is shorter than this, fill in zero. If `n` is not given,
  279. it is considered to be ``2 * (k-1)``, where ``k`` is the length of the input axis specified
  280. along the ` axis'.
  281. axis (int, optional): Axis used to calculate FFT. If not specified, the last axis
  282. is used by default.
  283. norm (str, optional): Indicates which direction to scale the `forward` or `backward` transform
  284. pair and what normalization factor to use. The parameter value must be one
  285. of "forward" or "backward" or "ortho". Default is "backward".
  286. name (str, optional): The default value is None. Normally there is no need for user to set
  287. this property. For more information, please refer to :ref:`api_guide_Name` .
  288. Returns:
  289. Real tensor. Truncated or zero fill input for the transformation along the axis indicated by
  290. `axis`, or the last input if `axis` is not specified. The length of the conversion axis
  291. is `n`, or ``2 * k-2``, if `k` is None, where `k` is the length of the input conversion axis.
  292. If the output is an odd number, you need to specify the value of 'n', such as ``2 * k-1``
  293. in some cases.
  294. Examples:
  295. .. code-block:: python
  296. >>> import paddle
  297. >>> x = paddle.to_tensor([1, -1j, -1])
  298. >>> irfft_x = paddle.fft.irfft(x)
  299. >>> print(irfft_x)
  300. Tensor(shape=[4], dtype=float32, place=Place(cpu), stop_gradient=True,
  301. [0., 1., 0., 0.])
  302. """
  303. return fft_c2r(x, n, axis, norm, forward=False, name=name)
  304. def hfft(x, n=None, axis=-1, norm="backward", name=None):
  305. """
  306. Compute the FFT of a signal that has Hermitian symmetry, a real
  307. spectrum.
  308. Args:
  309. x (Tensor): The input data. It's a Tensor type. It's a complex.
  310. n (int, optional): The length of the output transform axis. For `n` output
  311. points, ``n//2 + 1`` input points are necessary. If the length of the input tensor is greater
  312. than `n`, it will be cropped, if it is shorter than this, fill in zero. If `n` is not given,
  313. it is considered to be ``2 * (k-1)``, where ``k`` is the length of the input axis specified
  314. along the ` axis'.
  315. axis (int,optional): Axis used to calculate FFT. If not specified, the last axis
  316. is used by default.
  317. norm (str, optional): Indicates which direction to scale the `forward` or `backward` transform
  318. pair and what normalization factor to use. The parameter value must be one
  319. of "forward" or "backward" or "ortho". Default is "backward".
  320. name (str, optional): The default value is None. Normally there is no need for user to set
  321. this property. For more information, please refer to :ref:`api_guide_Name` .
  322. Returns:
  323. Real tensor. Truncated or zero fill input for the transformation along the axis indicated by
  324. `axis`, or the last input if `axis` is not specified. The length of the conversion axis
  325. is `n`, or ``2 * k-2``, if `k` is None, where `k` is the length of the input conversion axis.
  326. If the output is an odd number, you need to specify the value of 'n', such as ``2 * k-1`` in
  327. some cases.
  328. Examples:
  329. .. code-block:: python
  330. >>> import paddle
  331. >>> x = paddle.to_tensor([1, -1j, -1])
  332. >>> hfft_x = paddle.fft.hfft(x)
  333. >>> print(hfft_x)
  334. Tensor(shape=[4], dtype=float32, place=Place(cpu), stop_gradient=True,
  335. [0., 0., 0., 4.])
  336. """
  337. return fft_c2r(x, n, axis, norm, forward=True, name=name)
  338. def ihfft(x, n=None, axis=-1, norm="backward", name=None):
  339. """
  340. The inverse FFT of a signal that has Hermitian symmetry.
  341. This function computes the one dimensional *n*-point inverse FFT of a signal
  342. that has Hermitian symmetry by means of an efficient algorithm called
  343. the Fast Fourier Transform (FFT).
  344. When the DFT is computed for purely real input, the output is
  345. Hermitian-symmetric. This function does not compute the negative frequency
  346. terms, and the length of the transformed axis of the output is therefore
  347. ``n//2 + 1``.
  348. Args:
  349. x(Tensor): Input tensor.
  350. n(int, optional): The number of points along transformation axis in the
  351. input to use. If `n` is smaller than the length of the input, the
  352. input is cropped. If it is larger, the input is padded with zeros.
  353. If `n` is not given, the length of the input along the axis
  354. specified by `axis` is used.
  355. axis(int, optional) : Axis over which to compute the inverse FFT. If not
  356. given, the last axis is used.
  357. norm(str, optional) : Normalization mode, indicates which direction of
  358. the forward/backward pair of transforms is scaled and with what
  359. normalization factor. Include {"backward", "ortho", "forward"},
  360. default value is "backward".
  361. name(str, optional): The default value is None. Normally there is no
  362. need for user to set this property. For more information, please
  363. refer to :ref:`api_guide_Name` .
  364. Returns:
  365. out(Tensor) : complex tensor.
  366. Examples:
  367. .. code-block:: python
  368. >>> import paddle
  369. >>> spectrum = paddle.to_tensor([10.0, -5.0, 0.0, -1.0, 0.0, -5.0])
  370. >>> print(paddle.fft.ifft(spectrum))
  371. Tensor(shape=[6], dtype=complex64, place=Place(cpu), stop_gradient=True,
  372. [(-0.1666666716337204+0j), (1-0j),
  373. (2.3333334922790527-0j), (3.5+0j),
  374. (2.3333334922790527+0j), (1+0j)])
  375. >>> print(paddle.fft.ihfft(spectrum))
  376. Tensor(shape=[4], dtype=complex64, place=Place(cpu), stop_gradient=True,
  377. [(-0.1666666716337204+0j), (1-0j),
  378. (2.3333334922790527-0j), (3.5+0j)])
  379. """
  380. return fft_r2c(x, n, axis, norm, forward=False, onesided=True, name=name)
  381. # public APIs nd
  382. def fftn(x, s=None, axes=None, norm="backward", name=None):
  383. """
  384. Compute the N-D discrete Fourier Transform.
  385. This function calculates the n-D discrete Fourier transform on any number of axes
  386. in the M-D array by fast Fourier transform (FFT).
  387. Args:
  388. x (Tensor): The input data. It's a Tensor type. It's a complex.
  389. s (sequence of ints, optional): Shape (length of each transformed axis) of the output
  390. (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.).
  391. This corresponds to ``n`` for ``fft(x, n)``.
  392. Along any axis, if the given shape is smaller than that of the input,
  393. the input is cropped. If it is larger, the input is padded with zeros.
  394. if `s` is not given, the shape of the input along the axes specified
  395. by `axes` is used.
  396. axes (sequence of ints, optional): Axes used to calculate FFT. If not given, the last ``len(s)``
  397. axes are used, or all axes if `s` is also not specified.
  398. norm (str, optional): Indicates which direction to scale the `forward` or `backward` transform
  399. pair and what normalization factor to use. The parameter value must be one
  400. of "forward" or "backward" or "ortho". Default is "backward", meaning no normalization on
  401. the forward transforms and scaling by ``1/n`` on the `ifft`. "forward" instead applies
  402. the ``1/n`` factor on the forward transform. For ``norm="ortho"``, both directions are
  403. scaled by ``1/sqrt(n)``.
  404. name (str, optional): The default value is None. Normally there is no need for user to set
  405. this property. For more information, please refer to :ref:`api_guide_Name`.
  406. Returns:
  407. complex tensor. The truncated or zero-padded input, transformed along the axes indicated by
  408. `axes`, or by a combination of `s` and `x`, as explained in the parameters section above.
  409. Examples:
  410. .. code-block:: python
  411. >>> import paddle
  412. >>> arr = paddle.arange(4, dtype="float64")
  413. >>> x = paddle.meshgrid(arr, arr, arr)[1]
  414. >>> fftn_xp = paddle.fft.fftn(x, axes=(1, 2))
  415. >>> print(fftn_xp)
  416. Tensor(shape=[4, 4, 4], dtype=complex128, place=Place(cpu), stop_gradient=True,
  417. [[[(24+0j), 0j, 0j, -0j],
  418. [(-8+8j), 0j, 0j, -0j],
  419. [(-8+0j), 0j, 0j, -0j],
  420. [(-8-8j), 0j, 0j, -0j]],
  421. [[(24+0j), 0j, 0j, -0j],
  422. [(-8+8j), 0j, 0j, -0j],
  423. [(-8+0j), 0j, 0j, -0j],
  424. [(-8-8j), 0j, 0j, -0j]],
  425. [[(24+0j), 0j, 0j, -0j],
  426. [(-8+8j), 0j, 0j, -0j],
  427. [(-8+0j), 0j, 0j, -0j],
  428. [(-8-8j), 0j, 0j, -0j]],
  429. [[(24+0j), 0j, 0j, -0j],
  430. [(-8+8j), 0j, 0j, -0j],
  431. [(-8+0j), 0j, 0j, -0j],
  432. [(-8-8j), 0j, 0j, -0j]]])
  433. """
  434. if is_integer(x) or is_floating_point(x):
  435. return fftn_r2c(
  436. x, s, axes, norm, forward=True, onesided=False, name=name
  437. )
  438. else:
  439. return fftn_c2c(x, s, axes, norm, forward=True, name=name)
  440. def ifftn(x, s=None, axes=None, norm="backward", name=None):
  441. """
  442. Compute the N-D inverse discrete Fourier Transform.
  443. This function computes the inverse of the N-D discrete
  444. Fourier Transform over any number of axes in an M-D array by
  445. means of the Fast Fourier Transform (FFT). In other words,
  446. ``ifftn(fftn(x)) == x`` to within numerical accuracy.
  447. The input, analogously to `ifft`, should be ordered in the same way as is
  448. returned by `fftn`, i.e., it should have the term for zero frequency
  449. in all axes in the low-order corner, the positive frequency terms in the
  450. first half of all axes, the term for the Nyquist frequency in the middle
  451. of all axes and the negative frequency terms in the second half of all
  452. axes, in order of decreasingly negative frequency.
  453. Args:
  454. x (Tensor): The input data. It's a Tensor type. It's a complex.
  455. s (sequence of ints, optional): Shape (length of each transformed axis) of the output
  456. (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.).
  457. This corresponds to ``n`` for ``fft(x, n)``.
  458. Along any axis, if the given shape is smaller than that of the input,
  459. the input is cropped. If it is larger, the input is padded with zeros.
  460. if `s` is not given, the shape of the input along the axes specified
  461. by `axes` is used.
  462. axes (sequence of ints, optional): Axes used to calculate FFT. If not given, the last ``len(s)``
  463. axes are used, or all axes if `s` is also not specified.
  464. norm (str, optional): Indicates which direction to scale the `forward` or `backward` transform
  465. pair and what normalization factor to use. The parameter value must be one
  466. of "forward" or "backward" or "ortho". Default is "backward", meaning no normalization on
  467. the forward transforms and scaling by ``1/n`` on the `ifft`. "forward" instead applies
  468. the ``1/n`` factor on the forward transform. For ``norm="ortho"``, both directions are
  469. scaled by ``1/sqrt(n)``.
  470. name (str, optional): The default value is None. Normally there is no need for user to set
  471. this property. For more information, please refer to :ref:`api_guide_Name`.
  472. Returns:
  473. complex tensor. The truncated or zero-padded input, transformed along the axes indicated by
  474. `axes`, or by a combination of `s` and `x`, as explained in the parameters section above.
  475. Examples:
  476. .. code-block:: python
  477. >>> import paddle
  478. >>> x = paddle.eye(3)
  479. >>> ifftn_x = paddle.fft.ifftn(x, axes=(1,))
  480. >>> print(ifftn_x)
  481. Tensor(shape=[3, 3], dtype=complex64, place=Place(cpu), stop_gradient=True,
  482. [[(0.3333333432674408+0j),
  483. (0.3333333432674408-0j),
  484. (0.3333333432674408+0j)],
  485. [(0.3333333432674408+0j),
  486. (-0.1666666716337204+0.28867512941360474j),
  487. (-0.1666666716337204-0.28867512941360474j)],
  488. [(0.3333333432674408+0j),
  489. (-0.1666666716337204-0.28867512941360474j),
  490. (-0.1666666716337204+0.28867512941360474j)]])
  491. """
  492. if is_integer(x) or is_floating_point(x):
  493. return fftn_r2c(
  494. x, s, axes, norm, forward=False, onesided=False, name=name
  495. )
  496. else:
  497. return fftn_c2c(x, s, axes, norm, forward=False, name=name)
  498. def rfftn(x, s=None, axes=None, norm="backward", name=None):
  499. """
  500. The N dimensional FFT for real input.
  501. This function computes the N-dimensional discrete Fourier Transform over
  502. any number of axes in an M-dimensional real array by means of the Fast
  503. Fourier Transform (FFT). By default, all axes are transformed, with the
  504. real transform performed over the last axis, while the remaining
  505. transforms are complex.
  506. The transform for real input is performed over the last transformation
  507. axis, as by `rfft`, then the transform over the remaining axes is
  508. performed as by `fftn`. The order of the output is as for `rfft` for the
  509. final transformation axis, and as for `fftn` for the remaining
  510. transformation axes.
  511. Args:
  512. x(Tensor) : Input tensor, taken to be real.
  513. s(Sequence[int], optional) : Shape to use from the exec fft. The final element of
  514. `s` corresponds to `n` for ``rfft(x, n)``, while for the remaining
  515. axes, it corresponds to `n` for ``fft(x, n)``. Along any axis, if
  516. the given shape is smaller than that of the input, the input is
  517. cropped. If it is larger, the input is padded with zeros. if `s` is
  518. not given, the shape of the input along the axes specified by `axes`
  519. is used.
  520. axes(Sequence[int], optional) : Axes over which to compute the FFT. If not given,
  521. the last ``len(s)`` axes are used, or all axes if `s` is also not
  522. specified.
  523. norm(str, optional) : Normalization mode, indicates which direction of
  524. the forward/backward pair of transforms is scaled and with what
  525. normalization factor. Include {"backward", "ortho", "forward"},
  526. default value is "backward". The details of
  527. three operations are shown below:
  528. - "backward": The factor of forward direction and backward direction are ``1``
  529. and ``1/n`` respectively;
  530. - "forward": The factor of forward direction and backward direction are ``1/n``
  531. and ``1`` respectively;
  532. - "ortho": The factor of forward direction and backward direction are both ``1/sqrt(n)``.
  533. Where ``n`` is the multiplication of each element in ``s`` .
  534. name(str, optional): The default value is None. Normally there is no
  535. need for user to set this property. For more information, please
  536. refer to :ref:`api_guide_Name` .
  537. Returns:
  538. out(Tensor), complex tensor
  539. Examples:
  540. .. code-block:: python
  541. >>> import paddle
  542. >>> # default, all axis will be used to exec fft
  543. >>> x = paddle.ones((2, 3, 4))
  544. >>> print(paddle.fft.rfftn(x))
  545. Tensor(shape=[2, 3, 3], dtype=complex64, place=Place(cpu), stop_gradient=True,
  546. [[[(24+0j), 0j, 0j],
  547. [0j, 0j, 0j],
  548. [0j, 0j, 0j]],
  549. [[0j, 0j, 0j],
  550. [0j, 0j, 0j],
  551. [0j, 0j, 0j]]])
  552. >>> # use axes(2, 0)
  553. >>> print(paddle.fft.rfftn(x, axes=(2, 0)))
  554. Tensor(shape=[2, 3, 4], dtype=complex64, place=Place(cpu), stop_gradient=True,
  555. [[[(8+0j), 0j, 0j, 0j],
  556. [(8+0j), 0j, 0j, 0j],
  557. [(8+0j), 0j, 0j, 0j]],
  558. [[0j, 0j, 0j, 0j],
  559. [0j, 0j, 0j, 0j],
  560. [0j, 0j, 0j, 0j]]])
  561. """
  562. return fftn_r2c(x, s, axes, norm, forward=True, onesided=True, name=name)
  563. def irfftn(x, s=None, axes=None, norm="backward", name=None):
  564. """
  565. Computes the inverse of `rfftn`.
  566. This function computes the inverse of the N-D discrete
  567. Fourier Transform for real input over any number of axes in an
  568. M-D array by means of the Fast Fourier Transform (FFT). In
  569. other words, ``irfftn(rfftn(x), x.shape) == x`` to within numerical
  570. accuracy. (The ``x.shape`` is necessary like ``len(x)`` is for `irfft`,
  571. and for the same reason.)
  572. The input should be ordered in the same way as is returned by `rfftn`,
  573. i.e., as for `irfft` for the final transformation axis, and as for `ifftn`
  574. along all the other axes.
  575. Args:
  576. x (Tensor): The input data. It's a Tensor type.
  577. s (sequence of ints, optional): The length of the output transform axis.
  578. (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.).
  579. - `s` is also the number of input points used along this axis, except for the last axis, where ``s[-1]//2+1`` points of the input are used.
  580. - Along any axis, if the shape indicated by `s` is smaller than that of the input, the input is cropped. If it is larger, the input is padded with zeros.
  581. - If `s` is not given, the shape of the input along the axes specified by axes is used. Except for the last axis which is taken to be ``2*(k-1)``
  582. where ``k`` is the length of the input along that axis.
  583. axes (sequence of ints, optional): Axes over which to compute the inverse FFT. If not given, the last
  584. `len(s)` axes are used, or all axes if `s` is also not specified.
  585. norm (str): Indicates which direction to scale the `forward` or `backward` transform
  586. pair and what normalization factor to use. The parameter value must be one
  587. of "forward" or "backward" or "ortho". Default is "backward". The details of
  588. three operations are shown below:
  589. - "backward": The factor of forward direction and backward direction are ``1`` and ``1/n`` respectively;
  590. - "forward": The factor of forward direction and backward direction are ``1/n`` and ``1`` respectively;
  591. - "ortho": The factor of forward direction and backward direction are both ``1/sqrt(n)``.
  592. Where ``n`` is the multiplication of each element in ``s`` .
  593. name (str, optional): The default value is None. Normally there is no need for user to set
  594. this property. For more information, please refer to :ref:`api_guide_Name`.
  595. Returns:
  596. Real tensor. The truncated or zero-padded input, transformed along the axes indicated by `axes`,
  597. or by a combination of `s` or `x`, as explained in the parameters section above. The length of
  598. each transformed axis is as given by the corresponding element of `s`, or the length of the input
  599. in every axis except for the last one if `s` is not given. In the final transformed axis the length
  600. of the output when `s` is not given is ``2*(m-1)``, where ``m`` is the length of the final
  601. transformed axis of the input. To get an odd number of output points in the final axis,
  602. `s` must be specified.
  603. Examples:
  604. .. code-block:: python
  605. >>> import paddle
  606. >>> x = paddle.to_tensor([2.+2.j, 2.+2.j, 3.+3.j]).astype(paddle.complex128)
  607. >>> print(x)
  608. Tensor(shape=[3], dtype=complex128, place=Place(cpu), stop_gradient=True,
  609. [(2+2j), (2+2j), (3+3j)])
  610. >>> irfftn_x = paddle.fft.irfftn(x)
  611. >>> print(irfftn_x)
  612. Tensor(shape=[4], dtype=float64, place=Place(cpu), stop_gradient=True,
  613. [2.25000000, -1.25000000, 0.25000000, 0.75000000])
  614. """
  615. return fftn_c2r(x, s, axes, norm, forward=False, name=name)
  616. def hfftn(x, s=None, axes=None, norm="backward", name=None):
  617. """
  618. Compute the N-D FFT of Hermitian symmetric complex input, i.e., a
  619. signal with a real spectrum.
  620. This function calculates the n-D discrete Fourier transform of Hermite symmetric
  621. complex input on any axis in M-D array by fast Fourier transform (FFT).
  622. In other words, ``ihfftn(hfftn(x, s)) == x`` is within the numerical accuracy range.
  623. (``s`` here are ``x.shape`` and ``s[-1] = x.shape[- 1] * 2 - 1``. This is necessary
  624. for the same reason that ``irfft`` requires ``x.shape``.)
  625. Args:
  626. x (Tensor): The input data. It's a Tensor type.
  627. s (sequence of ints, optional): The length of the output transform axis.
  628. (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.). `s` is also the
  629. number of input points used along this axis, except for the last axis,
  630. where ``s[-1]//2+1`` points of the input are used. Along any axis, if
  631. the shape indicated by `s` is smaller than that of the input, the input
  632. is cropped. If it is larger, the input is padded with zeros.
  633. If `s` is not given, the shape of the input along the axes specified by axes
  634. is used. Except for the last axis which is taken to be ``2*(k-1)`` where
  635. ``k`` is the length of the input along that axis.
  636. axes (sequence of ints, optional): Axes over which to compute the inverse FFT. If not given, the last
  637. `len(s)` axes are used, or all axes if `s` is also not specified.
  638. norm (str, optional): Indicates which direction to scale the `forward` or `backward` transform
  639. pair and what normalization factor to use. The parameter value must be one
  640. of "forward" or "backward" or "ortho". Default is "backward".
  641. name (str, optional): The default value is None. Normally there is no need for user to set
  642. this property. For more information, please refer to :ref:`api_guide_Name`.
  643. Returns:
  644. Real tensor. Truncate or zero fill input, transforming along the axis indicated by axis or
  645. a combination of `s` or `X`.
  646. Examples:
  647. .. code-block:: python
  648. >>> import paddle
  649. >>> x = paddle.to_tensor([(2+2j), (2+2j), (3+3j)])
  650. >>> hfftn_x = paddle.fft.hfftn(x)
  651. >>> print(hfftn_x)
  652. Tensor(shape=[4], dtype=float32, place=Place(cpu), stop_gradient=True,
  653. [9., 3., 1., -5.])
  654. """
  655. return fftn_c2r(x, s, axes, norm, forward=True, name=name)
  656. def ihfftn(x, s=None, axes=None, norm="backward", name=None):
  657. """
  658. The n dimensional inverse FFT of a signal that has Hermitian symmetry.
  659. This function computes the n dimensional inverse FFT over any number of axes
  660. in an M-dimensional of a signal that has Hermitian symmetry by means of an
  661. efficient algorithm called the Fast Fourier Transform (FFT).
  662. Args:
  663. x(Tensor): Input tensor.
  664. s(Sequence[int], optional) : Shape (length along each transformed axis)
  665. to use from the input. (``s[0]`` refers to axis 0, ``s[1]`` to axis
  666. 1, etc.). Along any axis, if the given shape is smaller than that
  667. of the input, the input is cropped. If it is larger, the input is
  668. padded with zeros. if `s` is not given, the shape of the input
  669. along the axes specified by `axes` is used.
  670. axes(Sequence[int], optional) : Axis over which to compute the inverse FFT. If not
  671. given, the last axis is used.
  672. norm(str, optional) : Normalization mode, indicates which direction of
  673. the forward/backward pair of transforms is scaled and with what
  674. normalization factor. Include {"backward", "ortho", "forward"},
  675. default value is "backward".
  676. name(str, optional): The default value is None. Normally there is no
  677. need for user to set this property. For more information, please
  678. refer to :ref:`api_guide_Name` .
  679. Returns:
  680. out(Tensor) : complex tensor.
  681. Examples:
  682. .. code-block:: python
  683. >>> import paddle
  684. >>> spectrum = paddle.to_tensor([10.0, -5.0, 0.0, -1.0, 0.0, -5.0])
  685. >>> print(paddle.fft.ifft(spectrum))
  686. Tensor(shape=[6], dtype=complex64, place=Place(cpu), stop_gradient=True,
  687. [(-0.1666666716337204+0j), (1-0j),
  688. (2.3333334922790527-0j), (3.5+0j),
  689. (2.3333334922790527+0j), (1+0j)])
  690. >>> print(paddle.fft.ihfft(spectrum))
  691. Tensor(shape=[4], dtype=complex64, place=Place(cpu), stop_gradient=True,
  692. [(-0.1666666716337204+0j), (1-0j),
  693. (2.3333334922790527-0j), (3.5+0j)])
  694. """
  695. return fftn_r2c(x, s, axes, norm, forward=False, onesided=True, name=name)
  696. # public APIs 2d
  697. def fft2(x, s=None, axes=(-2, -1), norm="backward", name=None):
  698. """
  699. Compute the 2-D discrete Fourier Transform
  700. This function computes the N-D discrete Fourier Transform
  701. over any axes in an M-D array by means of the
  702. Fast Fourier Transform (FFT). By default, the transform is computed over
  703. the last two axes of the input array, i.e., a 2-dimensional FFT.
  704. Args:
  705. x (Tensor): The input data. It's a Tensor type.
  706. s (sequence of ints, optional): Shape (length of each transformed axis) of the output.
  707. It should be a sequence of 2 integers. This corresponds to ``n`` for ``fft(x, n)``.
  708. Along each axis, if the given shape is smaller than that of the input,
  709. the input is cropped. If it is larger, the input is padded with zeros.
  710. if `s` is not given, the shape of the input along the axes specified
  711. by `axes` is used. Default is None.
  712. axes (sequence of ints, optional): Axes over which to compute the FFT. It should be a
  713. sequence of 2 integers. If not specified, the last two axes are used by default.
  714. norm (str, optional): Indicates which direction to scale the `forward` or `backward` transform
  715. pair and what normalization factor to use. The parameter value must be one
  716. of "forward" or "backward" or "ortho". Default is "backward".
  717. name (str, optional): The default value is None. Normally there is no need for user to set
  718. this property. For more information, please refer to :ref:`api_guide_Name`.
  719. Returns:
  720. Complex tensor. The truncated or zero-padded input, transformed along the axes indicated by `axes`,
  721. or the last two axes if `axes` is not given.
  722. Examples:
  723. .. code-block:: python
  724. >>> import paddle
  725. >>> arr = paddle.arange(2, dtype="float64")
  726. >>> x = paddle.meshgrid(arr, arr)[0]
  727. >>> fft2_xp = paddle.fft.fft2(x)
  728. >>> print(fft2_xp)
  729. Tensor(shape=[2, 2], dtype=complex128, place=Place(cpu), stop_gradient=True,
  730. [[(2+0j), 0j],
  731. [(-2+0j), 0j]])
  732. """
  733. _check_at_least_ndim(x, 2)
  734. if s is not None:
  735. if not isinstance(s, Sequence) or len(s) != 2:
  736. raise ValueError(
  737. f"Invalid FFT argument s ({s}), it should be a sequence of 2 integers."
  738. )
  739. if axes is not None:
  740. if not isinstance(axes, Sequence) or len(axes) != 2:
  741. raise ValueError(
  742. f"Invalid FFT argument axes ({axes}), it should be a sequence of 2 integers."
  743. )
  744. return fftn(x, s, axes, norm, name)
  745. def ifft2(x, s=None, axes=(-2, -1), norm="backward", name=None):
  746. """
  747. Compute the 2-D inverse discrete Fourier Transform.
  748. This function computes the inverse of the 2-D discrete Fourier
  749. Transform over any number of axes in an M-D array by means of
  750. the Fast Fourier Transform (FFT). In other words, ``ifft2(fft2(x)) == x``
  751. to within numerical accuracy. By default, the inverse transform is
  752. computed over the last two axes of the input array.
  753. The input, analogously to `ifft`, should be ordered in the same way as is
  754. returned by `fft2`, i.e., it should have the term for zero frequency
  755. in the low-order corner of the two axes, the positive frequency terms in
  756. the first half of these axes, the term for the Nyquist frequency in the
  757. middle of the axes and the negative frequency terms in the second half of
  758. both axes, in order of decreasingly negative frequency.
  759. Args:
  760. x (Tensor): The input data. It's a Tensor type.
  761. s (sequence of ints, optional): Shape (length of each transformed axis) of the output.
  762. It should be a sequence of 2 integers. This corresponds to ``n`` for ``fft(x, n)``.
  763. Along each axis, if the given shape is smaller than that of the input,
  764. the input is cropped. If it is larger, the input is padded with zeros.
  765. if `s` is not given, the shape of the input along the axes specified
  766. by `axes` is used. Default is None.
  767. axes (sequence of ints, optional): Axes over which to compute the FFT. It should be a
  768. sequence of 2 integers. If not specified, the last two axes are used by default.
  769. norm (str, optional): Indicates which direction to scale the `forward` or `backward` transform
  770. pair and what normalization factor to use. The parameter value must be one
  771. of "forward" or "backward" or "ortho". Default is "backward".
  772. name (str, optional): The default value is None. Normally there is no need for user to set
  773. this property. For more information, please refer to :ref:`api_guide_Name`.
  774. Returns:
  775. Complex tensor. The truncated or zero-padded input, transformed along the axes indicated by `axes`,
  776. or the last two axes if `axes` is not given.
  777. Examples:
  778. .. code-block:: python
  779. >>> import paddle
  780. >>> arr = paddle.arange(2, dtype="float64")
  781. >>> x = paddle.meshgrid(arr, arr)[0]
  782. >>> ifft2_xp = paddle.fft.ifft2(x)
  783. >>> print(ifft2_xp)
  784. Tensor(shape=[2, 2], dtype=complex128, place=Place(cpu), stop_gradient=True,
  785. [[(0.5+0j), 0j],
  786. [(-0.5+0j), 0j]])
  787. """
  788. _check_at_least_ndim(x, 2)
  789. if s is not None:
  790. if not isinstance(s, Sequence) or len(s) != 2:
  791. raise ValueError(
  792. f"Invalid FFT argument s ({s}), it should be a sequence of 2 integers."
  793. )
  794. if axes is not None:
  795. if not isinstance(axes, Sequence) or len(axes) != 2:
  796. raise ValueError(
  797. f"Invalid FFT argument axes ({axes}), it should be a sequence of 2 integers."
  798. )
  799. return ifftn(x, s, axes, norm, name)
  800. def rfft2(x, s=None, axes=(-2, -1), norm="backward", name=None):
  801. """
  802. The two dimensional FFT with real tensor input.
  803. This is really just `rfftn` with different default behavior.
  804. For more details see `rfftn`.
  805. Args:
  806. x(Tensor): Input tensor, taken to be real.
  807. s(Sequence[int], optional) : Shape of the FFT.
  808. axes(Sequence[int], optional): Axes over which to compute the FFT.
  809. norm(str, optional) : {"backward", "ortho", "forward"},
  810. default is "backward". Indicates which direction of the
  811. forward/backward pair of transforms is scaled and with what
  812. normalization factor. The details of
  813. three operations are shown below:
  814. - "backward": The factor of forward direction and backward direction are ``1`` and ``1/n`` respectively;
  815. - "forward": The factor of forward direction and backward direction are ``1/n`` and ``1`` respectively;
  816. - "ortho": The factor of forward direction and backward direction are both ``1/sqrt(n)``.
  817. Where ``n`` is the multiplication of each element in ``s`` .
  818. name(str, optional): The default value is None. Normally there is no
  819. need for user to set this property. For more information, please
  820. refer to :ref:`api_guide_Name` .
  821. Returns:
  822. out(Tensor): The result of the real 2-D FFT.
  823. Examples:
  824. .. code-block:: python
  825. >>> import paddle
  826. >>> arr = paddle.arange(5, dtype="float64")
  827. >>> x = paddle.meshgrid(arr, arr)[0]
  828. >>> result = paddle.fft.rfft2(x)
  829. >>> print(result.numpy())
  830. [[50. +0.j 0. +0.j 0. +0.j]
  831. [-12.5+17.20477401j 0. +0.j 0. +0.j]
  832. [-12.5 +4.0614962j 0. +0.j 0. +0.j]
  833. [-12.5 -4.0614962j 0. +0.j 0. +0.j]
  834. [-12.5-17.20477401j 0. +0.j 0. +0.j]]
  835. """
  836. _check_at_least_ndim(x, 2)
  837. if s is not None:
  838. if not isinstance(s, Sequence) or len(s) != 2:
  839. raise ValueError(
  840. f"Invalid FFT argument s ({s}), it should be a sequence of 2 integers."
  841. )
  842. if axes is not None:
  843. if not isinstance(axes, Sequence) or len(axes) != 2:
  844. raise ValueError(
  845. f"Invalid FFT argument axes ({axes}), it should be a sequence of 2 integers."
  846. )
  847. return rfftn(x, s, axes, norm, name)
  848. def irfft2(x, s=None, axes=(-2, -1), norm="backward", name=None):
  849. """
  850. Computes the inverse of `rfft2`.
  851. Args:
  852. x (Tensor): The input data. It's a Tensor type.
  853. s (sequence of ints, optional): Shape of the real output to the inverse FFT. Default is None.
  854. axes (sequence of ints, optional): The axes over which to compute the inverse FFT. Axes
  855. must be two-dimensional. If not specified, the last two axes are used by default.
  856. norm (str, optional): Indicates which direction to scale the `forward` or `backward` transform
  857. pair and what normalization factor to use. The parameter value must be one
  858. of "forward" or "backward" or "ortho". Default is "backward". The details of
  859. three operations are shown below:
  860. - "backward": The factor of forward direction and backward direction are ``1`` and ``1/n`` respectively;
  861. - "forward": The factor of forward direction and backward direction are ``1/n`` and ``1`` respectively;
  862. - "ortho": The factor of forward direction and backward direction are both ``1/sqrt(n)``.
  863. Where ``n`` is the multiplication of each element in ``s`` .
  864. name (str, optional): The default value is None. Normally there is no need for user to set
  865. this property. For more information, please refer to :ref:`api_guide_Name` .
  866. Returns:
  867. Real tensor. The result of the inverse real 2-D FFT.
  868. Examples:
  869. .. code-block:: python
  870. >>> import paddle
  871. >>> x = paddle.to_tensor([[3.+3.j, 2.+2.j, 3.+3.j], [2.+2.j, 2.+2.j, 3.+3.j]])
  872. >>> irfft2_x = paddle.fft.irfft2(x)
  873. >>> print(irfft2_x)
  874. Tensor(shape=[2, 4], dtype=float32, place=Place(cpu), stop_gradient=True,
  875. [[2.37500000, -1.12500000, 0.37500000, 0.87500000],
  876. [0.12500000, 0.12500000, 0.12500000, 0.12500000]])
  877. """
  878. _check_at_least_ndim(x, 2)
  879. if s is not None:
  880. if not isinstance(s, Sequence) or len(s) != 2:
  881. raise ValueError(
  882. f"Invalid FFT argument s ({s}), it should be a sequence of 2 integers."
  883. )
  884. if axes is not None:
  885. if not isinstance(axes, Sequence) or len(axes) != 2:
  886. raise ValueError(
  887. f"Invalid FFT argument axes ({axes}), it should be a sequence of 2 integers."
  888. )
  889. return irfftn(x, s, axes, norm, name)
  890. def hfft2(x, s=None, axes=(-2, -1), norm="backward", name=None):
  891. """
  892. Compute the 2-D FFT of a Hermitian complex array.
  893. Args:
  894. x (Tensor): The input data. It's a Tensor type.
  895. s (sequence of ints, optional): Shape of the real output. Default is None.
  896. axes (sequence of ints, optional): Axes over which to compute the FFT. Axes must be
  897. two-dimensional. If not specified, the last two axes are used by default.
  898. norm (str): Indicates which direction to scale the `forward` or `backward` transform
  899. pair and what normalization factor to use. The parameter value must be one
  900. of "forward" or "backward" or "ortho". Default is "backward".
  901. name (str, optional): The default value is None. Normally there is no need for user to set
  902. this property. For more information, please refer to :ref:`api_guide_Name`.
  903. Returns:
  904. Real tensor. The real result of the 2-D Hermitian complex real FFT.
  905. Examples:
  906. .. code-block:: python
  907. >>> import paddle
  908. >>> x = paddle.to_tensor([[3.+3.j, 2.+2.j, 3.+3.j], [2.+2.j, 2.+2.j, 3.+3.j]])
  909. >>> hfft2_x = paddle.fft.hfft2(x)
  910. >>> print(hfft2_x)
  911. Tensor(shape=[2, 4], dtype=float32, place=Place(cpu), stop_gradient=True,
  912. [[19., 7., 3., -9.],
  913. [1., 1., 1., 1.]])
  914. """
  915. _check_at_least_ndim(x, 2)
  916. if s is not None:
  917. if not isinstance(s, Sequence) or len(s) != 2:
  918. raise ValueError(
  919. f"Invalid FFT argument s ({s}), it should be a sequence of 2 integers."
  920. )
  921. if axes is not None:
  922. if not isinstance(axes, Sequence) or len(axes) != 2:
  923. raise ValueError(
  924. f"Invalid FFT argument axes ({axes}), it should be a sequence of 2 integers."
  925. )
  926. return hfftn(x, s, axes, norm, name)
  927. def ihfft2(x, s=None, axes=(-2, -1), norm="backward", name=None):
  928. """
  929. Compute the two dimensional inverse FFT of a real spectrum.
  930. This is really `ihfftn` with different defaults.
  931. For more details see `ihfftn`.
  932. Args:
  933. x(Tensor): Input tensor.
  934. s(Sequence[int], optional): Shape of the real input to the inverse FFT.
  935. axes(Sequence[int], optional): The axes over which to compute the
  936. inverse fft. Default is the last two axes.
  937. norm(str, optional): {"backward", "ortho", "forward"}. Default is
  938. "backward".
  939. name(str, optional): The default value is None. Normally there is no
  940. need for user to set this property. For more information, please
  941. refer to :ref:`api_guide_Name` .
  942. Returns:
  943. out(Tensor) : The result of the inverse hermitian 2-D FFT.
  944. Examples:
  945. .. code-block:: python
  946. >>> import paddle
  947. >>> arr = paddle.arange(5, dtype="float64")
  948. >>> x = paddle.meshgrid(arr, arr)[0]
  949. >>> print(x)
  950. Tensor(shape=[5, 5], dtype=float64, place=Place(cpu), stop_gradient=True,
  951. [[0., 0., 0., 0., 0.],
  952. [1., 1., 1., 1., 1.],
  953. [2., 2., 2., 2., 2.],
  954. [3., 3., 3., 3., 3.],
  955. [4., 4., 4., 4., 4.]])
  956. >>> ihfft2_xp = paddle.fft.ihfft2(x)
  957. >>> print(ihfft2_xp.numpy())
  958. [[2. +0.j 0. -0.j 0. -0.j]
  959. [-0.5-0.68819096j 0. +0.j 0. +0.j]
  960. [-0.5-0.16245985j 0. +0.j 0. +0.j]
  961. [-0.5+0.16245985j 0. +0.j 0. +0.j]
  962. [-0.5+0.68819096j 0. +0.j 0. +0.j]]
  963. """
  964. _check_at_least_ndim(x, 2)
  965. if s is not None:
  966. if not isinstance(s, Sequence) or len(s) != 2:
  967. raise ValueError(
  968. f"Invalid FFT argument s ({s}), it should be a sequence of 2 integers."
  969. )
  970. if axes is not None:
  971. if not isinstance(axes, Sequence) or len(axes) != 2:
  972. raise ValueError(
  973. f"Invalid FFT argument axes ({axes}), it should be a sequence of 2 integers."
  974. )
  975. return ihfftn(x, s, axes, norm, name)
  976. # public APIs utilities
  977. def fftfreq(n, d=1.0, dtype=None, name=None):
  978. """
  979. Return the Discrete Fourier Transform sample frequencies.
  980. The returned float array `f` contains the frequency bin centers in cycles
  981. per unit of the sample spacing (with zero at the start). For instance, if
  982. the sample spacing is in seconds, then the frequency unit is cycles/second.
  983. Given input length `n` and a sample spacing `d`::
  984. f = [0, 1, ..., n/2-1, -n/2, ..., -1] / (d*n) if n is even
  985. f = [0, 1, ..., (n-1)/2, -(n-1)/2, ..., -1] / (d*n) if n is odd
  986. Args:
  987. n (int): Dimension inputed.
  988. d (scalar, optional): Sample spacing (inverse of the sampling rate). Defaults is 1.
  989. name (str, optional): The default value is None. Normally there is no need for user to set
  990. this property. For more information, please refer to :ref:`api_guide_Name`.
  991. Returns:
  992. Tensor. A tensor of length 'n' containing the sampling frequency.
  993. Examples:
  994. .. code-block:: python
  995. >>> import paddle
  996. >>> scalar_temp = 0.5
  997. >>> fftfreq_xp = paddle.fft.fftfreq(5, d=scalar_temp)
  998. >>> print(fftfreq_xp)
  999. Tensor(shape=[5], dtype=float32, place=Place(cpu), stop_gradient=True,
  1000. [0., 0.40000001, 0.80000001, -0.80000001, -0.40000001])
  1001. """
  1002. if d * n == 0:
  1003. raise ValueError("d or n should not be 0.")
  1004. dtype = paddle.framework.get_default_dtype()
  1005. val = 1.0 / (n * d)
  1006. pos_max = (n + 1) // 2
  1007. neg_max = n // 2
  1008. indices = paddle.arange(-neg_max, pos_max, dtype=dtype, name=name)
  1009. indices = paddle.roll(indices, -neg_max, name=name)
  1010. return indices * val
  1011. def rfftfreq(n, d=1.0, dtype=None, name=None):
  1012. """
  1013. Return the Discrete Fourier Transform sample frequencies.
  1014. The returned floating-point array "F" contains the center of the frequency unit,
  1015. and the unit is the number of cycles of the sampling interval (the starting point is zero).
  1016. Given input length `n` and a sample spacing `d`::
  1017. f = [0, 1, ..., n/2-1, n/2] / (d*n) if n is even
  1018. f = [0, 1, ..., (n-1)/2-1, (n-1)/2] / (d*n) if n is odd
  1019. the Nyquist frequency component is considered to be positive.
  1020. Args:
  1021. n (int): Dimension inputed.
  1022. d (scalar, optional): Sample spacing (inverse of the sampling rate). Defaults is 1.
  1023. dtype (str, optional): The data type of returns. Defaults is the data type of returns
  1024. of ``paddle.get_default_dtype()``.
  1025. name (str, optional): The default value is None. Normally there is no need for user to set
  1026. this property. For more information, please refer to :ref:`api_guide_Name`.
  1027. Returns:
  1028. Tensor. A tensor of length ``n//2 + 1`` containing the sample frequencies.
  1029. Examples:
  1030. .. code-block:: python
  1031. >>> import paddle
  1032. >>> scalar_temp = 0.3
  1033. >>> rfftfreq_xp = paddle.fft.rfftfreq(5, d=scalar_temp)
  1034. >>> print(rfftfreq_xp)
  1035. Tensor(shape=[3], dtype=float32, place=Place(cpu), stop_gradient=True,
  1036. [0., 0.66666669, 1.33333337])
  1037. """
  1038. if d * n == 0:
  1039. raise ValueError("d or n should not be 0.")
  1040. dtype = paddle.framework.get_default_dtype()
  1041. val = 1.0 / (n * d)
  1042. pos_max = 1 + n // 2
  1043. indices = paddle.arange(0, pos_max, dtype=dtype, name=name)
  1044. return indices * val
  1045. def fftshift(x, axes=None, name=None):
  1046. """
  1047. Shift the zero-frequency component to the center of the spectrum.
  1048. This function swaps half spaces for all the axes listed (all by default).
  1049. Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even.
  1050. Args:
  1051. n (int): Dimension inputed.
  1052. axes (int|tuple, optional): The axis on which to move. The default is none, which moves all axes.
  1053. Default is None.
  1054. name (str, optional): The default value is None. Normally there is no need for user to set
  1055. this property. For more information, please refer to :ref:`api_guide_Name`.
  1056. Returns:
  1057. Tensor. The shifted tensor.
  1058. Examples:
  1059. .. code-block:: python
  1060. >>> import paddle
  1061. >>> fftfreq_xp = paddle.fft.fftfreq(5, d=0.3)
  1062. >>> print(fftfreq_xp)
  1063. Tensor(shape=[5], dtype=float32, place=Place(cpu), stop_gradient=True,
  1064. [0., 0.66666669, 1.33333337, -1.33333337, -0.66666669])
  1065. >>> res = paddle.fft.fftshift(fftfreq_xp)
  1066. >>> print(res)
  1067. Tensor(shape=[5], dtype=float32, place=Place(cpu), stop_gradient=True,
  1068. [-1.33333337, -0.66666669, 0., 0.66666669, 1.33333337])
  1069. """
  1070. shape = paddle.shape(x)
  1071. if axes is None:
  1072. # shift all axes
  1073. rank = len(x.shape)
  1074. axes = list(range(0, rank))
  1075. shifts = shape // 2
  1076. elif isinstance(axes, int):
  1077. shifts = shape[axes] // 2
  1078. else:
  1079. shifts = paddle.concat([shape[ax : ax + 1] // 2 for ax in axes])
  1080. return paddle.roll(x, shifts, axes, name=name)
  1081. def ifftshift(x, axes=None, name=None):
  1082. """
  1083. The inverse of `fftshift`. Although the even length 'x' is the same, the function of the
  1084. odd length 'x' is different. An example.
  1085. Args:
  1086. n (int): Dimension inputed.
  1087. axes (int|tuple, optional): The axis on which to move. The default is none, which moves all axes.
  1088. Default is None.
  1089. name (str, optional): The default value is None. Normally there is no need for user to set
  1090. this property. For more information, please refer to :ref:`api_guide_Name`.
  1091. Returns:
  1092. Tensor. The shifted tensor.
  1093. Examples:
  1094. .. code-block:: python
  1095. >>> import paddle
  1096. >>> fftfreq_xp = paddle.fft.fftfreq(5, d=0.3)
  1097. >>> print(fftfreq_xp)
  1098. Tensor(shape=[5], dtype=float32, place=Place(cpu), stop_gradient=True,
  1099. [0., 0.66666669, 1.33333337, -1.33333337, -0.66666669])
  1100. >>> res = paddle.fft.ifftshift(fftfreq_xp)
  1101. >>> print(res)
  1102. Tensor(shape=[5], dtype=float32, place=Place(cpu), stop_gradient=True,
  1103. [1.33333337, -1.33333337, -0.66666669, 0., 0.66666669])
  1104. """
  1105. shape = paddle.shape(x)
  1106. if axes is None:
  1107. # shift all axes
  1108. rank = len(x.shape)
  1109. axes = list(range(0, rank))
  1110. shifts = (shape + 1) // 2
  1111. elif isinstance(axes, int):
  1112. shifts = (shape[axes] + 1) // 2
  1113. else:
  1114. shifts = paddle.concat([(shape[ax : ax + 1] + 1) // 2 for ax in axes])
  1115. return paddle.roll(x, shifts, axes, name=name)
  1116. # internal functions
  1117. def fft_c2c(x, n, axis, norm, forward, name):
  1118. if is_integer(x):
  1119. x = paddle.cast(x, _real_to_complex_dtype(paddle.get_default_dtype()))
  1120. elif is_floating_point(x):
  1121. x = paddle.cast(x, _real_to_complex_dtype(x.dtype))
  1122. _check_normalization(norm)
  1123. axis = axis if axis is not None else -1
  1124. _check_fft_axis(x, axis)
  1125. axes = [axis]
  1126. axes = _normalize_axes(x, axes)
  1127. if n is not None:
  1128. _check_fft_n(n)
  1129. s = [n]
  1130. x = _resize_fft_input(x, s, axes)
  1131. if in_dynamic_or_pir_mode():
  1132. out = _C_ops.fft_c2c(x, axes, norm, forward)
  1133. else:
  1134. op_type = 'fft_c2c'
  1135. check_variable_and_dtype(x, 'x', ['complex64', 'complex128'], op_type)
  1136. inputs = {
  1137. 'X': [x],
  1138. }
  1139. attrs = {'axes': axes, 'normalization': norm, 'forward': forward}
  1140. helper = LayerHelper(op_type, **locals())
  1141. dtype = helper.input_dtype(input_param_name='x')
  1142. out = helper.create_variable_for_type_inference(dtype)
  1143. outputs = {"Out": [out]}
  1144. helper.append_op(
  1145. type=op_type, inputs=inputs, outputs=outputs, attrs=attrs
  1146. )
  1147. return out
  1148. def fft_r2c(x, n, axis, norm, forward, onesided, name):
  1149. if is_integer(x):
  1150. x = paddle.cast(x, paddle.get_default_dtype())
  1151. _check_normalization(norm)
  1152. axis = axis if axis is not None else -1
  1153. _check_fft_axis(x, axis)
  1154. axes = [axis]
  1155. axes = _normalize_axes(x, axes)
  1156. if n is not None:
  1157. _check_fft_n(n)
  1158. s = [n]
  1159. x = _resize_fft_input(x, s, axes)
  1160. if in_dynamic_or_pir_mode():
  1161. out = _C_ops.fft_r2c(x, axes, norm, forward, onesided)
  1162. else:
  1163. op_type = 'fft_r2c'
  1164. check_variable_and_dtype(
  1165. x, 'x', ['float16', 'float32', 'float64'], op_type
  1166. )
  1167. inputs = {
  1168. 'X': [x],
  1169. }
  1170. attrs = {
  1171. 'axes': axes,
  1172. 'normalization': norm,
  1173. 'forward': forward,
  1174. 'onesided': onesided,
  1175. }
  1176. helper = LayerHelper(op_type, **locals())
  1177. dtype = helper.input_dtype(input_param_name='x')
  1178. out = helper.create_variable_for_type_inference(
  1179. _real_to_complex_dtype(dtype)
  1180. )
  1181. outputs = {"Out": [out]}
  1182. helper.append_op(
  1183. type=op_type, inputs=inputs, outputs=outputs, attrs=attrs
  1184. )
  1185. return out
  1186. def fft_c2r(x, n, axis, norm, forward, name):
  1187. if is_integer(x):
  1188. x = paddle.cast(x, _real_to_complex_dtype(paddle.get_default_dtype()))
  1189. elif is_floating_point(x):
  1190. x = paddle.cast(x, _real_to_complex_dtype(x.dtype))
  1191. _check_normalization(norm)
  1192. axis = axis if axis is not None else -1
  1193. _check_fft_axis(x, axis)
  1194. axes = [axis]
  1195. axes = _normalize_axes(x, axes)
  1196. if n is not None:
  1197. _check_fft_n(n)
  1198. s = [n // 2 + 1]
  1199. x = _resize_fft_input(x, s, axes)
  1200. if in_dynamic_or_pir_mode():
  1201. if n is not None:
  1202. out = _C_ops.fft_c2r(x, axes, norm, forward, n)
  1203. else:
  1204. out = _C_ops.fft_c2r(x, axes, norm, forward, 0)
  1205. else:
  1206. op_type = 'fft_c2r'
  1207. check_variable_and_dtype(x, 'x', ['complex64', 'complex128'], op_type)
  1208. inputs = {
  1209. 'X': [x],
  1210. }
  1211. attrs = {'axes': axes, 'normalization': norm, 'forward': forward}
  1212. if n is not None:
  1213. attrs['last_dim_size'] = n
  1214. helper = LayerHelper(op_type, **locals())
  1215. dtype = helper.input_dtype(input_param_name='x')
  1216. out = helper.create_variable_for_type_inference(
  1217. _complex_to_real_dtype(dtype)
  1218. )
  1219. outputs = {"Out": [out]}
  1220. helper.append_op(
  1221. type=op_type, inputs=inputs, outputs=outputs, attrs=attrs
  1222. )
  1223. return out
  1224. def fftn_c2c(x, s, axes, norm, forward, name):
  1225. if is_integer(x):
  1226. x = paddle.cast(x, _real_to_complex_dtype(paddle.get_default_dtype()))
  1227. elif is_floating_point(x):
  1228. x = paddle.cast(x, _real_to_complex_dtype(x.dtype))
  1229. _check_normalization(norm)
  1230. if s is not None:
  1231. _check_fft_shape(x, s)
  1232. rank = x.ndim
  1233. if axes is None:
  1234. if s is None:
  1235. axes = list(range(rank))
  1236. else:
  1237. fft_ndims = len(s)
  1238. axes = list(range(rank - fft_ndims, rank))
  1239. else:
  1240. _check_fft_axes(x, axes)
  1241. axes = _normalize_axes(x, axes)
  1242. axes_argsoft = np.argsort(axes).tolist()
  1243. axes = [axes[i] for i in axes_argsoft]
  1244. if s is not None:
  1245. if len(s) != len(axes):
  1246. raise ValueError(
  1247. f"Length of s ({len(s)}) and length of axes ({len(axes)}) does not match."
  1248. )
  1249. s = [s[i] for i in axes_argsoft]
  1250. if s is not None:
  1251. x = _resize_fft_input(x, s, axes)
  1252. if in_dynamic_or_pir_mode():
  1253. out = _C_ops.fft_c2c(x, axes, norm, forward)
  1254. else:
  1255. op_type = 'fft_c2c'
  1256. check_variable_and_dtype(x, 'x', ['complex64', 'complex128'], op_type)
  1257. inputs = {
  1258. 'X': [x],
  1259. }
  1260. attrs = {'axes': axes, 'normalization': norm, 'forward': forward}
  1261. helper = LayerHelper(op_type, **locals())
  1262. dtype = helper.input_dtype(input_param_name='x')
  1263. out = helper.create_variable_for_type_inference(dtype)
  1264. outputs = {"Out": [out]}
  1265. helper.append_op(
  1266. type=op_type, inputs=inputs, outputs=outputs, attrs=attrs
  1267. )
  1268. return out
  1269. def fftn_r2c(x, s, axes, norm, forward, onesided, name):
  1270. if is_integer(x):
  1271. x = paddle.cast(x, paddle.get_default_dtype())
  1272. _check_normalization(norm)
  1273. if s is not None:
  1274. _check_fft_shape(x, s)
  1275. rank = x.ndim
  1276. if axes is None:
  1277. if s is None:
  1278. axes = list(range(rank))
  1279. else:
  1280. fft_ndims = len(s)
  1281. axes = list(range(rank - fft_ndims, rank))
  1282. else:
  1283. _check_fft_axes(x, axes)
  1284. axes = _normalize_axes(x, axes)
  1285. axes_argsoft = np.argsort(axes[:-1]).tolist()
  1286. axes = [axes[i] for i in axes_argsoft] + [axes[-1]]
  1287. if s is not None:
  1288. if len(s) != len(axes):
  1289. raise ValueError(
  1290. f"Length of s ({len(s)}) and length of axes ({len(axes)}) does not match."
  1291. )
  1292. s = [s[i] for i in axes_argsoft] + [s[-1]]
  1293. if s is not None:
  1294. x = _resize_fft_input(x, s, axes)
  1295. if in_dynamic_or_pir_mode():
  1296. out = _C_ops.fft_r2c(x, axes, norm, forward, onesided)
  1297. else:
  1298. op_type = 'fft_r2c'
  1299. check_variable_and_dtype(
  1300. x, 'x', ['float16', 'float32', 'float64'], op_type
  1301. )
  1302. inputs = {
  1303. 'X': [x],
  1304. }
  1305. attrs = {
  1306. 'axes': axes,
  1307. 'normalization': norm,
  1308. 'forward': forward,
  1309. 'onesided': onesided,
  1310. }
  1311. helper = LayerHelper(op_type, **locals())
  1312. dtype = helper.input_dtype(input_param_name='x')
  1313. out = helper.create_variable_for_type_inference(
  1314. _real_to_complex_dtype(dtype)
  1315. )
  1316. outputs = {"Out": [out]}
  1317. helper.append_op(
  1318. type=op_type, inputs=inputs, outputs=outputs, attrs=attrs
  1319. )
  1320. return out
  1321. def fftn_c2r(x, s, axes, norm, forward, name):
  1322. if is_integer(x):
  1323. x = paddle.cast(x, _real_to_complex_dtype(paddle.get_default_dtype()))
  1324. elif is_floating_point(x):
  1325. x = paddle.cast(x, _real_to_complex_dtype(x.dtype))
  1326. _check_normalization(norm)
  1327. if s is not None:
  1328. _check_fft_shape(x, s)
  1329. rank = x.ndim
  1330. if axes is None:
  1331. if s is None:
  1332. axes = list(range(rank))
  1333. else:
  1334. fft_ndims = len(s)
  1335. axes = list(range(rank - fft_ndims, rank))
  1336. else:
  1337. _check_fft_axes(x, axes)
  1338. axes = _normalize_axes(x, axes)
  1339. axes_argsoft = np.argsort(axes[:-1]).tolist()
  1340. axes = [axes[i] for i in axes_argsoft] + [axes[-1]]
  1341. if s is not None:
  1342. if len(s) != len(axes):
  1343. raise ValueError(
  1344. f"Length of s ({len(s)}) and length of axes ({len(axes)}) does not match."
  1345. )
  1346. s = [s[i] for i in axes_argsoft] + [s[-1]]
  1347. if s is not None:
  1348. fft_input_shape = list(s)
  1349. fft_input_shape[-1] = fft_input_shape[-1] // 2 + 1
  1350. x = _resize_fft_input(x, fft_input_shape, axes)
  1351. if in_dynamic_or_pir_mode():
  1352. if s is not None:
  1353. out = _C_ops.fft_c2r(x, axes, norm, forward, s[-1])
  1354. else:
  1355. out = _C_ops.fft_c2r(x, axes, norm, forward, 0)
  1356. else:
  1357. op_type = 'fft_c2r'
  1358. check_variable_and_dtype(x, 'x', ['complex64', 'complex128'], op_type)
  1359. inputs = {
  1360. 'X': [x],
  1361. }
  1362. attrs = {'axes': axes, 'normalization': norm, 'forward': forward}
  1363. if s:
  1364. attrs["last_dim_size"] = s[-1]
  1365. helper = LayerHelper(op_type, **locals())
  1366. dtype = helper.input_dtype(input_param_name='x')
  1367. out = helper.create_variable_for_type_inference(
  1368. _complex_to_real_dtype(dtype)
  1369. )
  1370. outputs = {"Out": [out]}
  1371. helper.append_op(
  1372. type=op_type, inputs=inputs, outputs=outputs, attrs=attrs
  1373. )
  1374. return out