我有复合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
答案 0 :(得分:5)
一方面,你的h
定义是错误的。 h
代表您要估算的每个区间的步长。您不必要地除以2.在h
定义中删除该2。您还要使用n
而不是x
的值来评估您的函数。您可能应该删除此语句,因为最终不会使用此语句。
此外,对于奇数值或偶数值,您将从1到N+1
或从1到N-1
求和,这是不正确的。请记住,您在奇数间隔甚至间隔中选择其他所有值,因此这应该从1循环到N/2 - 1
。为了避免找出与i
相乘的内容,只需跳过这个,然后按照2的步长进行循环。但这不是重点。
我建议您不要循环并将奇数和偶数间隔的值相加。您可以通过指定x
的奇数或偶数值并仅应用总和来轻松完成此操作。我会使用冒号运算符并指定步长为2来准确确定x
的哪些值为奇数或甚至您想要应用于总和。
您还宣布x
为n
- 点间隔,但您正在覆盖循环中的这些值。在这种情况下,您实际上不需要在代码中使用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