Reputation: 45
i have small piece of code which produce errormessages (I think because of the math formula). Anyone an idea why?
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
from scipy.integrate import quad
n = 3
x = np.array([2.1,2.2,2.3,2.4])
y = np.array([0.9,2.1,3.2,17.9])
def func(x, a, b):
b1 = n*quad(x[n]*np.log(y[n]), 1, n) - quad(x[n], 1, n)*quad(np.log(y[n]), 1, n)
b2 = n*quad(x[n]**2, 1, n) - (quad(x[n], 1, n))**2
b = b1 / b2
a = np.exp(1/n+(quad(np.log(y[n]), 1, n) - b(quad(x[n], 1, n))))
return a*np.exp(b*x)
popt, pcov = curve_fit(func, x, y)
print popt
plt.plot(x, y)
plt.grid(True)
plt.show()
Errorlog:
Traceback (most recent call last):
File "F:\py-IAT\Laktat.py", line 20, in <module>
popt, pcov = curve_fit(func, x, y)
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 506, in curve_fit
res = leastsq(func, p0, args=args, full_output=1, **kw)
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 348, in leastsq
m = _check_func('leastsq', 'func', func, x0, args, n)[0]
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 14, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 418, in _general_function
return function(xdata, *params) - ydata
File "F:\py-IAT\Laktat.py", line 15, in func
b1 = n*quad(x[n]*np.log(y[n]), 1, n) - quad(x[n], 1, n)*quad(np.log(y[n]), 1, n)
File "C:\Python27\lib\site-packages\scipy\integrate\quadpack.py", line 247, in quad
retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)
File "C:\Python27\lib\site-packages\scipy\integrate\quadpack.py", line 312, in _quad
return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
quadpack.error: quad: first argument is not callable
Thanks!
Upvotes: 0
Views: 1418
Reputation: 4425
Kevin pointed out that the first argument to quad is supposed to be a function and you are putting in a number. I would suggest creating a function
def newfunc(x, y, n):
# Insert appropriate processing here
return x[n]*np.log(y[n])
Now put newfunc as the first argument to quad with the appropriate aguments in the calling sequence.
Note that the other calls to quad would require similar modifications.
Upvotes: 1
Reputation: 12713
According to docs, the first argument to quad
should be a function to integrate. You have an expression rather than function. To fix that, you can try to introduce anonymous functions to quad
calls:
b1 = n*quad(lambda n:x[n]*np.log(y[n]), 1, n) - quad(lambda n:x[n], 1, n) * \
quad(lambda n:np.log(y[n]), 1, n)
This is untested, but it should work.
Upvotes: 1