2012-02-08 62 views
0

的求根我想用加載如何使用牛頓功能爲SciPy的的優化包

from scipy.optimize import newton 

newton功能,以便找到用戶enetered一個函數的零點。我寫了一個腳本,首先要求用戶指定一個函數以及它的一階導數,也是算法的起點。首先鍵入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

首先,請注意,使用eval會使您的程序容易受到惡意用戶的攻擊。如果關注不適用,你可以這樣創建F和DF:

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

然後兩種功能期望只有一個參數,你可以離開args參數爲空。

編輯。如果你真的想盡可能地堅持你的代碼,這也應該可行,但對我來說看起來並不好。 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)) 
+0

對不起,這對我來說很不清楚(我的意思是lambda),你能解釋我這樣的「形式主義」嗎? – 2012-02-08 13:30:42

+0

@StefanoMessina [lambda表達式](http://docs.python.org/tutorial/controlflow.html#lambda-forms)計算爲一個函數對象。 – 2012-02-08 13:46:03

+0

讓我們假設我「必須」使用函數newton()的參數'args'來傳遞'fie'。 – 2012-02-08 14:00:13