root#
- scipy.optimize.root(fun, x0, args=(), method='hybr', jac=None, tol=None, callback=None, options=None)[源代码]#
查找向量函数的根。
- 参数:
- fun可调用对象
要查找根的向量函数。
假设可调用对象的签名为
f0(x, *my_args, **my_kwargs)
,其中my_args
和my_kwargs
是必需的位置参数和关键字参数。与其将f0
作为可调用对象传递,不如将其包装为仅接受x
;例如,将fun=lambda x: f0(x, *my_args, **my_kwargs)
作为可调用对象传递,其中my_args
(元组) 和my_kwargs
(字典) 在调用此函数之前已收集。- x0ndarray
初始猜测。
- argstuple,可选
传递给目标函数及其雅可比矩阵的额外参数。
- methodstr,可选
求解器的类型。应该为以下之一
- jacbool 或 callable,可选
如果 jac 是布尔值且为 True,则假定 fun 返回雅可比矩阵的值以及目标函数。如果为 False,则将以数值方式估计雅可比矩阵。jac 也可以是返回 fun 的雅可比矩阵的可调用对象。在这种情况下,它必须接受与 fun 相同的参数。
- tolfloat,可选
终止的容差。对于详细控制,请使用特定于求解器的选项。
- callbackfunction,可选
可选的回调函数。它在每次迭代时以
callback(x, f)
的形式调用,其中 x 是当前解,f 是相应的残差。适用于除 ‘hybr’ 和 ‘lm’ 以外的所有方法。- optionsdict,可选
求解器选项的字典。例如,xtol 或 maxiter,有关详细信息,请参阅
show_options()
。
- 返回:
- solOptimizeResult
以
OptimizeResult
对象表示的解。重要的属性为:x
解数组,success
指示算法是否成功退出的布尔标志,以及message
描述终止原因。有关其他属性的说明,请参阅OptimizeResult
。
另请参见
show_options
求解器接受的其他选项
说明
本节介绍可以通过 ‘method’ 参数选择的可用求解器。默认方法为 *hybr*。
方法 *hybr* 使用 MINPACK [1] 中实现的 Powell 混合方法的修改版本。
方法 *lm* 使用 MINPACK [1] 中实现的 Levenberg-Marquardt 算法的修改版本,以最小二乘法求解非线性方程组。
方法 *df-sane* 是一种无导数谱方法。[3]
方法 *broyden1*、*broyden2*、*anderson*、*linearmixing*、*diagbroyden*、*excitingmixing*、*krylov* 是不精确的牛顿方法,带有回溯或完整线搜索 [2]。每种方法都对应于特定的雅可比矩阵近似。
方法 *broyden1* 使用 Broyden 的第一个雅可比矩阵近似,它被称为 Broyden 的好方法。
方法 *broyden2* 使用 Broyden 的第二个雅可比矩阵近似,它被称为 Broyden 的坏方法。
方法 *anderson* 使用(扩展的)Anderson 混合。
方法 *Krylov* 使用 Krylov 近似来计算逆雅可比矩阵。它适用于大规模问题。
方法 *diagbroyden* 使用对角 Broyden 雅可比矩阵近似。
方法 *linearmixing* 使用标量雅可比矩阵近似。
方法 *excitingmixing* 使用调整后的对角雅可比矩阵近似。
警告
为方法 *diagbroyden*、*linearmixing* 和 *excitingmixing* 实现的算法可能对特定问题有用,但它们是否有效可能很大程度上取决于问题。
在版本 0.11.0 中添加。
参考文献
[1] (1,2)More, Jorge J., Burton S. Garbow, and Kenneth E. Hillstrom. 1980. User Guide for MINPACK-1.
[2]C. T. Kelley. 1995. Iterative Methods for Linear and Nonlinear Equations. Society for Industrial and Applied Mathematics. <https://archive.siam.org/books/kelley/fr16/>
[3]La Cruz, J.M. Martinez, M. Raydan. Math. Comp. 75, 1429 (2006).
示例
以下函数定义了非线性方程组及其雅可比矩阵。
>>> import numpy as np >>> def fun(x): ... return [x[0] + 0.5 * (x[0] - x[1])**3 - 1.0, ... 0.5 * (x[1] - x[0])**3 + x[1]]
>>> def jac(x): ... return np.array([[1 + 1.5 * (x[0] - x[1])**2, ... -1.5 * (x[0] - x[1])**2], ... [-1.5 * (x[1] - x[0])**2, ... 1 + 1.5 * (x[1] - x[0])**2]])
可以按如下方式获得解。
>>> from scipy import optimize >>> sol = optimize.root(fun, [0, 0], jac=jac, method='hybr') >>> sol.x array([ 0.8411639, 0.1588361])
大型问题
假设我们需要在正方形 \([0,1]\times[0,1]\) 上求解以下积分微分方程
\[\nabla^2 P = 10 \left(\int_0^1\int_0^1\cosh(P)\,dx\,dy\right)^2\]其中 \(P(x,1) = 1\),在正方形边界的其他位置 \(P=0\)。
可以使用
method='krylov'
求解器找到解>>> from scipy import optimize >>> # parameters >>> nx, ny = 75, 75 >>> hx, hy = 1./(nx-1), 1./(ny-1)
>>> P_left, P_right = 0, 0 >>> P_top, P_bottom = 1, 0
>>> def residual(P): ... d2x = np.zeros_like(P) ... d2y = np.zeros_like(P) ... ... d2x[1:-1] = (P[2:] - 2*P[1:-1] + P[:-2]) / hx/hx ... d2x[0] = (P[1] - 2*P[0] + P_left)/hx/hx ... d2x[-1] = (P_right - 2*P[-1] + P[-2])/hx/hx ... ... d2y[:,1:-1] = (P[:,2:] - 2*P[:,1:-1] + P[:,:-2])/hy/hy ... d2y[:,0] = (P[:,1] - 2*P[:,0] + P_bottom)/hy/hy ... d2y[:,-1] = (P_top - 2*P[:,-1] + P[:,-2])/hy/hy ... ... return d2x + d2y - 10*np.cosh(P).mean()**2
>>> guess = np.zeros((nx, ny), float) >>> sol = optimize.root(residual, guess, method='krylov') >>> print('Residual: %g' % abs(residual(sol.x)).max()) Residual: 5.7972e-06 # may vary
>>> import matplotlib.pyplot as plt >>> x, y = np.mgrid[0:1:(nx*1j), 0:1:(ny*1j)] >>> plt.pcolormesh(x, y, sol.x, shading='gouraud') >>> plt.colorbar() >>> plt.show()