Problem with curve fitting, overflow encountered in exp

Viewed 186

I want to fit a curve with the following data, but I get the error:

ipython-input>:2: RuntimeWarning: overflow encountered in exp

Does anyone know what is the reason for this problem? I fitted this curve with a different datatype for Matlab and it worked fine. I used the initial condition from my Matlab code. Both curves are the same but the values of the y-axes are much higher in this case.

import numpy as np
import scipy.optimize
#sympy.init_printing()
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

list_R1_fit = [
    19.53218114920747, 42.52167990454083, 60.95540646861309,
    70.10646960395906, 73.99897337091254, 75.36736639556727,
    75.69578522881915, 75.62147077733012, 75.42605227692485,
    75.21657113589387, 75.04519265636262, 74.94144261816007,
    74.92153132015117, 74.99475606015201, 75.15746897265564
]
tau_list = [
    0.052, 0.12, 0.252,
    0.464, 0.792, 1.264,
    1.928, 2.824, 4,
    5.600, 7.795, 10.806,
    14.928, 20.599, 28.000
]

array_R1_fit = np.asarray(list_R1_fit)
tau_array = np.asarray(tau_list)
plt.plot(tau_array, array_R1_fit, 'o') 

def func_R1_fit( t, a0, a1, a2, a3, a4):
    R1_fit_Curve = (
        a0 * np.exp(
            a1 * (1 - (28 / t)**(4 / 5))
        ) + 
        a2 * (t / ((a3)**a4 + t**a4))
    )
    return R1_fit_Curve

pars, cov = curve_fit(
    f=func_R1_fit, 
    xdata=tau_array, ydata=array_R1_fit, 
    p0=[
        0.249714296337621, 0.101851223776512,
        0.209343265573669, 0.306273529630680,
        1.511897539010256
    ],
    bounds=(-np.inf, np.inf),
    maxfev=100000
)

I have generated more data in the first part of the chart. Now I get another error.

<ipython-input-7-f61377d66140>:2: RuntimeWarning:
 invalid value encountered in double_scalars
  R1_fit_Curve=a0*np.exp(a1*(1-(28/t)**(4/5)))+a2*(t/((a3)**a4+t**a4))

The new lists are as follows:

list_R1_fit=[8.889450414508385, 13.832704635961235, 3.0955553517738656, 6.944672155278666, 19.53218114920747, 23.06912497313617, 32.92595485184, 42.52167990454083, 54.23640835031421, 60.95540646861309, 66.91996368676925, 70.10646960395906, 72.69136093289741, 73.99897337091254, 74.93277916119311, 75.36736639556727, 75.62190347933995, 75.69578522881915, 75.68268608294542, 75.62147077733012, 75.52270979845973, 75.42605227692485, 75.21657113589387, 75.04519265636262, 74.94144261816007, 74.92153132015117, 74.99475606015201, 75.15746897265564]
tau_list=[0.03,0.04,0.052/3,0.052/2,0.052,0.12/2,(0.052+0.12)/2,0.12,(0.252+0.12)/2,0.252,(0.464+0.252)/2,0.464,(0.464+0.792)/2,0.792,(1.264+0.792)/2,1.264,(1.264+1.928)/2,1.928,(2.824+1.928)/2,2.824,(2.824+4)/2,4,5.600,7.795,10.806,14.928,20.599,28.000]
2 Answers

Exponentials often cause trouble in curve fitting on "smaller" datatypes. So what you want to do is cast your input to bigger representations like longdouble which should be the biggest your platform naturally supports.

array_R1_fit = np.asarray(list_R1_fit).astype(np.longdouble)
tau_array =np.asarray(tau_list).astype(np.longdouble)

If you set the dtypes of array_R1_fit and tau_array to np.longdouble ornp.float64 should fix the RuntimeWarning: overflow encountered in exp that is:

array_R1_fit = np.asarray(list_R1_fit, dtype=np.longdouble)
tau_array =np.asarray(tau_list, dtype=np.longdouble)

Note that if you are on a Windows 64-bit computer np.longdouble will not result in float128 but is defined to be float64. You can try to run it on a linux system.

Related