numpy中的FFT与MATLAB中的FFT没有相同的结果 [英] FFT in numpy vs FFT in MATLAB do not have the same results
问题描述
我有一个带有复数的向量(可以在此处),无论是在Python中还是在MATLAB中.我正在用
计算ifft
-变换
I have a vector with complex numbers (can be found here), both in Python and in MATLAB. I am calculating the ifft
-transformation with
ifft(<vector>)
在MATLAB中和
np.fft.ifft(<vector>)
在Python中.我的问题是我从中得到两个完全不同的结果,即虽然Python中的向量很复杂,但MATLAB中却没有.虽然MATLAB中的某些组件为零,但Python中没有.这是为什么? fft
-版本按预期工作.最小值在1e-10
左右,即不太低.
in Python. My problem is that I get two completely different results out of it, i.e. while the vector in Python is complex, it is not in MATLAB. While some components in MATLAB are zero, none are in Python. Why is that? The fft
-version works as intended. The minimal values are at around 1e-10
, i.e. not too low.
推荐答案
实际上,它们是相同的,但是Python以极高的精度显示了虚部.虚部的数值显示为10^{-12}
左右.
Actually, they are the same but Python is showing the imaginary part with extremely high precision. The imaginary components are being shown with values with a magnitude of around 10^{-12}
.
这是我写的在MATLAB中重构您的问题的内容:
Here's what I wrote to reconstruct your problem in MATLAB:
format long g;
data = importdata('data.txt');
out = ifft(data);
format long g;
是一种格式设置选项,可向您显示更高的有效位数,而我们显示的15个有效位数(包括小数位).
format long g;
is a formatting option that shows you more significant digits where we show 15 significant digits including decimal places.
当我显示反FFT输出的前10个元素时,这就是我得到的:
When I show the first 10 elements of the inverse FFT output, this is what I get:
>> 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
.完成后,您可以正常加载数据:
For numpy
, be advised that complex numbers are read in with the j
letter, not i
. Therefore when you load in your text, you must transform all i
characters to j
. Once you do that, you can load in the data as normal:
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
并返回字符串列表,其中该列表中的每个元素都是复杂的i
替换为j
的文本文件中的数字.然后,我们将调用numpy.loadtxt
函数将这些字符串转换为复数数组.
When you open up the file, the call to map
would thus take the contents of the file and transform each i
character into j
and return a list of strings where each element in this list is a complex number in your text file with the i
replaced as j
. We would then call numpy.loadtxt
function to convert these strings into an array of complex numbers.
现在,当我进行IFFT并显示反演结果的前10个元素时(如我们在MATLAB版本中看到的那样),我们得到:
Now when I take the IFFT and display the first 10 elements of the inversed result as we saw with the MATLAB version, we get:
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
调用返回的数据类型是真实的,因此在调用ifft
丢弃这些虚构分量后可能会进行一些后处理. numpy
不会做相同的事情,但您最好将这些组件视为很小且无关紧要的.
As you can see the real part is the same but the imaginary part still exists. However, note how small in magnitude the imaginary components are. MATLAB in this case chose to not display the imaginary components because their magnitudes are very small. Actually, the data type returned from the ifft
call in MATLAB is real so there was probably some post-processing after ifft
was called to discard these imaginary components. numpy
does not do the same thing by the way but you might as well consider these components to be very small and insignificant.
总而言之,Python和MATLAB中的ifft
调用在本质上是相同的,但是虚构组件在某种意义上不同,即Python/numpy
返回这些虚构组件,即使它们与ifft
无关紧要.在MATLAB中没有调用.另请注意,您需要确保将虚数变量替换为j
,并且不能像提供的原始文本文件中那样使用i
.如果确定肯定,则输出类型应该是实数,也可以通过调用ifft
结果上的numpy.real
来删除虚部.
All in all, both ifft
calls in Python and MATLAB are essentially the same but the imaginary components are different in the sense that Python/numpy
returns those imaginary components even though they are insignificant where as the ifft
call in MATLAB does not. Also take note that you need to ensure that the imaginary variable is replaced with j
and you can't use i
as in the original text file you've provided. If you know for certain that the output type should be real, you can also drop the imaginary components by giving a call to numpy.real
on the ifft
result if you so wish.
这篇关于numpy中的FFT与MATLAB中的FFT没有相同的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!