如何使用牛顿函数进行Scipy优化包的根查找

时间:2012-02-08 11:10:54

标签: python scipy

我想使用

加载的newton函数
from scipy.optimize import newton

以便找到用户输入的函数的零。我编写了一个脚本,首先要求用户指定一个函数及其一阶导数,以及算法的起点。首先输入help(newton)我看到哪些参数采用了函数和相关解释:

newton(func, x0, fprime=None, args=(), tol=1.48e-08, maxiter=50)

func : function
    The function whose zero is wanted. It must be a function of a
    single variable of the form f(x,a,b,c...), where a,b,c... are extra
    arguments that can be passed in the `args` parameter.

我必须以哪种方式传递我的功能?如果我用于func,例如x**3(及其一阶导数)响应为NameError: name 'x' is not defined。在互联网上,我发现首先我必须定义我的函数及其一阶导数并将名称作为参数传递。所以我做了以下

fie = raw_input('Enter function in terms of x (e.g. x**2 - 2*x). F= ')
dfie = raw_input('Enter first derivative of function above DF = ')
x0 = input('Enter starting point x0 = ')

def F(x,fie):
    y = eval(fie)
    return y 

def DF(x, dfie):
    dy = eval(dfie)
    return dy

print newton(F,x0,DF)

但是我得到了输出

    102         for iter in range(maxiter):
    103             myargs = (p0,) + args
--> 104             fder = fprime(*myargs)
    105             if fder == 0:
    106                 msg = "derivative was zero."

TypeError: DF() takes exactly 2 arguments (1 given)
如果省略F

DF的问题相同。查看/usr/local/share/src/scipy/scipy/optimize/zeros.py中的代码,我看到它使用fder=fprime(*myargs)来评估一阶导数,所以也许我必须放入args使其工作的东西。我在考虑它,但没有解决方案。

1 个答案:

答案 0 :(得分:1)

首先,请注意使用eval会使您的程序容易受到恶意用户的攻击。如果该问题不适用,您可以像这样创建F和DF:

F = eval('lambda x :'+fie)
DF = eval('lambda x :'+dfie)

然后两个函数只需要一个参数,你可以将args参数留空。

EDIT。如果你真的想尽可能地坚持你的代码,这也应该有效,但对我来说看起来并不是很好。 newton会向两个函数发送相同的args

def F(x,fie,dfie):
    y = eval(fie)
    return y 

def DF(x,fie,dfie):
    dy = eval(dfie)
    return dy

print newton(F,x0,DF,(fie,dfie))