#python #numpy
#python #numpy
Вопрос:
Я реализую алгоритм быстрого преобразования Фурье (FFT) на Python, и из-за сложных манипуляций с числами (или, может быть, просто из-за сложности, присущей компьютеру для обработки чисел с плавающей запятой), много раз я получаю незначительные отклонения от ожидаемого значения.
Мне пришлось использовать numpy.around
для округления результата вычислений до приемлемой точности (10 знаков после запятой). Из-за этого я иногда получаю такие числа, как -0 0j. На первый взгляд это может показаться не такой уж большой проблемой, но последующие вычисления включали поиск аргументов комплексных чисел (для фазового спектра). Поэтому я получил неправильные значения, поскольку знаки играют огромную роль в вычислениях.
Есть ли какой-либо способ преобразовать эти результаты -0 в 0? Немного кода приведено ниже. В центре внимания здесь находится оператор return в fft(f)
функции.
...
def fft(f):
Ni = len(f)
Mi = int(Ni / 2)
if Mi <= 2:
return [f[0] f[1] f[2] f[3],
f[0] - 1j*f[1] - f[2] 1j*f[3],
f[0] - f[1] f[2] - f[3],
f[0] 1j*f[1] - f[2] - 1j*f[3]]
wn = math.cos(2*math.pi/Ni) - 1j*math.sin(2*math.pi/Ni)
fe = [f[i] for i in range(Ni) if i % 2 == 0]
fo = [f[i] for i in range(Ni) if i % 2 == 1]
Fe = fft(fe)
Fo = fft(fo)
return [np.around(Fe[i] (wn**i)*Fo[i], decimals=10) for i in range(Mi)] [np.around(Fe[i] - (wn**i)*Fo[i], decimals=10) for i in range(Mi)]
x = [np.around(signal(n*tp/N), decimals=10) for n in range(N)] # input sequence
_X = fft(x) # discrete Fourier transform
X = [Xi/N for Xi in _X] # frequency spectrum
X_amp = [np.absolute(Xi) for Xi in X] # amplitude spectrum
X_phase = [np.angle(Xi) for Xi in X] # phase spectrum
Ответ №1:
Не существует общего способа избежать этого — отрицательный ноль — это действительно просто реальность работы с числами с плавающей запятой.
Если вы хотите, чтобы комплексный аргумент был равен нулю для случая отрицательного нуля, то вы могли бы сделать что-то вроде этого, чтобы заменить его на «положительный» ноль:
X_phase = [np.angle(Xi if Xi else 0 0j) for Xi in X] # phase spectrum
Это заменит все нулевые значения независимо от знака значением, имеющим «положительные» действительные и мнимые части.