You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

脉冲傅里叶变换Python绘图问题:实部与sinc曲线不一致原因排查

问题:Python绘制脉冲傅里叶变换时实部与sinc曲线不一致的原因

问题背景

我尝试用Python绘制脉冲信号的傅里叶变换,代码如下:

import numpy as np
import matplotlib.pyplot as plt
def pulse(time, L=1, A=1, C=0):
    return [A * int(C-L/2 <= t <= C+L/2) for t in time]
# data
time = np.arange(-5, 5, 0.01)
freq = np.arange(-5, 5, 0.01)
signal = pulse(time)
fourier = [np.mean(signal * np.exp(-2j * np.pi * f * time)) for f in freq]
# figure
fig, axs = plt.subplots(nrows=3, figsize=(6, 6))
# original signal
axs[0].grid(True)
axs[0].set_ylabel('f(t)')
axs[0].plot(time, signal)
# real part fourier transform
axs[1].grid(True)
axs[1].set_ylabel('Re(F{f})')
axs[1].plot(freq, np.real(fourier))
# Fourier{pulse(width)} = width * sinc(PI * f * width)
axs[2].grid(True)
axs[2].set_ylabel('sinc(f)')
axs[2].plot(freq, np.sinc(np.pi*freq))
# show
fig.canvas.set_window_title('Fourier Transform')
plt.show()

运行后发现傅里叶变换实部和sinc曲线不完全一致,怀疑问题出在freq = np.arange(-5, 5, 0.01)和fourier = [np.mean(signal * np.exp(-2j * np.pi * f * time)) for f in freq]这两行,请问原因是什么?


问题分析与解决

嘿,你找对方向了,问题确实出在你怀疑的那两行,主要有两个核心原因:

1. 傅里叶变换的离散近似错误

你用np.mean()来近似计算傅里叶变换,但标准的连续傅里叶变换是积分形式:

$F(f) = \int_{-\infty}^{\infty} f(t) e^{-2j\pi f t} dt$

当用离散采样点近似这个积分时,应该用采样间隔乘以采样点的求和,而不是取平均。你的时间采样间隔是0.01,np.mean()相当于把求和结果除以了采样点总数,这会引入一个错误的缩放系数。

修正方法是把np.mean()换成np.sum()再乘以采样间隔dt:

dt = 0.01
fourier = [dt * np.sum(signal * np.exp(-2j * np.pi * f * time)) for f in freq]

2. Numpy的sinc函数定义理解偏差

Numpy中的np.sinc(x)定义是:$\text{sinc}(x) = \frac{\sin(\pi x)}{\pi x}$,而宽度为1、幅度为1的矩形脉冲的傅里叶变换理论值是$F(f) = \text{sinc}(f)$(对应$\frac{\sin(\pi f)}{\pi f}$)。但你现在绘制的是np.sinc(np.pi*freq),这相当于$\frac{\sin(\pi \cdot \pi f)}{\pi \cdot \pi f}$,和理论公式完全不符!

修正方法是直接使用np.sinc(freq)来绘制理论曲线:

axs[2].plot(freq, np.sinc(freq))

修正后的关键代码片段

把这两处修改后,关键代码部分应该是这样:

dt = 0.01
time = np.arange(-5, 5, dt)
freq = np.arange(-5, 5, 0.01)
signal = pulse(time)
# 修正傅里叶变换计算
fourier = [dt * np.sum(signal * np.exp(-2j * np.pi * f * time)) for f in freq]
# 修正sinc曲线绘制
axs[2].set_ylabel('sinc(f)')
axs[2].plot(freq, np.sinc(freq))

这样调整后,傅里叶变换的实部曲线就会和理论的sinc曲线完全重合了。


内容的提问来源于stack exchange,提问作者Omar Aflak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:37:45