分别利用变步长复化梯形公式、变步长复化Simpson公式和复化Guass-Legendre I型公式计算下列式子,要求绝对误差限为 0.5 ∗ 1 0 − 7 0.5*10^{-7} 0.5∗10−7,并比较每种算法的计算时间。
(1) ln 2 − ln 3 = − 2 ∫ 2 3 1 x 2 − 1 d x \ln2-\ln3=-2\int^3_2{1\over x^2-1}dx ln2−ln3=−2∫23x2−11dx
(2) π = 4 ∫ 0 1 1 x 2 + 1 d x \pi=4\int^1_0{1\over x^2+1}dx π=4∫01x2+11dx
(3) 2 ln 3 = ∫ 0 1 3 x d x {2\over \ln3}=\int^1_0 3^xdx ln32=∫013xdx
(4) e 2 = ∫ 1 2 x e x d x e^2=\int^2_1xe^xdx e2=∫12xexdx
1.1、变步长复化梯形公式和变步长Simpson公式,是在实际计算时,将区间逐次分半计算(每分一次就进行一次计算),并利用结果来判断误差的大小。
对于变步长复化梯形公式,有
1.2、以上两种,实际上限定了求积公式的精度。若以求公式的代数精度达到最大值的原则去选取求积节点和求出相应的求积系数,那就是Gauss求积公式。以Gauss-Legendre I型求积公式为例子,在区间[a,b]的复化积分公式为:
∫ b a f ( x ) d x = h 2 ∑ k = 0 n − 1 [ f ( x k + 1 2 − h 2 3 ) + f ( x k + 1 2 + h 2 3 ) ] \int^a_bf(x)dx={h\over 2}\sum_{k=0}^{n-1}[f(x_{k+{1\over2}}-{h\over2\sqrt3})+f(x_{k+{1\over2}}+{h\over2\sqrt3})] ∫baf(x)dx=2h∑k=0n−1[f(xk+21−23h)+f(xk+21+23h)]
function test_4_1
%分别利用变步长复化梯形公式、变步长复化Simpson公式、复化Gauss-Legendre I型公式计算。
% 绝对误差限为1/2*10^(-7)
% 将计算结果与精确解作比较,并比较各种算法的运行时间
promps={'选择积分公式,若用变步长复化梯形公式,输入T;用复化Simpson公式,输入S;用复化Gauss_Legendre,输入GL'};
Nb=char(inputdlg(promps,'text_4_1',1,{'T'}));
if (Nb~='T'& Nb~='S'& Nb~='GL')
errordlg('积分公式选择错误!');
return;
end
Nb_f=str2num(char(inputdlg('输入积分式子题号1-4:','text_4_1',1,{'1'})));
if(Nb_f<1'&&Nb_f>4)
errordlg('没有该积分式子');
return;
end
switch Nb_f
case 1
fun=@(x)-2./(x.^2-1);a=2;b=3;
case 2
fun=@(x)4./(1+x.^2);a=0;b=1;
case 3
fun=@(x)3.^x;a=0;b=1;
case 4
fun=@(x)x.*exp(x);a=1;b=2;
end
r=0.5e-7;%误差
if (Nb=='T')%变步长复化梯形公式
tic;
t=(fun(a)+fun(b))*(b-a)/2;
t0=0;
k=1;
while abs(t-t0)>=3*r%用区间逐次分半求积分,T2n-Tn<3r
h=(b-a)/(2^k);
t0=t;
t=(fun(a)+fun(b))*h/2+h*sum(fun(a+h:h:b-h));
k=k+1;
end
time=toc;
elseif (Nb=='S')%变步长复化Simpson公式
tic;
[t,iter]=quad(fun,a,b,r);%quad()函数是MATLAB自带的Simpson自适应函数
time=toc;
elseif (Nb=='GL')%复化Gauss-Legendre I型公式
tic;
promps={'请输入用复化Gauss-Legendre I型公式应取的步长:'};
h=str2num(char(inputdlg(promps,'test 4-1',1,{'0.01'})));
N=(b-a)/h;t=0;
for k=1:N-1
xk=a+k*h+h/2;
t=t+fun(xk-h/(2*sqrt(3)))+fun(xk+h/(2*sqrt(3)));
end
t=t*h/2;
time=toc;
end
fprintf('方程(%s)的计算结果:%.10f\n',Nb,t);
switch Nb_f
case 1
result=log(2)-log(3);
fprintf('精确解:ln2-ln3=%.10f\n',result);
disp(['绝对误差:',num2str(abs(t-result))]);
disp(['运行时间:',num2str(time)]);
case 2
result=pi;
fprintf('精确解:Π=%.10f\n',result);
disp(['绝对误差:',num2str(abs(t-result))]);
disp(['运行时间:',num2str(time)]);
case 3
result=2/log(3);
fprintf('精确解:2/log(3)=%.10f\n',result);
disp(['绝对误差:',num2str(abs(t-result))]);
disp(['运行时间:',num2str(time)]);
case 4
result=exp(2);
fprintf('精确解:exp(2)=%.10f\n',result);
disp(['绝对误差:',num2str(abs(t-result))]);
disp(['运行时间:',num2str(time)]);
end
从结果可看出,精度最高的是Guass-Legendre I型公式,且步长取得越小,绝对误差越小,但是相应所花费的时间越长。而计算时间最短的是变步长梯形公式,但是其绝对误差三者中最大。
绝对误差:Guass-Legendre I型公式<变步长Simpson公式<变步长复化梯形公式
计算时间:变步长复化梯形公式<变步长Simpson公式
利用复化Simpson公式和变步长复化Simpson公式计算下列定积分,并比较这两种算法所需的节点数和计算时间,要求绝对误差限为 0.5 ∗ 1 0 − 7 0.5*10^{-7} 0.5∗10−7。
(1) ∫ 0 2 ( ( x 6 10 − x 2 + x ) d x \int ^2_0(({x^6\over 10}-x^2+x)dx ∫02((10x6−x2+x)dx
(2) ∫ 0 1 x x d x \int^1_0x\sqrt xdx ∫01xxdx
(3) ∫ 5 200 1 x d x \int^{200}_5{1\over \sqrt x}dx ∫5200x1dx
复化Simpson公式:
S n = h 6 [ f ( a ) + 4 ∑ k = 0 n − 1 [ f ( x k + 1 2 ) + 2 ∑ k = 1 n − 1 f ( x k ) + f ( b ) ] S_n={h\over 6}[f(a)+4\sum_{k=0}^{n-1}[f(x_{k+{1\over2}})+2\sum_{k=1}^{n-1} f(x_k)+f(b)] Sn=6h[f(a)+4∑k=0n−1[f(xk+21)+2∑k=1n−1f(xk)+f(b)]
变步长复化Simpson公式如实验一,在MATLAB中可以调用库函数quad()
function test_4_1
promps={'选择积分公式,用复化Simpson公式,输入S;用变步长复化Simpson公式,输入VS'};
Nb=char(inputdlg(promps,'text_4_2',1,{'S'}));
if (Nb~='S'& Nb~='VS')
errordlg('积分公式选择错误!');
return;
end
Nb_f=str2num(char(inputdlg('输入积分式子题号1-3:','text_4_2',1,{'1'})));
if(Nb_f<1 &&Nb_f>3)
errordlg('没有该积分式子');
return;
end
switch Nb_f
case 1
fun=@(x)(x.^6/10)-x.^2+x;a=0;b=2;
case 2
fun=@(x)x.*sqrt(x);a=0;b=1;
case 3
fun=@(x)1./sqrt(x);a=5;b=200;
end
r=0.5e-7;%误差
if (Nb=='S')%复化Simpson公式
tic;
promps={'请输入用复化Simpson公式应取的步长:'};
h=str2num(char(inputdlg(promps,'test 4-2',1,{'0.01'})));
N=(b-a)/h;t1=0;t2=0;
for k=0:N-1
xk=a+k*h+h/2;
t1=t1+fun(xk);
end
for k=1:N-1
xk=a+k*h;
t2=t2+fun(xk);
end
t=(1+fun(b)+4*t1+2*t2)*h/6;
n=2*N+1;
time=toc;
elseif (Nb=='VS')%变步长复化Simpson公式
tic;
[t,iter]=quad(fun,a,b,r);
n=2*iter+1;
time=toc;
end
fprintf('方程(%s)的计算结果:\n',Nb);
if (Nb=='S')
fprintf('用复化Simpson公式,所需的节点数:%d,求得的近似值:%.10f,运行时间:%.5f\n',n,t,time);
elseif(Nb=='VS')
fprintf('用变步长复化Simpson公式,所需的节点数:%d,求得的近似值:%.10f,运行时间:%.5f\n',n,t,time);
end