Search code examples
pythonmathscipynumerical-integrationquad

error in math formulas in python code scipy


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!


Solution

  • 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.