在SciPy/NumPy中查找复函数的零点

4 投票
1 回答
3438 浏览
提问于 2025-04-18 11:04

有人告诉我,只要提供函数的第一个导数,scipy.optimize.newton()这个方法就能解决复杂的函数问题。但是我试了之后发现它不管用。newton()的说明文档里没有提到复杂函数的内容。有没有人能给我演示一下,如何在SciPy中找到像f(z) = 1 + z^2这样的函数的根?我需要解决一些更复杂的问题,但一个简单的例子对我来说会有很大帮助。

1 个回答

6

这里有一个关于如何在IPython环境中使用newton的例子,适用于一个复杂的函数:

In [1]: def func(z):
   ...:     return 1 + z*z
   ...: 

In [2]: def deriv(z):
   ...:     return 2*z
   ...: 

In [3]: from scipy.optimize import newton

In [4]: newton(func, x0=1+1j, fprime=deriv, tol=1e-12)
Out[4]: 1j

In [5]: newton(func, x0=-2j, fprime=deriv, tol=1e-12)
Out[5]: -1j

需要注意的是,newton这个函数不适合用在导数为零的点,也就是x0如果在这个点上,它就会出问题:

In [6]: newton(func, x0=0, fprime=deriv, tol=1e-12)
/Users/warren/local_scipy/lib/python2.7/site-packages/scipy/optimize/zeros.py:119: RuntimeWarning: derivative was zero.
  warnings.warn(msg, RuntimeWarning)
Out[6]: 0.0

另外,如果你的函数在真实的输入下返回的是实数,记得给x0传入一个复数值。否则,函数就只能在实数轴上运行,无法探索其他可能性:

In [21]: newton(func, x0=0.5, fprime=deriv, tol=1e-12)
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-21-2feb08057c57> in <module>()
----> 1 newton(func, x0=0.5, fprime=deriv, tol=1e-12)

/Users/warren/local_scipy/lib/python2.7/site-packages/scipy/optimize/zeros.pyc in newton(func, x0, fprime, args, tol, maxiter, fprime2)
    159             q1 = func(*((p1,) + args))
    160     msg = "Failed to converge after %d iterations, value is %s" % (maxiter, p)
--> 161     raise RuntimeError(msg)
    162 
    163 

RuntimeError: Failed to converge after 50 iterations, value is -0.870752774435

增加maxiter的值也不会有帮助:

In [22]: newton(func, x0=0.5, fprime=deriv, tol=1e-12, maxiter=1000)
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
[...]
RuntimeError: Failed to converge after 1000 iterations, value is -0.0895687261655

撰写回答