2013-01-02 49 views
4

我想使用類的__call__方法作爲Numpy curve_fit函數的輸入,這是因爲我的函數和數據準備過程相當複雜(將分析模型數據擬合到一些測量)。通過定義一個函數,它工作得很好,但我無法使它與類一起工作。使用類的__call__方法作爲Numpy的輸入curve_fit

要重新創建我的問題,你可以運行:

import numpy as np 
from scipy.optimize import curve_fit 

#WORKS: 
#def goal(x,a1,a2,a3,a4,a5): 
# y=a1*x**4*np.sin(x)+a2*x**3+a3*x**2+a4*x+a5 
# return y 

# DOES NOT WORK: 
class func(): 
    def __call__(self,x,a1,a2,a3,a4,a5): 
     y=a1*x**4*np.sin(x)+a2*x**3+a3*x**2+a4*x+a5 
     return y  

goal=func() 

#data prepraration *********** 
xdata=np.linspace(0,50,100) 
ydata=goal(xdata,-2.1,-3.5,6.6,-1,2) 
# **************************** 

popt, pcov = curve_fit(goal, xdata, ydata) 
print 'optimial parameters',popt 
print 'The estimated covariance of optimial parameters',pcov 

我得到的錯誤是:

Traceback (most recent call last): 
    File "D:\...some path...\test_minimizacija.py", line 35, in <module> 
    popt, pcov = curve_fit(goal, xdata, ydata) 
    File "C:\Python26\lib\site-packages\scipy\optimize\minpack.py", line 412, in curve_fit 
    args, varargs, varkw, defaults = inspect.getargspec(f) 
    File "C:\Python26\lib\inspect.py", line 803, in getargspec 
    raise TypeError('arg is not a Python function') 
TypeError: arg is not a Python function 

我怎樣才能使這項工作?

+1

在我看來,這是一個非常好的StackOverflow問題的例子。這個問題清楚地概述,用最少的代碼來證明,可以重現問題。追溯被包括在內。做得很好。我希望更多的人喜歡這個。 – mgilson

回答

3

容易(雖然不漂亮),只是將其更改爲:

popt, pcov = curve_fit(goal.__call__, xdata, ydata) 

有趣的是,numpy的力量,你給一個函數對象傳遞給curve_fit而非任意調用...

迅速檢查源curve_fit,看來另一個解決辦法可能是:

popt,pcov = curve_fit(goal, xdata, ydata, p0=[1]*5) 

這裏,p0是適合參數的初始猜測。問題似乎是scipy檢查函數的參數,以便它知道如果實際上沒有提供參數作爲初始猜測,需要使用多少個參數。在這裏,由於我們有5個參數,所以我最初的猜測是所有長度爲5的列表。(scipy默認使用,如果你還沒有提供猜測)。

+1

我不確定'goal .__ call__'是否可以工作,因爲函數實際上是一個方法並且有一個額外的參數('self')。 – poke

+1

@poke - 試一試,它工作得很好。 'goal .__ call__'是實例方法,它是一個函數,它封裝了'func .__ call__',並在調用'func .__ call__'時將該實例插入到適當的位置。 – mgilson

+1

好吧,我會相信你的,因爲我沒有numpy atm來自己測試它。只是'inspect.getargspec'仍然報告'goal .__ call__'的'self'參數。 – poke