我的辛普森算法出了什么问题?

时间:2014-08-14 18:43:36

标签: matlab numerical-methods

我试图用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是我们想要近似的被积函数。

2 个答案:

答案 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)替换它可以修复代码,从而修复准确性。