I would like to use a __call__
method of a class as a input to a Numpy curve_fit function due to my rather elaborate function and data preparation process (fitting analytical model data to some measurements). It works just fine by defining a function, but I can't get it to work with classes.
To recreate my problem you can run:
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
The error i get is:
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
How can I make this work?
Easy (although, not pretty), just change it to:
popt, pcov = curve_fit(goal.__call__, xdata, ydata)
It's interesting that numpy forces you to pass a function object to curve_fit
rather than an arbitrary callable ...
quickly inspecting the source for curve_fit
, it appears that another workaround might be:
popt,pcov = curve_fit(goal, xdata, ydata, p0=[1]*5)
Here, p0
is the initial guess for the fit parameters. The problem appears to be that scipy
inspects the arguments to the function so that it knows how many parameters to use if you don't actually provide parameters as an initial guess. Here, since we have 5 parameters, my initial guess is a list of all ones of length 5. ( scipy
defaults to using ones if you don't provide a guess also).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.