Что IFFT возвращает в Python? - PullRequest
3 голосов
/ 23 мая 2019

Мне нужно обратное преобразование Фурье сложного массива. ifft должен возвращать реальный массив, но он возвращает другой сложный массив.

В MATLAB, a=ifft(fft(a)), но в Python это так не работает.

a = np.arange(6)
m = ifft(fft(a))
m # Google says m should = a, but m is complex

Выход:

array([0.+0.00000000e+00j, 1.+3.70074342e-16j, 2.+0.00000000e+00j,
       3.-5.68396583e-17j, 4.+0.00000000e+00j, 5.-3.13234683e-16j])

Ответы [ 4 ]

6 голосов
/ 23 мая 2019

Мнимая часть - это ошибка вычисления числа с плавающей точностью результата. Если оно очень маленькое, его можно отбросить.

Numpy имеет встроенную функцию real_if_close, для этого:

>>> np.real_if_close(np.fft.ifft(np.fft.fft(a)))
array([0., 1., 2., 3., 4., 5.])

Вы можете прочитать об ограничениях плавающей системы здесь: https://docs.python.org/3.8/tutorial/floatingpoint.html

3 голосов
/ 23 мая 2019

если мнимая часть близка к нулю, вы можете отбросить ее:

import numpy as np

arr = np.array(
    [
        0.0 + 0.00000000e00j,
        1.0 + 3.70074342e-16j,
        2.0 + 0.00000000e00j,
        3.0 - 5.68396583e-17j,
        4.0 + 0.00000000e00j,
        5.0 - 3.13234683e-16j,
    ]
)

if all(np.isclose(arr.imag, 0)):
    arr = arr.real
# [ 0.  1.  2.  3.  4.  5.]

(это то, что real_if_close делает в одной строке, как в ответе R2RT ).

2 голосов
/ 23 мая 2019

Вы ошибаетесь в "Ifft должен вернуть реальный массив".Если вы хотите получить реальный вывод (т. Е. У вас есть полные значения реальных данных, и теперь вы хотите выполнить ifft), вы должны использовать irfft.

См. Этот пример из документов :

>>> np.fft.ifft([1, -1j, -1, 1j])
array([ 0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j])   #Output is complex which is correct
>>> np.fft.irfft([1, -1j, -1])
array([ 0.,  1.,  0.,  0.])   #Output is real valued
1 голос
/ 23 мая 2019

Вы можете проверить, как это:

import numpy as np
from numpy import fft
a = np.arange(6)
print(a)
f = np.fft.fft(a)
print(f)
m = np.fft.ifft(f)
print(m)

[0 1 2 3 4 5]
[15.+0.j         -3.+5.19615242j -3.+1.73205081j -3.+0.j
 -3.-1.73205081j -3.-5.19615242j]
[0.+0.j 1.+0.j 2.+0.j 3.+0.j 4.+0.j 5.+0.j]

Чтобы получить реальную часть, вы можете использовать:

print(m.real) # [0. 1. 2. 3. 4. 5.]
...