将函数与Python(sympy,quad)集成,结果是我想要绘制的另一个函数

将函数与Python(sympy,quad)集成,结果是我想要绘制的另一个函数,python,scipy,sympy,integrate,quad,Python,Scipy,Sympy,Integrate,Quad,我想使用python集成一个函数,其中输出是一个新函数,而不是一个数值。例如,我有一个方程(来自Arnett 1982——超新星的分析描述): 我想找到A的积分,然后画出结果。首先,我天真地尝试了scipy.quad: def Arnett(t,z,tm,tni,tco,Mni,Eni,Eco): x=t/tm Eni=3.90e+10 # Heating from Ni56 decay Eco=6.78e+09 # Heating fro

我想使用python集成一个函数,其中输出是一个新函数,而不是一个数值。例如,我有一个方程(来自Arnett 1982——超新星的分析描述):

我想找到A的积分,然后画出结果。首先,我天真地尝试了scipy.quad:

def Arnett(t,z,tm,tni,tco,Mni,Eni,Eco): 
     x=t/tm
     Eni=3.90e+10       # Heating from Ni56 decay
     Eco=6.78e+09       # Heating from Co56 decay
     tni=8.77           # efolding time of Ni56
     tco=111.3          # efolding time of Co56
     tm=8.8             # diffusion parameter 
     f=integrate.quad(A(z,tm,tni),0,x)      #integral of A
     h=integrate.quad(B(z,tm,tni,tco),0,x)  #integral of B
     g=np.exp((-(x/tm)**2))
     return Mni*g*((Eni-Eco)*f+Eco*h)
其中,B也是一个预定义函数(此处不提供)。A和B都是z的函数,但最终的方程是时间t的函数。(我相信正是在这里我导致了我的代码失败。)

A和B的积分从零到x,其中x是时间t的函数。尝试按原样运行代码时会出现一个错误:“ValueError:包含多个元素的数组的真值不明确。请使用a.any()或a.all()

因此,经过短暂的搜索,我认为也许辛皮是一条出路。然而,我在这方面也失败了

我想知道是否有人有一个有用的建议如何完成这项任务,请

非常感谢,,
Zach

我认为您要寻找的是lambda表达式(如果我正确理解了您所说的……有关lambda函数的更多信息和示例,请参阅)

它们允许您在A中定义一个匿名函数并返回它,这样您就可以得到B函数,应该是这样工作的:

 def A(parameters):
     return lambda x: x * parameters # for simplicity i applied a multiplication
                                     # but you can apply anything you want to x
 B = A(args)
 x = B(2)

希望我能给你一个体面的答复

您可以通过解析方式对一个函数进行积分。假设我没有因为起得太晚而错过一些愚蠢的事情,下面的方法有帮助吗

import sympy as sy
sys.displayhook = sy.pprint
A, y, z, tm, t, tni = sy.symbols('A, y, z, tm, t, tni')
A = 2*z*sy.exp(-2*z*y + z**2)
expr = sy.integrate(A, (z,0,t)) # patience - this takes a while
expr
# check:
(sy.diff(expr,t).simplify() - A.replace(z,t)).simplify()
# thus, the result:
expr.replace(y,tm/(2*tni)).replace(t,t/tm)

最后一行以解析形式生成A函数的积分,尽管它确实需要计算虚误差函数(可以使用scipy.special.erfi())。

我认为您得到的误差来自对scipy.integrate.quad的错误调用:

  • 第一个参数必须是函数名,然后对该函数的第一个变量执行积分。其他变量的值可以通过args关键字传递给函数
  • scipy.integrate.quad的输出不仅包含积分值,还包含误差估计。因此,将返回一个包含2个值的元组
最后,以下功能应起作用:

def Arnett(t, z, Mni, tm=8.8, tni=8.77, tco=111.3, Eni=3.90e+10,
           Eco=6.78e+09): 
  x=t/tm
  f,err=integrate.quad(A,0,x,args=(tm,tni))      #integral of A
  h,err=integrate.quad(B,0,x,args=(tm,tni,tco))  #integral of B
  g=np.exp((-(x/tm)**2))
  return Mni*g*((Eni-Eco)*f+Eco*h)
但更好的解决方案可能是对A和B进行解析积分,然后计算表达式

def Arnett(t, z, Mni, tm=8.8, tni=8.77, tco=111.3, Eni=3.90e+10,
           Eco=6.78e+09): 
  x=t/tm
  f,err=integrate.quad(A,0,x,args=(tm,tni))      #integral of A
  h,err=integrate.quad(B,0,x,args=(tm,tni,tco))  #integral of B
  g=np.exp((-(x/tm)**2))
  return Mni*g*((Eni-Eco)*f+Eco*h)