scipy.optimize curve_fit错误,同时将上限作为自变量拟合积分函数

时间:2016-09-30 17:19:53

标签: scipy curve-fitting

我正在尝试使用scipy.optimize curve_fit为我的数据拟合一个积分函数,如下所示:

import numpy as np
from scipy.integrate import quad, nquad, odeint
from scipy.special import gammainc, gamma
import math
import os
import sys
import contextlib
from scipy.optimize import curve_fit
import string

#Global model constants, all units are CGI
day=86400.     #seconds in a day
year=3.15436e7 #seconds in a year
Msun=1.99e33   #solar mass in grams
c=2.99792458e10#speed of light
sb=5.67051e-5  #Stefan-Boltzmann constant
kms2cms=1.e5   #km/s in cm/s
r15=1.e15      #radii in units of 10^15cm
tni=8.8        #Ni-56 decay time-scale
tco=111.3      #Co-56 decay time-scale
eni=3.9e10     #Ni-56 decay specific energy generation rate
eco=6.8e9      #Co-56 decay specific energy generation rate
TH=5500.       #Hydrogen ionization temperature in K
A0=1.e14       #Radioactive decay model gamma-ray leakage parameter 
E51=1.e51      #Energy in units of 1 F.O.E. (10^51 erg)
L45=1.e45      #Luminosity in units of 10^45 erg/s
nmax=1000000   #Grid resolution for fallback accretion model 

def rad_decay_dep(t,td,r0,vej):
    return ((r0*r15/(vej*td*day*kms2cms))+t/td)*np.exp((t/td)**2  
   (2.*r0*r15*t/(vej*kms2cms*(td**2)*day)))

# Integrants for Ni-56 and Co-56 decay energy depositions

def rad_decay_int1(t,td,r0,vej):
    return rad_decay_dep(t,td,r0,vej)*np.exp(-t/tni)

def rad_decay_int2(t,td,r0,vej):
    return rad_decay_dep(t,td,r0,vej)*np.exp(-t/tco)

# Final radioactive decay luminosity integral function

def Lum_rad(x,Mni,td,r0,vej,A):
    return (2.*Mni*Msun/td)*np.exp(-((x/td)**2+(2.*r0*r15*x
    /(vej*kms2cms*(td**2)*day))))* \
    ((eni-eco)*quad(rad_decay_int1,0,x,args=(td,r0,vej))[0] +  
    eco*quad(rad_decay_int2,0,x,args=(td,r0,vej))[0])* \
    (1.-np.exp(-A*A0/(x*day)**2))

xdata, ydata = np.loadtxt(sys.argv[1], usecols=(0,1), unpack=True)

popt, pcov = curve_fit(Lum_rad, xdata, ydata)

我收到以下错误:

Traceback (most recent call last):
  File "SLSNFit.py", line 11, in <module>
    popt, pcov = curve_fit(LCmods.Lum_rad, xdata, ydata)
  File "/usr/local/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 676, in curve_fit
    res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 377, in leastsq
    shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
  File "/usr/local/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 26, in _check_func
    res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
  File "/usr/local/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 455, in func_wrapped
    return func(xdata, *params) - ydata
  File "/Users/macbro/Desktop/LCmods.py", line 86, in Lum_rad
    ((eni-eco)*quad(rad_decay_int1,0,x,args=(td,r0,vej))[0] + eco*quad(rad_decay_int2,0,x,args=(td,r0,vej))[0])* \
  File "/usr/local/lib/python2.7/site-packages/scipy/integrate/quadpack.py", line 315, in quad
    points)
  File "/usr/local/lib/python2.7/site-packages/scipy/integrate/quadpack.py", line 364, in _quad
    if (b != Inf and a != -Inf):
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

我尝试使用np.vectorize对函数进行矢量化,但这也没有用(我得到TypeError:不是Python函数)。

输入文件(sn2006gy)的链接位于:https://www.dropbox.com/s/ng4lknaja4igwhm/sn2006gy?dl=0。我运行:&gt; python test.py sn2006gy,我得到上面的错误。 任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

scipy.integral.quad无法将数组作为集成限制处理。您可以定义一个接受非标量限制的包装函数,例如

def integral(func, a, b, args):
    ret = np.asarray([quad(func, a, q, args)[0] for q in b])
    return ret

并像这样修改Lum_rad

def Lum_rad(x,Mni,td,r0,vej,A):
    return (2.*Mni*Msun/td)*np.exp(-((x/td)**2+(2.*r0*r15*x
    /(vej*kms2cms*(td**2)*day))))* \
    ((eni-eco)*integral(rad_decay_int1,0,x,args=(td,r0,vej)) +  
    eco*integral(rad_decay_int2,0,x,args=(td,r0,vej)))* \
    (1.-np.exp(-A*A0/(x*day)**2))

该程序在相当长的一段时间后结束

RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 1200.

现在由你决定数学。