I';我正在尝试将我的matlab代码转换为python,以实现自适应高斯求积
Matlab代码运行良好I';我正在尝试将我的matlab代码转换为python,以实现自适应高斯求积,python,matlab,numerical-integration,Python,Matlab,Numerical Integration,Matlab代码运行良好 function [int, abt]= gadap(a,b,f,p,tol); % a,b: interval endpoints with a < b % f: function handle f(x, p) to integrate (p for user parameters) % tol: User-provided tolerance for integral accuracy % int: Approximation to the integral
function [int, abt]= gadap(a,b,f,p,tol);
% a,b: interval endpoints with a < b
% f: function handle f(x, p) to integrate (p for user parameters)
% tol: User-provided tolerance for integral accuracy
% int: Approximation to the integral
% abt: Endpoints and approximations
a_j=a;
b_j=b;
j=1;
int=0;
n=1;
abt=[[a_j,b_j,0]];
while j<=n
%%%Evaluation of t%%%
t_j=(b_j-a_j)/2*(5/9*f((b_j-a_j)/2*-1*sqrt(3/5)+(b_j+a_j)/2)+8/9*f((b_j+a_j)/2)+5/9*f((b_j-a_j)/2*sqrt(3/5)+(b_j+a_j)/2));
%%%Evaluation of l%%%
k=j+1;
a_k=a_j;
b_k=a_j+(b_j-a_j)/2;
l_j=(b_k-a_k)/2*(5/9*f((b_k-a_k)/2*-1*sqrt(3/5)+(b_k+a_k)/2)+8/9*f((b_k+a_k)/2)+5/9*f((b_k-a_k)/2*sqrt(3/5)+(b_k+a_k)/2));
%%%Evaluation of r%%%
z=j+2;
a_z=a_j+(b_j-a_j)/2;
b_z=b_j;
r_j=(b_z-a_z)/2*(5/9*f((b_z-a_z)/2*-1*sqrt(3/5)+(b_z+a_z)/2)+8/9*f((b_z+a_z)/2)+5/9*f((b_z-a_z)/2*sqrt(3/5)+(b_z+a_z)/2));
%%%List Generation%%%
if abs(t_j-(l_j+r_j))>tol*max(abs(t_j), (abs(l_j)+abs(r_j)))
abt=[abt; [a_k, b_k, l_j]; [a_z, b_z, r_j]];
else
int=int+t_j;
end
n=size(abt,1);
j=j+1;
if j>n
continue
end
a_j=abt(j,1);
b_j=abt(j,2);
end
function[int,abt]=gadap(a,b,f,p,tol);
%a,b:an
持续
结束
a_j=abt(j,1);
b_j=abt(j,2);
结束
Python代码
import numpy as np
from numpy import *
from numpy import array
f = lambda x:x**2
def gaussian(a,b,f,tolerance):
# a,b: interval endpoints with a < b
# f: function f(x) to integrate
# tol: tolerance for integral accuracy
# integral: Approximation to the integral
# abt: Endpoints and approximations
a_j=a
b_j=b
j=0
integral=0
n=0
abt=matrix([a_j,b_j,0])
while j<=n:
#Evaluation of t
t_j=(b_j-a_j)/2*(5/9*f((b_j-a_j)/2*-1*sqrt(3/5)+(b_j+a_j)/2)+8/9*f((b_j+a_j)/2)+5/9*f((b_j-a_j)/2*sqrt(3/5)+(b_j+a_j)/2))
#Evaluation of right
z=j+2;
a_z=a_j+(b_j-a_j)/2;
b_z=b_j;
r_j=(b_z-a_z)/2*(5/9*f((b_z-a_z)/2*-1*sqrt(3/5)+(b_z+a_z)/2)+8/9*f((b_z+a_z)/2)+5/9*f((b_z-a_z)/2*sqrt(3/5)+(b_z+a_z)/2))
#Evaluation of left
k=j+1;
a_k=a_j;
b_k=a_j+(b_j-a_j)/2;
l_j=(b_k-a_k)/2*(5/9*f((b_k-a_k)/2*-1*sqrt(3/5)+(b_k+a_k)/2)+8/9*f((b_k+a_k)/2)+5/9*f((b_k-a_k)/2*sqrt(3/5)+(b_k+a_k)/2))
if abs(t_j-(l_j+r_j))>tolerance*max(abs(t_j), (abs(l_j)+abs(r_j))):
abt=numpy.vstack([abt, [a_k, b_k, l_j], [a_z, b_z, r_j]])
else:
integral=integral+t_j
n=abt.shape[0]
j=j+1
if j>n:
continue
a_j=abt[j,0]
b_j=abt[j,1]
return integral
print gaussian(0,2,f,10**(-3))
将numpy导入为np
从numpy进口*
从numpy导入数组
f=λx:x**2
def高斯(a、b、f、公差):
#a,b:an:
持续
a_j=abt[j,0]
b_j=abt[j,1]
返回积分
打印高斯(0,2,f,10**(-3))
但是当我为我的函数测试python代码时,我得到了一个错误。怎么了?要返回整数值,我更改了一些索引,但它一直返回整数值0,这就是我初始化整数值的原因。现在它告诉我错误是
索引器回溯(最后一次最近调用)
在()
45返回积分
46
--->47打印高斯(0,2,f,10**(-3))
四十八
高斯分布(a、b、f、公差)
41如果j>n:
42继续
--->43 a_j=abt[j,0]
44 b_j=abt[j,1]
45返回积分
C:\Users\Brandon Tran\AppData\Local\enthund\Canopy\User\lib\site packages\numpy\matrixlib\defmatrix.pyc ingetitem(self,index)
314
315尝试:
-->316 out=N.ndarray.getitem(自身,索引)
317最后:
318 self.\u getitem=False
索引器错误:索引1超出大小为1的轴0的界限。您的问题是MATLAB和numpy对数组索引使用不同的顺序。MATLAB使用Fortran编程语言的顺序,而numpy(默认情况下)使用C语言的顺序。这些是相反的。所以,当你的MATLAB矩阵是Nx1矩阵时,你的numpy矩阵是1xN矩阵。因此,例如,
a_j=abt[j,0]
应该是a_j=abt[0,j]
。您可以使用abt.shape
验证这一点,它将为您提供(1,3)
还有其他问题。在Python2.x中,两个整数的除法返回一个整数。因此,例如5/9
,就是0
。在您的代码顶部,您应该放置来自未来导入部门的,
,以使其按照您期望的方式运行
另外,你真的不应该一开始就使用numpy矩阵。坚持使用numpy阵列,它们得到了更好的支持。这样,只需使用1D数组就可以完全避免问题
最后,将numpy作为np导入比从numpy导入*导入安全得多,这可能会与内置版本产生函数名冲突。无需自行实现。(我写的)有自适应正交 安装
pip install quadpy
试一试
从numpy导入exp
导入四边形
val,err=quadpy.quad(λx:exp(0.3*x)、0.0、1.0)
打印(val)
打印(错误)
代码通过Gauss Kronrod实现自适应。我们无法为您调试代码,但我猜您在使用Matlab和Python处理索引的不同方式时遇到了问题:Matlab数组的索引从1开始,Python数组的第一个索引是0。
1.1661960252533439
3.170663072723789e-20