numpy 中的 FFT 与 MATLAB 中的 FFT 没有相同的结果

FFT in numpy vs FFT in MATLAB do not have the same results

我有一个包含复数的向量(可以在 here 中找到),在 Python 和 MATLAB 中都有。我正在用

计算 ifft-转换
ifft(<vector>) 

在 MATLAB 中使用

np.fft.ifft(<vector>)

在 Python 中。我的问题是我从中得到了两个完全不同的结果,即 Python 中的向量很复杂,但它不在 MATLAB 中。虽然 MATLAB 中的某些组件为零,但 none 在 Python 中。这是为什么? fft-版本按预期工作。最小值在 1e-10 左右,即不会太低。

其实是一样的,只是Python以极高的精度显示了虚部。虚部显示的数值约为 10^{-12}.

这是我为在 MATLAB 中重构您的问题而写的内容:

format long g;
data = importdata('data.txt');
out = ifft(data);

format long g; 是一个格式选项,可以显示更多有效数字,我们显示 15 位有效数字,包括小数位。

当我显示反 FFT 输出的前 10 个元素时,我得到的是:

>> out(1:10)

ans =

         -6.08077329443768
         -5.90538963023573
         -5.72145198564976
         -5.53037208039314
         -5.33360059559345
         -5.13261402212083
         -4.92890104744583
         -4.72394865937531
         -4.51922820694745
         -4.31618153490126

对于 numpy,请注意复数是用 j 字母读入的,而不是 i。因此,当您加载文本时,您 必须 将所有 i 个字符转换为 j。完成后,您可以正常加载数据:

In [15]: import numpy as np

In [16]: with open('data.txt', 'r') as f:
   ....:     lines = map(lambda x: x.replace('i', 'j'), f)
   ....:     data = np.loadtxt(lines, dtype=np.complex)

当您打开文件时,对 map 的调用将获取文件的内容并将每个 i 字符转换为 j 和 return字符串列表,其中此列表中的每个元素都是文本文件中的复数,其中 i 替换为 j。然后我们将调用 numpy.loadtxt 函数将这些字符串转换为复数数组。

现在,当我采用 IFFT 并显示我们在 MATLAB 版本中看到的反转结果的前 10 个元素时,我们得到:

In [20]: out = np.fft.ifft(data)

In [21]: out[:10]
Out[21]: 
array([-6.08077329 +0.00000000e+00j, -5.90538963 +8.25472974e-12j,
       -5.72145199 +3.56159535e-12j, -5.53037208 -1.21875843e-11j,
       -5.33360060 +1.77529105e-11j, -5.13261402 -1.58326676e-11j,
       -4.92890105 -6.13731196e-12j, -4.72394866 +5.46673985e-12j,
       -4.51922821 -2.59774424e-11j, -4.31618154 -1.77484689e-11j])

如你所见,实部是一样的,但虚部仍然存在。但是,请注意虚部的幅度有多小。在这种情况下,MATLAB 选择不显示虚部,因为它们的量级非常小。实际上,从 MATLAB 中的 ifft 调用得到的数据类型 return 是实数,因此在调用 ifft 后可能有一些 post 处理以丢弃这些虚构的组件。 numpy 顺便说一句,它并没有做同样的事情,但您不妨认为这些组件非常小且无关紧要。


总而言之,Python 和 MATLAB 中的 ifft 调用本质上是相同的,但虚数部分在 Python/numpy returns 那些虚构的组件,即使它们是微不足道的,因为 MATLAB 中的 ifft 调用没有。另请注意,您需要确保将虚变量替换为 j,并且不能像您提供的原始文本文件中那样使用 i。如果您确定输出类型应该是实数,您也可以通过在ifft结果上调用numpy.real来删除虚部,如果您真希望。