我正在Python上实现快速傅立叶变换(FFT)算法,由于涉及到复杂的数字操作(或者可能仅仅是由于计算机处理浮点数的固有困难),很多时候我会出现微小的偏差从期望值。
我必须使用numpy.around
将计算结果四舍五入到可接受的精度(小数点后十位)。因此,有时我会得到-0 + 0j之类的数字。从表面上看,这似乎不是一个大问题,但随后的计算涉及寻找复数的论点(针对相位谱)。因此,我得到了错误的值,因为符号在计算中起着巨大的作用。
有什么办法可以将这些-0结果转换为0?下面给出了一些代码。这里的重点是fft(f)
函数中的return语句。
...
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
答案 0 :(得分:1)
没有通用的方法可以避免这种情况-负零确实只是使用浮点数的现实。
如果您希望在负零的情况下将复数参数设为零,则可以执行以下操作将其替换为“正”零:
X_phase = [np.angle(Xi if Xi else 0+0j) for Xi in X] # phase spectrum
这会将所有零值(无论符号如何)替换为具有“正”实部和虚部的值。