无法生成loglog图求助:辛普森积分误差可视化问题
代码问题分析与修正
你的代码无法生成loglog图主要是缩进错误、函数逻辑混乱、绘图顺序错误导致的,以下是具体问题和修正后的代码:
核心问题点
- 缩进错误:
integrate_analytic、error及绘图代码都被错误缩进在simpsonsRule函数内部,导致这些函数无法被外部正常调用。 - Simpson函数参数滥用:你直接把函数参数
n替换成固定列表,导致函数无法接收单个面板数参数,且数值计算时会因列表参与运算报错。 - 绘图逻辑颠倒:调用
plt.loglog时所需的误差变量还未定义,且先绘图再创建画布的顺序完全错误;同时loglog图需要传入x轴(面板数n)和y轴(对应误差值),而非同一变量重复传入。
修正后的完整代码
import matplotlib.pyplot as plt import numpy %matplotlib inline def bounds(): a = 0 b = 2 return a, b def f(x): return x**2 * numpy.cos(2*x) def simpsonsRule(n): # 接收单个整数n作为面板数,不再硬编码列表 a, b = bounds() total = f(a) + f(b) # 不用float()初始化,直接赋值更清晰 h = (b - a) / n # Simpson法则的步长,n是面板数(偶数) # 奇数项求和(i从1到n-1,步长2) odd_sum = sum(f(a + i*h) for i in range(1, n, 2)) # 偶数项求和(i从2到n-2,步长2) even_sum = sum(f(a + i*h) for i in range(2, n-1, 2)) total += 4 * odd_sum + 2 * even_sum return total * h / 3 def integrate_analytic(a, b): # 解析解函数,修正缩进到全局作用域 term_b = ((2*b**2 - 1)*numpy.sin(2*b) + 2*b*numpy.cos(2*b)) / 4 term_a = ((2*a**2 - 1)*numpy.sin(2*a) + 2*a*numpy.cos(2*a)) / 4 return term_b - term_a def error(n, a, b): # 计算分数误差,取绝对值更适合loglog图 numerical = simpsonsRule(n) analytic = integrate_analytic(a, b) return abs((numerical - analytic) / analytic) # 定义要测试的面板数列表 n_list = [4, 8, 16, 32, 64, 128, 256, 512, 1024] a, b = bounds() # 计算每个n对应的误差 error_list = [error(n, a, b) for n in n_list] # 绘制loglog图 plt.figure(figsize=(8, 4)) plt.loglog(n_list, error_list, marker='o', label='Simpson法则分数误差') plt.xlabel('面板数n') plt.ylabel('分数误差') plt.title('Simpson法则分数误差随面板数变化') plt.legend() plt.grid(True, which="both", ls="-") plt.show() # 打印误差值 for n, err in zip(n_list, error_list): print(f"面板数{n}: 分数误差{err}")
修正说明
- 修复缩进:将
integrate_analytic、error函数移到全局作用域,确保可正常调用。 - 重构Simpson函数:让函数接收单个整数n作为参数,用更简洁的生成式求和替代循环,修正步长计算逻辑(Simpson法则要求n为偶数,这里传入的列表都是偶数,符合要求)。
- 调整绘图逻辑:先创建画布,再计算所有n对应的误差值,最后调用
plt.loglog传入n列表和误差列表,添加坐标轴标签、标题和网格,让图更清晰。 - 误差取绝对值:分数误差可能为负,取绝对值后在loglog图上更易观察收敛趋势。
内容的提问来源于stack exchange,提问作者ebb
相关产品推荐
相关产品推荐

