为什么 NumPy 的 irfft2 of rfft2 在原始矩阵具有奇数第二个索引时导致矩阵少一列?

Why does NumPy's irfft2 of rfft2 lead to a matrix with one less column when the original matrix has an odd second index?

我对 NumPy 中 rfft2irfft2 的以下行为感到困惑。如果我从一个 m x n 的实数矩阵开始,其中 n 是奇数,然后如果我采用 rfft2 后跟 irfft2,我最终得到一个 m x (n-1) 矩阵。由于 irfft2rfft2 的逆矩阵,我希望得到一个大小为 m x n 的矩阵。此外,矩阵中的值不是我开始的值——请参阅下面的输出。

>>> import numpy as np
>>> x = np.ones((4, 3))
>>> ix = np.fft.rfft2(x)
>>> rx = np.fft.irfft2(ix)
>>> rx.shape
(4, 2)
>>> rx
array([[1.5, 1.5],
       [1.5, 1.5],
       [1.5, 1.5],
       [1.5, 1.5]])

我将不胜感激任何关于我是否以某种方式误解了结果或者这甚至可能是一个错误的反馈?我注意到,如果第一个索引是奇数,则不会出现相同的问题,而且 rfftirfft.

也没有等效问题

请注意,我在 iMac Pro (2017) 运行 macOS Mojave 上使用带有 Anaconda 发行版的 Python 3.8.8。

FFT 通常不处理奇数长度的输入。他们实际上想要 2 的幂。当您对奇数长度的实数向量进行 FFT 时,您会丢失一些信息。如果您尝试使用 (4,4) 进行实验,您会发现输出与输入完全匹配。

为了确保 irfft2 实际上是 rfft2 的逆向转换,您需要在逆向转换时让它知道输入数据的确切形状。

像这样:

import numpy as np
x = np.ones((4, 3))
ix = np.fft.rfft2(x)
rx = np.fft.irfft2(ix, x.shape)

这正是您在问题中强调的原因所必需的:转换后的数据(示例中的“频谱”,ix)表示为实值输入数据的方式(x) 取决于样本数量在任何维度上是奇数还是偶数。

(i)rfft* 系列函数都是针对输入数据是一系列实数的常见用例量身定制的,即 不是 复数。这种输入的离散傅里叶变换通常是复值的,但具有特殊的对称性:负频率分量是相应正频率分量的复共轭。也就是说,频谱两次包含基本相同的数字,一半的频谱已经包含重建输入数据所需的信息。这是有道理的:频谱是一系列复数,每个复数可以表示为两个实数,但输入数据没有那种“复杂性”,因为它是实数值。

话又说回来,当数据的长度(以及整个频谱的长度)可能是奇数或偶数时,“一半频谱”并不是一个明确的术语。从数学上讲,这两种情况的处理方式必须略有不同。这就是重构输入信号时需要数据长度的原因。

正如 NumPy documentation of rfft 对一维情况的注释:

If n is even, [the last array element of the spectrum] contains the term representing both positive and negative Nyquist frequency (+fs/2 and -fs/2), and must also be purely real. If n is odd, there is no term at fs/2; [the last array element of the spectrum] contains the largest positive frequency (fs/2*(n-1)/n), and is complex in the general case.

documentation of irfft 进一步说明:

The correct interpretation of the hermitian input depends on the length of the original data, as given by n. This is because each input shape could correspond to either an odd or even length signal. By default, irfft assumes an even output length which puts the last entry at the Nyquist frequency; aliasing with its symmetric counterpart. By Hermitian symmetry, the value is thus treated as purely real. To avoid losing information, the correct length of the real input must be given.

所以偶数长度的信号是默认的。这就是为什么你只 运行 进入这个问题的数组维度的奇数长度。 documentation of irfftn 特别指出它是 rfftn 的倒数,只有当像 irfftn(rfftn(x), x.shape).

这样调用时