Как исправить проблему -0 в numpy.around () - PullRequest
1 голос
/ 22 апреля 2019

Я реализую алгоритм быстрого преобразования Фурье (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 Ответ

1 голос
/ 22 апреля 2019

Нет общего способа избежать этого - отрицательный ноль - это просто реальность работы с числами с плавающей запятой.

Если вы хотите, чтобы комплексный аргумент был нулем для случая отрицательного нуля, то вы можете сделать что-то вроде этого, чтобы заменить его «положительным» нулем:

X_phase = [np.angle(Xi if Xi else 0+0j) for Xi in X] # phase spectrum

Это заменит все нулевые значения независимо от знака значением, имеющим «положительные» действительные и мнимые части.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...