牛顿优化问题中,如何用Python库自动求解函数的一、二阶导数?
用Python库自动求解函数的一、二阶导数(牛顿优化场景)
针对你需要计算函数 $f(x)=2\sin(x)-\frac{x^2}{10}$ 在 $x=2.5$ 处的一、二阶导数,并整合到牛顿优化中的需求,以下是两种可行的自动求导方案:
一、SymPy符号求导(精确解)
SymPy是符号计算库,能生成精确的导数表达式,再代入数值计算,适合需要高精度导数的场景。你之前报错大概率是符号变量与数值变量混用导致的,正确用法如下:
import sympy as sp import numpy as np def Newton_sympy(x0): # 定义符号变量 x_sym = sp.symbols('x') # 定义原函数(符号形式) f_sym = 2 * sp.sin(x_sym) - (x_sym**2)/10 # 求一、二阶导数(符号形式) f1_sym = sp.diff(f_sym, x_sym) f2_sym = sp.diff(f1_sym, x_sym) # 将符号函数转换为可计算数值的函数 f = sp.lambdify(x_sym, f_sym, 'numpy') f1 = sp.lambdify(x_sym, f1_sym, 'numpy') f2 = sp.lambdify(x_sym, f2_sym, 'numpy') # 计算x0处的函数值和导数值 f_x0 = f(x0) f_x1 = f1(x0) f_x2 = f2(x0) # 牛顿迭代步骤 x1 = x0 - (f_x1 / f_x2) return x0, f_x0, f_x1, f_x2, x1 # 测试x=2.5的情况 result = Newton_sympy(2.5) print(f"初始x: {result[0]}, 函数值: {result[1]}, 一阶导数: {result[2]}, 二阶导数: {result[3]}, 迭代后x: {result[4]}")
二、NumPy数值求导(近似解)
如果只需要数值结果,不需要精确的导数表达式,可以用数值差分法。注意np.diff是计算数组相邻元素的差,不是单点导数的正确计算方式,推荐用精度更高的中心差分法:
import numpy as np def Newton_numpy(x0, h=1e-6): # 定义原函数 f = lambda x: 2 * np.sin(x) - (x**2)/10 # 中心差分计算一阶导数 f_x1 = (f(x0 + h) - f(x0 - h)) / (2 * h) # 中心差分计算二阶导数 f_x2 = (f(x0 + h) - 2 * f(x0) + f(x0 - h)) / (h**2) f_x0 = f(x0) # 牛顿迭代步骤 x1 = x0 - (f_x1 / f_x2) return x0, f_x0, f_x1, f_x2, x1 # 测试x=2.5的情况 result = Newton_numpy(2.5) print(f"初始x: {result[0]}, 函数值: {result[1]}, 一阶导数: {result[2]}, 二阶导数: {result[3]}, 迭代后x: {result[4]}")
说明
- SymPy方案能得到精确的导数表达式,避免手动求导出错,适合需要推导或高精度计算的场景。
- NumPy数值求导适合只需要数值结果的场景,h的取值会影响精度,一般取1e-6~1e-8即可。
内容的提问来源于stack exchange,提问作者Jim Raynor
相关产品推荐
相关产品推荐

