Fit an integral function with parametric limit to data with Python (Debye Model) -


i trying fit resistivity vs temperature data bloch-gruneisen formula resistivity in metals:

function

as can see there integral function parametric limit. don't know how implement algorithm run least squares fit. came with:

import matplotlib.pyplot plt import numpy np import pylab pl import scipy sp scipy.optimize import leastsq  #retrieve data file data = pl.loadtxt('salita.txt') temp = data[:, 0] res = data[:, 2]  def debye_func(p, t, r):     rho0, ad, td = p     coeff = ad*np.power(t, 5)/np.power(td, 4)     f = np.power(x^5)/np.power(np.sinh(x), 2) #function integrate     err_debye = r - rho0 - coeff * #integral???     return err_debye  p0 = sp.array([0.0001 , 0.00001, 50])  plsq = leastsq(debye_func, p0, args=(temp, res))  print plsq 

ideas on how write it?

edit: code has become:

import matplotlib.pyplot plt import numpy np import pylab pl import scipy sp scipy.optimize import leastsq scipy.integrate import quad  #retrieve data file data = pl.loadtxt('salita.txt') temp = data[:, 0] res = data[:, 2]  def debye_integrand(x):     return np.power(x, 5)/np.power(np.sinh(x), 2)  def debye_func(p, t, r):     rho0, ad, td = p     coeff = ad*np.power(t, 5)/np.power(td, 4)     err_debye = r - rho0 - coeff * quad(debye_integrand, 0, td/(2*t))     return err_debye  p0 = sp.array([0.0001 , 0.00001, 50])  plsq = leastsq(debye_func, p0, args=(temp, res))  print plsq 

now valueerror:

traceback (most recent call last):   file "debye.py", line 24, in <module>     plsq = leastsq(debye_func, p0, args=(temp, res))   file "/system/library/frameworks/python.framework/versions/2.7/extras/lib/python/scipy/optimize/minpack.py", line 348, in leastsq     m = _check_func('leastsq', 'func', func, x0, args, n)[0]   file "/system/library/frameworks/python.framework/versions/2.7/extras/lib/python/scipy/optimize/minpack.py", line 14, in _check_func     res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))   file "debye.py", line 19, in debye_func     err_debye = r - rho0 - coeff * quad(debye_integrand, 0, td/(2*t))   file "/system/library/frameworks/python.framework/versions/2.7/extras/lib/python/scipy/integrate/quadpack.py", line 247, in quad     retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)   file "/system/library/frameworks/python.framework/versions/2.7/extras/lib/python/scipy/integrate/quadpack.py", line 296, in _quad     if (b != inf , != -inf): valueerror: truth value of array more 1 element ambiguous. use a.any() or a.all() 

i think means i'm providing leastsq argument can't take, don't know how modify code.

edit2: solved equation analytically maxima , got

import matplotlib.pyplot plt import numpy np import pylab pl import scipy sp scipy.optimize import leastsq scipy.integrate import quad scipy.special import zetac mpmath import polylog  #retrieve data file data = pl.loadtxt('salita.txt') temp = data[:, 0] res = data[:, 2]  def debye_integrand(x):     return np.power(x, 5)/np.power(np.sinh(x), 2)  def debye_func(p, t, r, integral):     rho0, ad, td = p     coeff = ad*np.power(t, 5)/np.power(td, 4)     den = np.exp(td/t) -1     m1 = 5*((td/(2*t))**4)*np.log(np.exp(td/(2*t)+1)*(np.exp(td/t)-1)+120*polylog(5, np.exp(td/(t))*(1-np.exp(td/(2*t)))     m2 = 120*(td/(2*t))*polylog(4, np.exp(td/(2*t)))*(np.exp(np.exp(td/t))-1)+60*((td/(2*t))**2)*polylog(3, np.exp(td/(2*t))*(1-np.exp((td/(2*t)))     m3 = 20*((td/(2*t))**3)*polylog(2, np.exp(td/(2*t))*(np.exp(td/t)-1)+120**polylog(5, -np.exp(td/(2*t)))*(1-np.exp(td/t))     m4 = 120*(td/(2*t))*polylog(4, -np.exp(td/(2*t)))*(np.exp(td/t)-1)+60*((td/(2*t))**2)*polylog(3, -np.exp(td/(2*t)))*(1-np.exp(td/t))     m5 = 20*((td/(2*t))**3)*polylog(2, -np.exp(td/(2*t)))*(np.exp(td/t)-1) -2*((td/(2*t))**5)*np.exp(td/t)     m6 = 5*((td/(2*t))**4)*np.log(1-np.exp(td/(2*t))*(np.exp(td/t)-1)     zeta = 15.0*zetac(5)/2      integral = (m1+m2+m3+m4+m5+m6)/den +zeta      err_debye = r - rho0 - coeff * integral     return err_debye  #initizalied einstein model fit p0 = sp.array([0.00001 , 0.0000001, 70.0])    plsq = leastsq(debye_func, p0, args=(temp, res))  print plsq 

it says syntaxerror: invalid syntax in m2. tried loops in numerical way, didn't succeed.

my .txt file here, if want try. first column temperature, third 1 resistivity.

you could, instance, separately define integrand function,

def debye_integrand(x,  n):         return x**n/((np.exp(x) - 1)*(1 - np.exp(-x))) 

and use scipy.integrate.quad integration numerically,

from scipy.integrate import quad   def debye_func(p, t, r):     # [...] rest of code above here     err_debye = r - rho0 - coeff * quad(debye_integrand, 0, t/td, args=(n,))     return np.sum(err_debye**2) 

that's general idea, , might need adapted further code. ideal solution find analytical solution integral, or rewrite classical integral functions scipy.special, but might not straightforward (see below).

also should use more general scipy.opitimize.minimize function instead of least-square fit, since provides algorithms more efficient , robust non-smooth optimizations. default optimization method bfgs start.

edit: actually, there analytical solution integral (for n=5), can obtain, instance, maxima,

>> integrate(x**5/((exp(x) - 1)*(1 - exp(-x))), x, 0, a) 

solution part 1 enter image description here

where a integration limit, li_k polylogarithm function of order k (see mpmath.polylog) , ΞΆ riemann zeta function (see scipy.special.zetac).

although, depending on needs, might faster go numerical integration (or pre-calculated table lookup) rather puyting of together, , converting python.

edit 2: here final solution analytical calculation of integral,

import numpy np import mpmath mp scipy.optimize import minimize scipy.integrate import quad import matplotlib.pyplot plt  def debye_integral_sym_scalar(x):      """      calculate debye integral scalar using multi precision math,      otherwise overflows 64bit floats      """      exp_x = mp.exp(x)       m1 = -120*mp.polylog(5, exp_x)      m2 = 120*x*mp.polylog(4, exp_x)      m3 = -60*x**2*mp.polylog(3, exp_x)      m4 = 20*x**3*mp.polylog(2, exp_x)      m5 = 5*x**4*mp.log(1 - exp_x)      m6 = - x**5*exp_x       return m1 + m2 + m3 + m4 + m5 + m6/(exp_x - 1) + 120*mp.zeta(5)   # actual function can use  def debye_integral_sym(x):      f =  np.vectorize(debye_integral_sym_scalar, otypes=[np.complex])      return f(x).real  def debye_integrand(x,  n):      return x**n/((np.exp(x) - 1)*(1 - np.exp(-x)))  # test debye_integral_sym returns same result quad = 10.0  res0 =  quad(debye_integrand, 0, a, args=(5,))[0] res1 = debye_integral_sym(a) np.testing.assert_allclose(res0, res1)  def resistivity_fit(p, t):     rho0, ad, td = p     coeff = ad*np.power(t, 5)/np.power(td, 4)     return rho0 + coeff * debye_integral_sym(td/(2*t))   def debye_err_func(p, t, r):     return  np.sum((r - resistivity_fit(p, t))**2)  # wget "http://pastebin.com/raw.php?i=tvzcdxya" -o salita.txt data = np.loadtxt('salita.txt')  temp_exp = data[:, 0] res_exp = data[:, 2]  p0 = np.array([0.0001 , 0.00001, 50]) p_opt = minimize(debye_err_func, p0, args=(temp_exp, res_exp))  print p_opt  temp = np.linspace(temp_exp.min(), temp_exp.max(), 100)  plt.plot(temp_exp, res_exp, '.', label='experimental data') plt.plot(temp, resistivity_fit(p_opt.x, temp), 'r', label='bloch-gruneisen fit') plt.legend(loc='best') plt.xlabel('temperature [k]') plt.ylabel('resistivity') plt.show() 

with output of optimization function,

   status: 0    success: true    njev: 5    nfev: 25    hess_inv: array([[  7.32764243e-01,  -4.89555962e-01,  -1.93879729e-08],    [ -4.89555962e-01,   3.27690582e-01,  -2.09510086e-08],    [ -1.93879729e-08,  -2.09510086e-08,   1.00000000e+00]])    fun: 1.784420370873494e-11    x: array([  9.96468440e-06,   7.40349389e-06,   5.00000000e+01])    message: 'optimization terminated successfully.'    jac: array([ -1.11880569e-06,   1.28115957e-06,   2.31303410e-12]) 

and resulting plot, the resulting plot


Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -