I have a set (at least 3) of curves (xy-data). For each curve the parameters E and T are constant but different. I\'m searching the coefficients a,n and m for the best fit o
One way to do this is use scipy.optimize.leastsq
instead (curve_fit
is a convenience wrapper around leastsq
).
Stack the x
data in one dimension; ditto for the y
data. The lengths of the 3 individual datasets don't even matter; let's call them n1
, n2
and n3
, so your new x
and y
will have a shape (n1+n2+n3,)
.
Inside the function to optimize, you can split up the data at your convenience. It will not be the nicest function, but this could work:
def function(x, E, T, a, n, m):
return x/E + (a/n+1)*T^(n+1)*x^m
def leastsq_function(params, *args):
a = params[0]
n = params[1]
m = params[2]
x = args[0]
y = args[1]
E = args[2]
T = args[3]
n1, n2 = args[2]
yfit = np.empty(x.shape)
yfit[:n1] = function(x[:n1], E[0], T[0], a, n, m)
yfit[n1:n2] = function(x[n1:n2], E[1], T[1], a, n, m)
yfit[n2:] = function(x[n2:], E[2], T[2], a, n, m)
return y - yfit
params0 = [a0, n0, m0]
args = (x, y, (E0, E1, E2), (T0, T1, T2), (n1, n1+n2))
result = scipy.optimize.leastsq(leastsq_function, params0, args=args)
I have not tested this, but this is the principle. You're now splitting up the data into 3 different calls inside the function that is to be optimized.
Note that scipy.optimize.leastsq
simply requires a function that returns whatever value you'd like to be minized, in this case the difference between your actual y
data and the fitted function data. The actual important variables in leastsq
are the parameters you want to fit for, not the x
and y
data. The latter are passed as extra arguments, together with the sizes of three separate datasets (I'm not using n3, and I've done some juggling with the n1+n2
for convenience; keep in mind that the n1
and n2
inside leastsq_function
are local variables, not the original ones).
Since this is an awkward function to fit (it probably won't have a smooth derivative, for example), it is quite essential to
provide good starting values (params0
, so all the ...0
values).
don't have data or parameters which span orders of magnitude. The closer everything is around 1 (a few orders of magnitude is certainly ok), the better.