我一直在用Python重写一些MATLAB代码,在尝试用Python执行二重积分时遇到了一些问题。 下面的MATLAB代码为Prad返回一个值2.5133
ant.Frequency = 3e8;
N = 5;
lambda = 3e8/ant.Frequency;
d = 0.5*lambda;
k = 2*pi/lambda;
theta = linspace(0,180,180)*pi/180;
phi = linspace(0,360,180) * pi/180;
theta0 = 0*pi/180;
phi0 = 0*pi/180;
PsiX = (k.*d.*sin(theta).*cos(phi) - k*d*sin(theta0)*cos(phi0));
PsiY = (k.*d.*sin(theta).*sin(phi) - k*d*sin(theta0)*sin(phi0));
AF = ((sin(N.*PsiX./2)./(N.*sin(PsiX./2)))).*((sin(N.*PsiY./2)./(N.*sin(PsiY./2))));
Pfun = @(x,y) ((1/N.*(sin(N.*(k.*d.*sin(x).*cos(y) - k.*d.*sin(theta0).*cos(phi0))./2)...
./sin((k.*d.*sin(x).*cos(y) - k.*d.*sin(theta0).*cos(phi0))./2))).^2).*sin(x);
Prad = integral2(Pfun,0,pi,0,2*pi);
我尝试在Python中创建相同的行为,结果Prad值为3.209E-16
theta = np.linspace(0,180,180)*np.pi/180
phi = np.linspace(0,360,180)*np.pi/180
theta0 = np.array([0])
phi0 = np.array([0])
wavelength = 3E8/3E8
k = 2 * np.pi/wavelength
d = 0.5 * wavelength
N = 5
PsiX = (k*d*np.sin(theta)*np.cos(phi) - k*d*np.sin(theta0)*np.cos(phi0))
PsiY = (k*d*np.sin(theta)*np.sin(phi) - k*d*np.sin(theta0)*np.sin(phi0))
AF = ((np.sin(N*PsiX/2)/(N*np.sin(PsiX/2)))) * ((np.sin(N*PsiY/2)/(N*np.sin(PsiY/2))))
Pfun = lambda x,y: ((1/N*(np.sin(N*(k*d*np.sin(x)*np.cos(y) - k*d*np.sin(theta0)*np.cos(phi0))/2)/np.sin((k*d*np.sin(x)*np.cos(y) - k*d*np.sin(theta0)*np.cos(phi0))/2)))**2)*np.sin(x)
Prad = dblquad(Pfun,0,np.pi,lambda x: 0, lambda x: 2*np.pi)
即使使用MATLAB dblquad函数也可以得到期望的结果。我在Python代码中有语法错误吗?还是我误解了某些功能? 问题来源StackOverflow 地址:/questions/59381403/python-quad2-and-matlab-integral2-returning-different-results
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在你的Python代码中,问题可能出在你使用dblquad
函数的方式上。MATLAB的integral2
和Python中的scipy.integrate.dblquad
虽然都是用于计算二重积分,但它们的参数和使用方式有细微差别。
在你的Python代码里,你这样调用dblquad
:
Prad = dblquad(Pfun, 0, np.pi, lambda x: 0, lambda x: 2*np.pi)
这里的问题在于,对于dblquad
的第二个和第四个参数(即边界函数),它们分别定义了内部积分(关于y
)和外部积分(关于x
)的边界。但是,你为y
的边界错误地设置了常量函数,这可能导致了积分范围的不正确设定。
正确的做法应该是确保边界函数根据x
的值来确定y
的积分范围,但在你的例子中实际上并不需要这样的依赖性,因为phi
的范围是固定的从0到2*pi
。因此,你可以直接提供这些固定值,而不是作为函数。然而,由于dblquad
的特性,你需要保持这种形式,尽管逻辑上它对y
的边界不依赖于x
。
为了更准确地模拟MATLAB的行为,你应该调整边界函数以反映实际的积分区间,但实际上在这个特定情况下,因为我们知道phi
的范围始终是从0到2*pi
,我们可以直接指定这个范围而不需要基于x
的边界函数。但鉴于dblquad
的接口要求,我们仍然需要传递lambda函数,只是它们实际上不起作用于变量x
。
不过,考虑到上述情况,一个更清晰且符合预期的转换可能是直接使用scipy.integrate.nquad
或确认dblquad
的使用是否完全符合你的需求,如果确实不需要y
的边界依赖于x
,则理解这一点很重要,因为这可能导致了不同的结果。
如果你确信边界处理无误,那么差异可能来源于数值积分的实现细节、精度设置或是浮点运算的微小差异。尝试调整积分的绝对误差容限(epsabs
)和相对误差容限(epsrel
)参数,看是否能获得更接近MATLAB结果的输出。
综上所述,建议检查并明确边界条件,并考虑是否有必要调整积分器的精度设置。