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

如何用Python绘制傅里叶级数图像?求修复维度不匹配错误

解决傅里叶级数绘图的维度不匹配问题及代码修正

首先来看你遇到的ValueError: x and y must have same first dimension错误,这是因为你生成的x_是包含10000个点的数组,但st只是5个单一数值的列表——你在循环里每次调用s(1,6),只计算了t=1这一个点的函数值,自然无法和长度为10000的x_匹配绘制曲线。

除此之外,你的代码还有一处关键笔误会导致傅里叶级数计算错误:在s(t,n)函数的正弦项里,你用了n代替循环变量i,这会让所有谐波项都使用同一个n值,而非当前循环的第i次谐波。

下面是修正后的完整代码,我会逐点解释修改的地方:

import numpy as np
import matplotlib.pyplot as plt

# 生成x轴数据,10000个点覆盖0到30
x_ = np.linspace(0, 30, 10000)
a0 = 3/5
f0 = 5

# 修正a(n)和b(n)的写法,确保系数计算符合公式
def a(n):
    return (1/(n * np.pi)) * (np.sin(0.4 * n * np.pi) + np.sin(0.8 * n * np.pi))

def b(n):
    return (1/(n * np.pi)) * (2 - np.cos(0.4 * n * np.pi) - np.cos(0.8 * n * np.pi))

# 修正s(t,n)函数:正弦项的谐波次数用i而非n,同时支持数组输入
def s(t, n_terms):
    temp = np.zeros_like(t)  # 创建和t同形状的零数组用于累加
    for i in range(1, n_terms + 1):
        # 修正正弦项的i,对应第i次谐波
        temp += a(i) * np.cos(2 * np.pi * i * f0 * t) + b(i) * np.sin(2 * np.pi * i * f0 * t)
    temp += a0  # 加上直流分量a0
    return temp

# 生成不同项数的傅里叶级数结果:每个n对应x_上所有点的函数值
st_list = []
for n in range(1, 6):
    st_list.append(s(x_, n))

# 绘制所有曲线并优化可视化
plt.title("Fourier Series Approximation (n=1 to 5)")
labels = [f"n={n}" for n in range(1,6)]
for st, label in zip(st_list, labels):
    plt.plot(x_, st, label=label)

plt.legend()
plt.xlabel("t")
plt.ylabel("s(t)")
plt.show()

关键修改点说明:

  1. 维度匹配修正:

    • 让s(t, n_terms)函数接受数组类型的t输入(比如x_),返回同样长度的数组,这样每个n对应的结果都和x_维度一致,可以正常绘制。
    • 生成st_list时,对每个n调用s(x_, n),计算整个x_区间的函数值,而非单一的t=1点。
  2. 傅里叶级数计算修正:

    • 把正弦项里的2 * np.pi * n * f0 * t改成2 * np.pi * i * f0 * t,确保第i次谐波使用正确的次数i。
    • 调整了a(n)和b(n)的括号位置,确保1/(n*np.pi)是整体系数(原代码的1/n * np.pi等价于np.pi/n,和你注释里的公式不符)。
  3. 可视化优化:

    • 添加了图例、坐标轴标签,方便观察不同项数的傅里叶级数逼近效果。

如果你想进一步提升代码效率,可以用numpy的向量化操作代替循环,尤其当n_terms很大时:

def s_vectorized(t, n_terms):
    n = np.arange(1, n_terms+1)
    an = (1/(n * np.pi)) * (np.sin(0.4 * n * np.pi) + np.sin(0.8 * n * np.pi))
    bn = (1/(n * np.pi)) * (2 - np.cos(0.4 * n * np.pi) - np.cos(0.8 * n * np.pi))
    # 利用广播机制一次性计算所有谐波项的和
    cos_terms = an * np.cos(2 * np.pi * n[:, None] * f0 * t)
    sin_terms = bn * np.sin(2 * np.pi * n[:, None] * f0 * t)
    return a0 + np.sum(cos_terms + sin_terms, axis=0)

这个版本利用numpy的广播特性,避免了Python层面的循环,计算速度会快很多。

内容的提问来源于stack exchange,提问作者Chatchai W.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:48:42