如何在Jupyter Notebook中用Sagemath实现牛顿-拉夫逊方法动画?
实现牛顿-拉夫逊方法动画的步骤
核心思路
牛顿法动画的核心是可视化每一步迭代逻辑:
- 保留原函数的基础曲线
- 标记当前迭代点
(xₙ, f(xₙ)) - 绘制该点处的切线(切线方程:
y = f(xₙ) + f’(xₙ)(x - xₙ)) - 标记切线与x轴的交点
(xₙ₊₁, 0) - 用线段连接
(xₙ,0)→(xₙ,f(xₙ))→(xₙ₊₁,0),直观展示迭代路径
具体实现(Python + Matplotlib)
以下是通用Python环境下的实现代码,适配你已有的函数:
1. 导入依赖库
import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation
2. 定义函数与导数
def f(x): return 4 * x**3 - 4 * x - 1 def df(x): return 12 * x**2 - 4
3. 预计算迭代序列
先算出所有收敛前的迭代点,避免动画实时计算卡顿:
# 初始迭代点(可替换为你之前用的f0值,比如1.5) x0 = 1.5 iterations = [x0] tolerance = 1e-6 # 收敛判定阈值 # 生成迭代点直到收敛 while True: x_next = iterations[-1] - f(iterations[-1]) / df(iterations[-1]) if abs(x_next - iterations[-1]) < tolerance: break iterations.append(x_next)
4. 设置绘图基础元素
# 生成函数图像的x范围 x = np.linspace(-2, 2, 400) y = f(x) # 创建画布与坐标轴 fig, ax = plt.subplots(figsize=(8, 6)) ax.plot(x, y, label=r'$f(x)=4x^3-4x-1$', color='blue') ax.axhline(y=0, color='black', linestyle='--', label='x轴') ax.set_xlim(-2, 2) ax.set_ylim(-5, 5) ax.set_xlabel('x') ax.set_ylabel('f(x)') ax.legend() ax.grid(True) # 初始化动画元素 current_point, = ax.plot([], [], 'ro', markersize=8) # 当前迭代点(红色) tangent_line, = ax.plot([], [], 'g--', linewidth=2) # 切线(绿色虚线) iteration_path, = ax.plot([], [], 'r-', linewidth=1) # 迭代路径线段 info_text = ax.text(0.02, 0.95, '', transform=ax.transAxes) # 迭代信息文本
5. 定义动画更新函数
def update(frame): x_n = iterations[frame] fx_n = f(x_n) # 更新当前迭代点 current_point.set_data([x_n], [fx_n]) # 计算并更新切线 tangent_x = np.linspace(x_n - 1, x_n + 1, 100) tangent_y = fx_n + df(x_n) * (tangent_x - x_n) tangent_line.set_data(tangent_x, tangent_y) # 更新迭代路径与信息文本 if frame < len(iterations) - 1: x_next = iterations[frame + 1] path_x = [x_n, x_n, x_next] path_y = [0, fx_n, 0] iteration_path.set_data(path_x, path_y) info_text.set_text(f'迭代次数: {frame+1}\n当前x: {x_n:.4f}\n下一个x: {x_next:.4f}') else: # 最后一步显示收敛结果 iteration_path.set_data([], []) info_text.set_text(f'迭代完成\n收敛根: {x_n:.6f}') return current_point, tangent_line, iteration_path, info_text
6. 生成并播放动画
# 创建动画,interval控制每帧停留毫秒数 ani = FuncAnimation(fig, update, frames=len(iterations), interval=1500, blit=True) # 可选:保存动画(需安装ffmpeg) # ani.save('newton_raphson_animation.mp4', writer='ffmpeg', dpi=100) plt.show()
SageMath环境适配(如果你用Sage)
如果是在SageMath中操作,可改用内置animate函数:
f(x) = 4*x^3 - 4*x - 1 df(x) = derivative(f, x) # 生成迭代序列 x0 = 1.5 iterations = [x0] while abs(iterations[-1] - (iterations[-1] - f(iterations[-1])/df(iterations[-1]))) > 1e-6: iterations.append(iterations[-1] - f(iterations[-1])/df(iterations[-1])) # 生成每帧图像 plots = [] for i in range(len(iterations)): p = plot(f, xmin=-2, xmax=2, ymin=-5, ymax=5) x_n = iterations[i] p += point((x_n, f(x_n)), color='red', size=40) # 绘制切线 tangent(x) = f(x_n) + df(x_n)*(x - x_n) p += plot(tangent, xmin=x_n-1, xmax=x_n+1, color='green', linestyle='--') if i < len(iterations)-1: x_next = iterations[i+1] p += line([(x_n,0), (x_n,f(x_n)), (x_next,0)], color='red') p += text(f'迭代 {i+1}: x={x_n:.4f}', (-1.8, 4), color='black') else: p += text(f'收敛根: {x_n:.6f}', (-1.8, 4), color='black') plots.append(p) # 播放动画 ani = animate(plots, interval=1500) show(ani)
关键注意点
- 更换初始点
x0(比如-1、0、1.5)可观察不同根的迭代路径 - 调整
interval参数可控制动画播放速度 - 保存动画需确保环境安装对应依赖(Python需ffmpeg,Sage无需额外配置)
内容的提问来源于stack exchange,提问作者EarthJump
相关产品推荐
相关产品推荐

