自定义逆傅里叶变换函数无法还原原正弦波,求问题排查
分析你的逆傅里叶变换函数问题
先梳理下你遇到的情况:你的自定义DFT能正确生成正弦波的功率谱,但对应的IFT无法还原原始信号。我来拆解下你的IFT函数里的几个关键错误:
1. 核心维度与目标对象搞反了
你的DFT接收的是长度为N1的原始信号x和长度为k的频率数组frequencies,输出的是长度为k的频域结果fourier。那逆变换的目标应该是从频域结果(长度k)还原出长度为N1的原始时间信号,但你的IFT函数:
- 把
N定义成了fft.size(也就是k),用这个生成了时间索引n = np.arange(N) - 输出的
inverse_fourier是长度k的数组,完全不符合原始信号的长度要求
你需要把原始信号的时间点数量(也就是len(time),对应你DFT里的N1)传入IFT函数,才能匹配维度。
2. 指数符号错误
DFT中你用的是负指数:exp(-2j*np.pi*frequencies[i]*t),而逆傅里叶变换需要用正指数才能还原信号,你现在IFT里还是用了负指数,这会直接导致相位完全反转,无法还原。
3. 缩放因子不匹配
你的DFT里给每个频率分量乘了1/k的缩放因子,为了让逆变换能正确还原,IFT需要乘回对应的k来抵消这个缩放,否则还原出的信号幅度会完全不对。
4. 循环逻辑错误
你现在的循环是遍历频率索引,生成对应频率的结果,但逆变换应该遍历原始时间点,对每个时间点计算所有频率分量的叠加。
修正后的IFT函数
结合以上问题,我调整了你的IFT函数,同时需要传入原始的时间数组来匹配DFT的输入维度:
def IFT(fft, frequencies, time): # 获取原始信号的时间点数量(对应DFT里的N1) N1 = time.size # 频域结果的长度(对应DFT里的k) k = fft.size # 初始化输出的时域信号,注意要用复数类型,避免截断虚部 inverse_fourier = np.zeros(N1, dtype=np.complex128) for i in range(N1): # 对每个时间点,计算所有频率分量的叠加,用正指数,乘回k抵消DFT的缩放 inverse_fourier[i] = k * np.dot(fft, np.exp(2j * np.pi * frequencies * time[i])) # 因为原始信号是实信号,取实部即可(虚部应该非常小,是浮点误差) return np.real(inverse_fourier)
测试验证
用你的原始信号测试修正后的函数:
# 先计算DFT fourier_result = DFT(signal, freq) # 用修正后的IFT还原信号 recovered_signal = IFT(fourier_result, freq, time) # 绘制原始信号和还原信号对比 plt.plot(time, signal, label='Original Signal') plt.plot(time, recovered_signal, label='Recovered Signal', linestyle='--') plt.xlabel('Time') plt.title('Original vs Recovered Sine Wave') plt.legend() plt.grid() plt.show()
这样应该就能完美还原原始的正弦波了。
内容的提问来源于stack exchange,提问作者wabash
相关产品推荐
相关产品推荐

