当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python SciPy optimize.root用法及代码示例


本文简要介绍 python 语言中 scipy.optimize.root 的用法。

用法:

scipy.optimize.root(fun, x0, args=(), method='hybr', jac=None, tol=None, callback=None, options=None)#

求向量函数的根。

参数

fun 可调用的

求根的向量函数。

x0 ndarray

初步猜测。

args 元组,可选

传递给目标函数及其雅可比行列式的额外参数。

method str,可选

求解器的类型。应该是其中之一

jac 布尔或可调用,可选

如果 jac 是一个布尔值并且为 True,则 fun 假定返回 Jacobian 的值以及目标函数。如果为 False,Jacobian 将以数值方式估计。 jac 也可以是一个可调用的返回有趣的雅可比行列式。在这种情况下,它必须接受与 fun 相同的参数。

tol 浮点数,可选

容忍终止。如需详细控制,请使用solver-specific 选项。

callback 函数,可选

可选的回调函数。它在每次迭代中被调用为callback(x, f)其中x是当前的解决方案,并且f相应的残差。适用于除 ‘hybr’ 和 ‘lm’ 之外的所有方法。

options 字典,可选

求解器选项字典。例如:,xtol或者马克西特, 看scipy.optimize.show_options详情。

返回

sol OptimizeResult

解决方案表示为 OptimizeResult 对象。重要属性是:x 解决方案数组,success 指示算法是否成功退出的布尔标志和说明终止原因的 message。有关其他属性的说明,请参见 OptimizeResult

注意

本节介绍可通过 ‘method’ 参数选择的可用求解器。默认方法是 hybr。

方法混合动力使用 MINPACK 中实现的 Powell 混合方法的修改[1].

方法流明使用在MINPACK 中实现的Levenberg-Marquardt 算法的修改,以最小二乘的方式求解非线性方程组[1].

方法df-sane是derivative-free频谱法。[3]

方法布罗伊登1,布罗伊登2,安德森,线性混合,迪亚布罗伊登,令人兴奋的混合,克雷洛夫是不精确的牛顿方法,具有回溯或全行搜索[2].每种方法对应于特定的雅可比近似。

  • 方法 broyden1 使用 Broyden 的第一个 Jacobian 近似,被称为 Broyden 的好方法。

  • 方法 broyden2 使用 Broyden 的第二雅可比近似,它被称为 Broyden 坏方法。

  • 方法安德森使用(扩展)安德森混合。

  • 方法 Krylov 将 Krylov 近似用于逆雅可比行列式。它适用于large-scale 问题。

  • 方法 diagbroyden 使用对角线 Broyden Jacobian 近似。

  • 方法线性混合使用标量雅可比近似。

  • 方法激发混合使用调谐对角雅可比近似。

警告

为方法diagbroyden、linearmixing和excitingmixing实现的算法可能对特定问题有用,但它们是否有效可能很大程度上取决于问题。

参考

[1] (1,2)

更多,Jorge J.、Burton S. Garbow 和 Kenneth E. Hillstrom。 1980. MINPACK-1 用户指南。

[2]

C. T. 凯利。 1995. 线性和非线性方程的迭代方法。工业和应用数学学会。 <https://archive.siam.org/books/kelley/fr16/>

[3]
  1. 拉克鲁兹,J.M.马丁内斯,M.雷丹。数学。比较。 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])

大问题

假设我们需要在正方形 上求解以下积分微分方程:

在广场边界的其他地方。

可以使用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()
scipy-optimize-root-1.png

相关用法


注:本文由纯净天空筛选整理自scipy.org大神的英文原创作品 scipy.optimize.root。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。