Question

I have a problem in using curve_fit function. The task is to solve symbolic a cubic equation and then to use this solution in fitting function.

import numpy as np
import pylab
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from sympy import *
from sympy.utilities.lambdify import lambdify

a, b, c, d, L, k1, k2, E1, E2, x, C0, E0 = symbols("a b c d L k1 k2 E1 E2 x C0 E0", real=True) 
sol = solve(Eq(a*L**3 + b*L**2 + c*L + d),L)
sol1 = sol[2].subs({a: k1*k2, b: (k1 + 2*k1*k2*x), c: (1 + k1*x - k1*C0), d: -C0,})
intensity = E0*L + E1*k1*L*x/(1 + k1*L + k1*k2*L**2) \
    + E2*k1*k2*L**2*x/(1 + k1*L + k1*k2*L**2)

E0r=1000.0
C0r=1E-4

function_sym = intensity.subs(L,sol1).subs(E0, E0r).subs(C0, C0r)
funct = lambdify([E1, E2, k1, k2, x],function_sym)
x_exp = np.array([0,1E-5,2E-5,3E-5,4E-5,6E-5,8E-5,1.3E-4])
y_exp = np.array([0,0.081,0.1936,0.264,0.297,0.3567,0.396,0.452])
popt, pcov = curve_fit(funct, x_exp, y_exp, (1000, 1000, 100000, 100000))

It results in error:

ValueError: array must not contain infs or NaNs

I've tried to solve this problem by getting a real part of function_sym and another definition way of fitting function:

function_re = re(function_sym)
def fit_func(E1r, E2r, k1r, k2r, xr):
    return function_re.subs(E1, E1r).subs(E2, E2r).subs(k1, k1r).subs(k2,k2r).subs(x, xr).evalf()

popt, pcov = curve_fit(fit_func, x_exp, y_exp, (1000, 1000, 100000, 100000))

And it results in another error:

TypeError: unhashable type: 'numpy.ndarray'
Was it helpful?

Solution

curve_fit() requires the objective function (your 'funct' or 'fit_funct') to have its first argument be an ndarray of variables. That is, you have to pack E1, E2, k1, and k2 into a single ndarray.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top