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

2024-09-30 05:15:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我对NumPy中rfft2irfft2的以下行为感到困惑。如果我从一个实矩阵开始,它是mxn,其中n是奇数,那么如果我取rfft2,然后是irfft2,我最终得到一个mx(n-1)矩阵。因为irfft2rfft2的倒数,所以我希望得到一个大小为mxn的矩阵。此外,矩阵中的值不是我开始使用的值——请参见下面的输出

>>> 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]])

我将非常感谢任何关于我是否以某种方式误解了结果的反馈,或者这可能是一个bug?我注意到,如果第一个索引是奇数,并且rfftirfft没有等价的问题,则不会出现相同的问题

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


Tags: importfftnumpyasnp矩阵rxix
2条回答

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)

这正是您在问题中强调的原因:实值输入数据(x)的转换数据(示例中的“光谱”)表示方式取决于样本数在任何维度中是奇数还是偶数

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

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

正如一维情形的NumPydocumentation of ^{}注释所示:

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 ^{}进一步解释:

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(x), x.shape)一样调用时,它才是rfftn的逆

相关问题 更多 >

    热门问题