Python/Scipy集成阵列
我正在尝试编写一个程序,该程序执行以下操作:Python/Scipy集成阵列,python,arrays,scipy,integrate,Python,Arrays,Scipy,Integrate,我正在尝试编写一个程序,该程序执行以下操作: 从数组中获取V的值 将V值传递为与E有关的积分 将积分结果输出到数组I中 一反五 这个等式看起来很糟糕,但除了V以外,其他都是常数。这个等式不是很重要 我该如何处理这个问题?我的尝试(如下所示)没有计算从文件中读取的每个V值的积分 from scipy import integrate #integrate.quad from numpy import * import pylab import datetime import time impo
- 从数组中获取V的值
- 将V值传递为与E有关的积分
- 将积分结果输出到数组I中
- 一反五
from scipy import integrate #integrate.quad
from numpy import *
import pylab
import datetime
import time
import os
import math
# import V
fn = 'cooltemp.dat'
V = loadtxt(fn,unpack=True,usecols=[1])
# variables
del1, del2, R, E, fE, fEeV = 1,2,1,2,1,1
e = 1.602176565*10**-19
# eqn = dint(abc)
a = E/( math.sqrt( E**2 - del1**2 ) )
b = ( E+ e*V )/( math.sqrt( ( E + e*V )**2) - del2**2)
c = fE-fEeV
d = 1/(e*R) # integration constant
eqn = a*b*c
# integrate
result = quad(lambda E: eqn,-inf,inf)
# current
I = result*d
# plot IV curve
pylab.plot(V,I,'-r')
## customise graph
pylab.legend(['degree '+str(n),'degree '+str(q),'data'])
pylab.axis([0,max(x),0,max(y)])
pylab.xlabel('voltage (V)')
pylab.ylabel('current (A)')
tc = datetime.datetime.fromtimestamp(os.path.getmtime(fn))
pylab.title('IV curve\n'+fn+'\n'+str(tc)+'\n'+str(datetime.datetime.now()))
pylab.grid(True)
pylab.show()
*更新的尝试:
from scipy import integrate
from numpy import *
import pylab
import datetime
import time
import os
import math
# import V
fn = 'cooltemp.dat'
V = loadtxt(fn,unpack=True,usecols=[1])
# print V
# variables
del1, del2, R, E, fE, fEeV = 1.0,2.0,1.0,2.0,1.0,1.0
e = 1.602176565*10**-19
I=[]
for n in range(len(V)):
constant = 1/(e*R) # integration constant
eqn = (E/( math.sqrt( E**2 - del1**2 ) ))*(( E + e*V[n] )/( math.sqrt( ( E + e*V[n] )**2) - del2**2))*(fE-fEeV)
# integrate
result,error = integrate.quad(lambda E: eqn,-inf,inf)
print result
# current
I.append(result*constant)
I = array(I)
# plot IV curve
pylab.plot(V,I,'-b')
您有一些问题: 传递给
quad
的“函数”总是返回eqn,这只是一个预先计算的数字。您需要定义一个适当的函数,该函数将给定的E值作为输入并返回被积函数。此函数还需要假定V为固定值。假定您提供的代码为给定的V和E值计算适当的数量(我没有选中,只是复制粘贴):
总结如下:
计算固定值v的完整积分(E上)结果(v)
在固定E(积分变量)和固定V(它从函数外部获取值,这就是为什么被积函数的定义嵌套在结果的定义中)处计算被积函数被积函数(E)
技巧只是一个非常方便的函数,它允许您将V的数组传递到@np.vectorize
结果中。Numpy将为您循环这些值,并返回一个数组而不是标量
将numpy作为np导入
从scipy.integrate导入四元组
spl=299792458.0#光速(m/s)
Mpc=3.0856E22#Mpc,单位为m
pc=3.0856E16#pc(单位:m)
def哈勃时间(H0):
返回3.0856e17/(H0/100.0)
def哈勃望远镜(H0):
“”“返回给定H_0的哈勃距离(以Mpc为单位)”
返回spl*哈勃时间(H0)/Mpc
def被积函数(z、Om、OLam):
“”“这是Hogg(2000)中的E(z)函数
被积函数(z,Om,OLam)
"""
返回(Om*(1+z)3+OLam)(-0.5)
def CosmComDist(z,H0=70,Om=0.30,OLam=0.70):
“”“给出红移z时的移动距离
CosmComDist(z,H0=70,Om=0.30,OLam=0.70)
"""
CMD=HubbleDist(H0)*四元(被积函数,0,z,args=(Om,OLam))[0]
返回指令
CosmComDist=np.vectorize(CosmComDist)
红移=np.linspace(0,1100)
距离=CosmComDist(红移)
看起来错误在result=quad(lambda E:eqn,-inf,inf)
中。lambda应该在冒号的两侧都包含相同的变量,而这不会发生。顺便说一下,这个表达不是很容易理解。谢谢heltonbiker。这是否意味着我应该def
eqn,然后尝试quad(lambda E:eqn,inf,-inf)
?我已经更新了我的代码,我知道eqn很难理解,所以它不再是块。如果eqn
是一个函数,那么你可以使用quad(lambda E:eqn(E),-inf,inf)
,但这意味着你首先不需要lambda,直接使用quad(eqn,-inf,inf)
,假设E
在-inf和inf之间不断变化。谢谢。我在程序中添加了一个循环,如更新中所示。我是否仍然需要在积分之前定义函数,以便E是一个变量,并删除E=1?我已经编辑了我的答案,使其更为明确。我也不确定quad是否知道如何处理(-inf,inf)--您可能需要帮助它并提供有限的输入(大的负数和正数),谢谢。刚刚尝试了该方法并得到了以下错误:UserWarning:积分可能发散,或缓慢收敛。
和ValueError:x和y必须具有相同的第一维度
# import V
fn = 'cooltemp.dat'
V = loadtxt(fn,unpack=True,usecols=[1])
# print V
@np.vectorize
def result(x):
def integrand(E):
del1, del2, R, fE, fEeV = 1.0,2.0,1.0,1.0,1.0
e = 1.602176565*10**-19
a = E/( math.sqrt( E**2 - del1**2 ) )
b = ( E+ e*x )/( math.sqrt( ( E + e*x )**2) - del2**2)
c = fE-fEeV
d = 1/(e*R) # integration constant
return a * b * c
return quad(integrand, -inf, inf)
I = result(V)
import numpy as np
from scipy.integrate import quad
spl=299792458.0 #speed of light in m/s
Mpc=3.0856E22 # Mpc in m
pc=3.0856E16 # pc in m
def HubbleTime(H0):
return 3.0856e17/(H0/100.0)
def HubbleDist(H0):
"""returns the Hubble Distance (in Mpc) for given H_0"""
return spl*HubbleTime(H0)/Mpc
def Integrand(z, Om, OLam):
""" This is the E(z) function from Hogg (2000)
Integrand(z, Om, OLam)
"""
return ( Om*(1+z)3 + OLam)(-0.5)
def CosmComDist(z, H0=70, Om=0.30, OLam=0.70):
"""Gives the comoving distance at redshift z
CosmComDist(z, H0=70, Om=0.30, OLam=0.70)
"""
CMD=HubbleDist(H0)*quad(Integrand, 0, z, args=(Om, OLam))[0]
return CMD
CosmComDist=np.vectorize(CosmComDist)
redshifts = np.linspace(0,1,100)
distances = CosmComDist(redshifts)