while ((ep>=eps)&&(abs(h)>d))||(n<16),
x=a-h; t2=0.5*t1;
for j=1:n
x=x+2.0*h;
g=simp1(x,eps);
t2=t2+h*g;
end
s=(4.0*t2-t1)/3.0;
ep=abs(s-s0)/(1.0+abs(s));
n=n+n; s0=s; t1=t2; h=h*0.5;
end
end
function g=simp1(x,eps)
n=1;
[y0,y1]=f2s(x);
h=0.5*(y1-y0);
d=abs(h*2.0e-06);
t1=h*(f2f(x,y0)+f2f(x,y1));
ep=1.0+eps; g0=1.0e+35;
while (((ep>=eps)&&(abs(h)>d))||(n<16))
yy=y0-h;
t2=0.5*t1;
for i=1:n
yy=yy+2.0*h;
t2=t2+h*f2f(x,yy);
end
g=(4.0*t2-t1)/3.0;
ep=abs(g-g0)/(1.0+abs(g));
n=n+n; g0=g; t1=t2; h=0.5*h;
end
end
%file f2s.m
function [y0,y1]=f2s(x)
y0=-sqrt(1.0-x*x);
y1=-y0;
end
%file f2f.m
function c=f2f(x,y)
c=exp(x*x+y*y);
end
%%%%%%%%%%%%%
>> tic
for i=1:100
a=fsim2(0,1,0.0001);
end
a
toc
a =
2.6989
Elapsed time is 0.995575 seconds.
-------
Lu代码:
fsim2s(x,y0,y1)=
{
y0=-sqrt(1.0-x*x),
y1=-y0
};
fsim2f(x,y)=exp(x*x+y*y);
//////////////////
simp1(x,eps : n,i,y0,y1,h,d,t1,yy,t2,g,ep,g0)=
{
n=1,
fsim2s(x,&y0,&y1),
h=0.5*(y1-y0),
d=abs(h*2.0e-06),
t1=h*(fsim2f(x,y0)+fsim2f(x,y1)),
ep=1.0+eps, g0=1.0e+35,
while {((ep>=eps)&(abs(h)>d))|(n<16),
yy=y0-h,
t2=0.5*t1,
i=1, while{i<=n,
yy=yy+2.0*h,
t2=t2+h*fsim2f(x,yy),
i++
},
g=(4.0*t2-t1)/3.0,
ep=abs(g-g0)/(1.0+abs(g)),
n=n+n, g0=g, t1=t2, h=0.5*h
},
g
};
fsim2(a,b,eps : n,j,h,d,s1,s2,t1,x,t2,g,s,s0,ep)=
{
n=1, h=0.5*(b-a),
d=abs((b-a)*1.0e-06),
s1=simp1(a,eps), s2=simp1(b,eps),
t1=h*(s1+s2),
s0=1.0e+35, ep=1.0+eps,
while {((ep>=eps)&(abs(h)>d))|(n<16),
x=a-h, t2=0.5*t1,
j=1, while{j<=n,
x=x+2.0*h,
g=simp1(x,eps),
t2=t2+h*g,
j++
},
s=(4.0*t2-t1)/3.0,
ep=abs(s-s0)/(1.0+abs(s)),
n=n+n, s0=s, t1=t2, h=h*0.5
},
s
};
//////////////////
main(:t0,i,a)=
t0=clock(),
i=0, while{i<100, a=fsim2(0,1,0.0001), i++},
o{"a=",a,", time=",[clock()-t0]/1000.};
Lu结果:
a=2.6989250006243033, time=0.657
---------
本例C/C++、matlab、Lu运行耗时之比为 1:12.7:8.5 。
=========
以下将变步长辛卜生二重求积算法写成通用的函数。不再给出C/C++代码,因其效率不会发生变化。
注意函数fsim2中增加了两个参数,函数句柄fsim2s用于计算二重积分时内层的上下限,函数句柄fsim2f用于计算积分函数的值。
Matlab 2009a代码:
%file fsim2.m
function s=fsim2(a,b,eps,fsim2s,fsim2f)
n=1; h=0.5*(b-a);
d=abs((b-a)*1.0e-06);
s1=simp1(a,eps,fsim2s,fsim2f); s2=simp1(b,eps,fsim2s,fsim2f);
t1=h*(s1+s2);
s0=1.0e+35; ep=1.0+eps;
while ((ep>=eps)&&(abs(h)>d))||(n<16),
x=a-h; t2=0.5*t1;
for j=1:n
x=x+2.0*h;
g=simp1(x,eps,fsim2s,fsim2f);
t2=t2+h*g;
end
s=(4.0*t2-t1)/3.0;
ep=abs(s-s0)/(1.0+abs(s));
n=n+n; s0=s; t1=t2; h=h*0.5;
end
end
function g=simp1(x,eps,fsim2s,fsim2f)
n=1;
[y0,y1]=fsim2s(x);
h=0.5*(y1-y0);
d=abs(h*2.0e-06);
t1=h*(fsim2f(x,y0)+fsim2f(x,y1));
ep=1.0+eps; g0=1.0e+35;
while (((ep>=eps)&&(abs(h)>d))||(n<16))
yy=y0-h;
t2=0.5*t1;
for i=1:n
yy=yy+2.0*h;
t2=t2+h*fsim2f(x,yy);
end
g=(4.0*t2-t1)/3.0;
ep=abs(g-g0)