python中强度函数的积分
有一个函数决定圆孔夫琅和费衍射图样的强度。。。() 函数在距离x=[-3.8317,3.8317]中的积分必须约为83.8%(如果假设I0为100),当您将距离增加到[-13.33,13.33]时,它应该约为95%。 但是当我在python中使用integral时,答案是错误的。。我不知道我的代码出了什么问题:(python中强度函数的积分,python,scipy,integral,numerical-integration,Python,Scipy,Integral,Numerical Integration,有一个函数决定圆孔夫琅和费衍射图样的强度。。。() 函数在距离x=[-3.8317,3.8317]中的积分必须约为83.8%(如果假设I0为100),当您将距离增加到[-13.33,13.33]时,它应该约为95%。 但是当我在python中使用integral时,答案是错误的。。我不知道我的代码出了什么问题:( 积分的结果不能大于100(I0),因为这是I0的衍射…我不知道…可能是缩放…可能是方法!:(问题似乎在于函数的行为接近于零。如果绘制函数,它看起来很平滑: 但是,scipy.inte
积分的结果不能大于100(I0),因为这是I0的衍射…我不知道…可能是缩放…可能是方法!:(问题似乎在于函数的行为接近于零。如果绘制函数,它看起来很平滑: 但是,
scipy.integrate.quad
抱怨舍入错误,这对于这条漂亮的曲线来说非常奇怪。但是,函数没有定义为0(当然,你是在除以0!),因此积分不太顺利
你可以使用一种更简单的积分方法,或者对你的函数做些什么。你也可以从两边将它积分到非常接近零的位置。但是,当你看到结果时,这些数字的积分看起来并不正确
然而,我想我对你的问题有预感。据我所记得的,你所展示的积分实际上是夫琅和费衍射的强度(功率/面积),作为距离中心的函数。如果你想在某个半径内积分总功率,你必须在二维中进行
根据简单的面积积分规则,在积分之前,你应该将你的函数乘以2πr(或者在你的例子中是x而不是r)。然后它变成:
f = lambda(r): r*(sp.j1(r)/r)**2
或
或者更好:
f = lambda(r): r * (sp.j0(r) + sp.jn(2,r))
最后一种形式是最好的,因为它没有任何奇点。它基于Jaime对原始答案的评论(请参见下面的评论!)
(注意,我省略了几个常数。)现在你可以将它从零积分到无穷大(没有负半径):
然后,可以从其他半径进行积分,并按全强度进行规格化:
pwr = quad(f, 1e-9, 3.8317)[0] / fullpower
你得到了0.839(相当接近84%)。如果你尝试更远的半径(13.33):
这等于0.954
需要注意的是,我们通过从1e-9开始积分而不是从0开始积分引入了一个小误差。可以通过尝试不同的起点值来估计误差的大小。积分结果在1e-9和1e-12之间变化很小,因此它们似乎是安全的。当然,您可以使用,例如,1e-30,但随后会出现在除法中,y可能是数值上的不稳定性(在这种情况下没有,但通常奇点在数值上是邪恶的)
让我们仍然做一件事:
import matplotlib.pyplot as plt
import numpy as np
x = linspace(0.01, 20, 1000)
intg = np.array([ quad(f, 1e-9, xx)[0] for xx in x])
plt.plot(x, intg/fullpower)
plt.grid('on')
plt.show()
这就是我们得到的:
至少这看起来是对的,艾里圆盘的黑色边缘清晰可见
问题的最后一部分是什么:I0定义了最大强度(单位可能是W/m2),而积分给出了总功率(如果强度以W/m2为单位,则总功率以W为单位)。将“最大强度”设置为100并不能保证总功率。这就是为什么计算总功率很重要的原因 对于辐射到圆形区域的总功率,实际上存在一个封闭式方程: p(x)=P0(1-J0(x)^2-J1(x)^2)
式中,P0为总功率。当在x=0处计算雅可比矩阵时,它们可能是积分算法中的奇点。您可以使用“”将该点从积分中排除: 然后我得到以下结果(这是你想要的结果吗?)
请注意,您还可以使用以下方法获得用于集成的封闭式解决方案:
F
的计算结果为:
1600*d*besselj(0, Abs(d))**2/3 + 1600*d*besselj(1, Abs(d))**2/3 - 800*besselj(1, Abs(d))**2/(3*d)
用
besselj(0,r)
对应于sp.j0(r)
谢谢杜德。这很好;)回答得很好,+1.Abramowitz和Stegun说2*j1(x)/x=j0(x)+j2(x)
,所以你也可以通过使你的函数I0*(sp.j0(x)+sp.jn(2,x))来解决所有的数值问题**2
。我相信这应该可以让你从0开始集成。我已经编辑了我的问题(添加了一个额外的部分)…你对此有什么想法吗?@Jaime,你有什么想法吗?
pwr = quad(f, 1e-9, 3.8317)[0] / fullpower
pwr = quad(f, 1e-9, 13.33)
import matplotlib.pyplot as plt
import numpy as np
x = linspace(0.01, 20, 1000)
intg = np.array([ quad(f, 1e-9, xx)[0] for xx in x])
plt.plot(x, intg/fullpower)
plt.grid('on')
plt.show()
f = lambda x:( I0*((2*sp.j1(x)/x)**2))
I = quad(f, -dist, dist, points = [0])
331.4990321315221
import sympy as sy
sy.init_printing() # LaTeX like pretty printing in IPython
x,d = sy.symbols("x,d", real=True)
I0=100
dist=3.8317
f = I0*((2*sy.besselj(1,x)/x)**2) # the integrand
F = f.integrate((x, -d, d)) # symbolic integration
print(F.evalf(subs={d:dist})) # numeric evalution
1600*d*besselj(0, Abs(d))**2/3 + 1600*d*besselj(1, Abs(d))**2/3 - 800*besselj(1, Abs(d))**2/(3*d)