我试图用Simpson的方法编写一个近似积分的算法。然而,当我尝试在loglog图中绘制它时,我没有得到正确的准确度,即O(h ^ 4)(我得到O(n))。我找不到任何错误。这是我的代码:
%Reference solution with Simpson's method (the reference solution works well)
yk = 0;
yj = 0;
href = 0.0001;
mref = (b-a)/href;
for k=2:2:mref-1
yk=yk+y(k*href+a);
end
for j=1:2:mref
yj=yj+y(href*j+a);
end
Iref=(href/3)*(y(a)+y(b)+2*yk+4*yj);
%Simpson's method
iter = 1;
Ehmatrix = 0;
for n = 0:nmax
h = b/(2^n+1);
x = a:h:b;
xodd = x(2:2:end-1);
xeven = x(3:2:end);
yodd = y(xodd);
yeven = y(xeven);
Isimp = (h/3)*(y(x(1))+4*sum(yodd)+2*sum(yeven)+y(b));
E = abs(Isimp-Iref);
Ehmatrix([iter],1) = [E];
Ehmatrix([iter],2) = [h];
iter = iter + 1;
end
figure
loglog(Ehmatrix(:,2),Ehmatrix(:,1))
a和b是积分限制,y是我们想要近似的被积函数。
答案 0 :(得分:3)
Djamillah - 虽然h
的初始化可能仅适用于a==0
的情况,但您的代码看起来很好,因此您可能希望将此行代码更改为
h = (b-a)/(2^n+1);
我想知道x = a:h:b;
是否始终有效 - 有时b
可能会包含在列表中,有时也可能不会,h
。您可能需要重新考虑并使用linspace
代替
x = linspace(a,b,2^n+1);
这将保证x
在[a,b]
区间内均匀分布2 ^ n + 1个点。然后可以将h
初始化为
h = x(2)-x(1);
此外,在确定偶数和奇数索引时,我们需要忽略偶数和奇数的x
的最后一个元素。而不是
xodd = x(2:2:end-1);
xeven = x(3:2:end);
DO
xodd = x(2:2:end-1);
xeven = x(3:2:end-1);
最后,不是使用向量y
(这是如何设置的?)我可能只使用函数句柄来代替我集成的函数,并将上面的计算替换为
Isimp = delta/3*(func(x(1)) + 4*sum(func(xodd)) + 2*sum(func(xeven)) + ...
func(x(end)));
除了这些微小的东西(可能是微不足道的)之外,你的算法中没有任何东西可以指出问题。它产生的结果与我的版本相似。
至于收敛顺序,应该是O(n^4)
还是O(h^4)
?
答案 1 :(得分:1)
考虑到Geoff的建议,并进行一些其他更改,这一切都按预期工作。
%Reference solution with Simpson's method (the reference solution works well)
a=0;
b=1;
y=@(x) cos(x);
nmax=10;
%Simpson's method
Ehmatrix = [];
for n = 0:nmax
x = linspace(a,b,2^n+1);
h = x(2)-x(1);
xodd = x(2:2:end-1);
xeven = x(3:2:end-1);
yodd = y(xodd);
yeven = y(xeven);
Isimp = (h/3)*(y(x(1))+4*sum(yodd)+2*sum(yeven)+y(b));
E = abs(Isimp-integral(y,0,1));
Ehmatrix(n+1,:) = [E h];
end
loglog(Ehmatrix(:,2),Ehmatrix(:,1))
P=polyfit(log(Ehmatrix(:,2)),log(Ehmatrix(:,1)),1);
OrderofAccuracy=P(1)
由于O(h)
错误,您的准确率为xeven=x(3:2:end)
。用xeven=x(3:e:end-1)
替换它可以修复代码,从而修复准确性。