I am trying to use scipy.optimize.curve_fit to fit a sigmoidal curve to my dataset but I get the following error:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "Y:\WORK\code\venv\lib\site-packages\scipy\optimize\minpack.py", line 784, in curve_fit
res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
File "Y:\WORK\code\venv\lib\site-packages\scipy\optimize\minpack.py", line 410, in leastsq
shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
File "Y:\WORK\code\venv\lib\site-packages\scipy\optimize\minpack.py", line 24, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
File "Y:\WORK\code\venv\lib\site-packages\scipy\optimize\minpack.py", line 484, in func_wrapped
return func(xdata, *params) - ydata
File "<input>", line 7, in func
File "Y:\WORK\code\venv\lib\site-packages\scipy\integrate\quadpack.py", line 348, in quad
flip, a, b = b < a, min(a, b), max(a, b)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
The sigmoidal function I'm trying to fit contains an integral from negative infinity to a function of the independent variable. Here is my code:
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.integrate import quad
import numpy as np
import math
x_data = np.array([ 2.5, 7.5, 12.5, 17.5, 22.5, 27.5, 32.5, 37.5, 42.5, 47.5, 52.5, 57.5, 62.5, 67.5, 72.5, 77.5])
y_data = np.array([0.05, 0.09, 0.13, 0.15, 0.2, 0.35, 0.45, 0.53, 0.68, 0.8, 0.9, 0.92, 0.99, 1, 0.95, 0.97])
#Constructing the sigmoidal function
def integrand(x):
return np.exp(-np.square(x)/2)
def func(x, a, b):
t = (x-a)/(b*a)
integral = quad(integrand, -math.inf, t)[0]
return math.sqrt(1/(2*math.pi))*integral
# Initial guess for parameters a, b
initialGuess = [35, 0.25]
# Perform the curve-fit
popt, pcov = curve_fit(func, x_data, y_data, initialGuess)
The problem seems to be coming from the integral part. In other similar posts, their function contains a boolean argument where if the independent variable exceeds a value then another function is provided. But not in my case. I'm very confused...
Thanks to @hpaulj
: the quad
function only takes scalar and my t
was an array. I have changed the function as follows and the error went away
def func(x, a, b):
sigmoid_arr = np.array([])
for i in x:
t = (i- a)/(b*a)
integral = quad(integrand, -math.inf, t)[0]
sigmoid = math.sqrt(1/(2*math.pi))*integral
sigmoid_arr = np.append(sigmoid_arr, sigmoid)
return sigmoid_arr