复合辛普森的规则

时间:2014-11-12 18:09:36

标签: matlab numerical-methods numerical-integration numerical-analysis

我有复合Simpson规则的代码。但是,我一直在摆弄它已经有一段时间了,我似乎无法让它发挥作用。

如何修复此算法?

function out = Sc2(func,a,b,N)
% Sc(func,a,b,N)
% This function calculates the integral of func on the interval [a,b]
% using the Composite Simpson's rule with N subintervals.
x=linspace(a,b,N+1);
% Partition [a,b] into N subintervals
fx=func(x);
h=(b-a)/(2*N);
%define for odd and even sums
sum_even = 0;
for i = 1:N-1
   x(i) = a + (2*i-2)*h;
   sum_even = sum_even + func(x(i));
end

sum_odd = 0;

for i = 1:N+1
   x(i) = a + (2*i-1)*h;
   sum_odd = sum_odd + func(x(i));
end
% Define the length of a subinterval
out=(h/3)*(fx(1)+ 2*sum_even + 4*sum_odd +fx(end));
% Apply the composite Simpsons rule
end

1 个答案:

答案 0 :(得分:5)

一方面,你的h定义是错误的。 h代表您要估算的每个区间的步长。您不必要地除以2.在h定义中删除该2。您还要使用n 而不是x 的值来评估您的函数。您可能应该删除此语句,因为最终不会使用此语句。

此外,对于奇数值或偶数值,您将从1到N+1或从1到N-1求和,这是不正确的。请记住,您在奇数间隔甚至间隔中选择其他所有值,因此这应该从1循环到N/2 - 1。为了避免找出与i相乘的内容,只需跳过这个,然后按照2的步长进行循环。但这不是重点。

我建议您不要循环并将奇数和偶数间隔的值相加。您可以通过指定x的奇数或偶数值并仅应用总和来轻松完成此操作。我会使用冒号运算符并指定步长为2来准确确定x的哪些值为奇数或甚至您想要应用于总和。

您还宣布xn - 点间隔,但您正在覆盖循环中的这些值。在这种情况下,您实际上不需要在代码中使用x声明。

因此,这是我的函数的修改版本,我想到了优化:

function out = Sc2(func, a, b, N)

h = (b – a) / N; %// Width of each interval
odd = 1 : 2 : n-1; %// Define odd interval 
xodd = a + h*odd; %// Create odd x values 
even = 2 : 2 : n-2; %// Create even interval
xeven = a + h*even; % Create even x values 

%// Return area
out = (h/3)*(func(a) + 4*sum(func(xodd)) + 2*sum(func(xeven))+ func(b));

但是,如果您希望让代码正常工作,则只需更改for循环迭代限制以及h的值即可。您还必须删除一些代码行,并更改一些变量名称。因此:

function out = Sc2(func,a,b,N)
% Sc(func,a,b,N)
% This function calculates the integral of func on the interval [a,b]
% using the Composite Simpson's rule with N subintervals.

%// Define width of each segment
h = (b - a) / N; %// Change

%//define for odd and even sums
sum_even = 0;
for i = 2 : 2 : N-2 %// Change 
   x = a + i*h; %// Change
   sum_even = sum_even + func(x);
end

sum_odd = 0;

for i = 1 : 2 : N-1 %// Change
   x = a + i*h %// Change
   sum_odd = sum_odd + func(x);
end

%// Output area
out = (h / 3)*(func(a) + 2*sum_even + 4*sum_odd + func(b)); %// Change

end