我需要帮助找到使用梯形和的函数的积分。
程序应该使用n = 1, 2, 3, ...
连续的梯形和
子区间,直到有两个n
的neighouring值相差小于给定的容差。我想在FOR
循环中至少有一个WHILE
循环,我不想使用trapz函数。该计划需要四个输入:
f
:函数句柄x
。a
:一个真实的数字。b
:大于a
的实数。tolerance
:一个正数且非常小的实数我遇到的问题是试图实现梯形和的公式
Δx/2[y0 + 2y1 + 2y2 + … + 2yn-1 + yn]
这是我的代码,而我所居住的领域是"总和"部分在FOR
循环中。我试图总结2y2 + 2y3....2yn-1
,因为我已经考虑了2y1
。我得到了答案,但它并不准确。例如,我得到6.071717974723753
而不是6.101605982576467
。
感谢您的帮助!
function t=trapintegral(f,a,b,tol)
format compact; format long;
syms x;
oldtrap = ((b-a)/2)*(f(a)+f(b));
n = 2;
h = (b-a)/n;
newtrap = (h/2)*(f(a)+(2*f(a+h))+f(b));
while (abs(newtrap-oldtrap)>=tol)
oldtrap = newtrap;
for i=[3:n]
dx = (b-a)/n;
trapezoidsum = (dx/2)*(f(x) + (2*sum(f(a+(3:n-1))))+f(b));
newtrap = trapezoidsum;
end
end
t = newtrap;
end
答案 0 :(得分:1)
此代码无效的原因是因为梯形规则的总和中存在两个小错误。我所指的是这句话:
trapezoidsum = (dx/2)*(f(x) + (2*sum(f(a+(3:n-1))))+f(b));
回想一下梯形积分规则的等式:
来源:Wikipedia
对于第一个错误,f(x)
应为f(a)
,因为您包含起点,不应将其保留为符号。实际上,您应该简单地删除syms x
语句,因为它在您的脚本中没用。通过查阅上述等式,a
对应x1
。
下一个错误是第二个任期。实际上,您需要将索引值(3:n-1)
乘以dx
。此外,这实际上应该来自(1:n-1)
,我稍后会解释。上面的等式从2变为N
,但就我们的目的而言,我们将从1变为N-1
,因为您的代码设置如此。
请记住,在梯形规则中,您将有限区间细分为n
个。 i th 片定义为:
x_i = a + dx*i; ,
其中i
从1
升级到N-1
。请注意,这从 1 开始,而不是3.原因是f(a)
已经考虑了第一部分,我们只计算N-1
作为一部分N
由f(b)
计算。对于等式,这从2变为N
并且通过这种方式修改代码,这正是我们最终所做的。
因此,您的陈述实际上需要是:
trapezoidsum = (dx/2)*(f(a) + (2*sum(f(a+dx*(1:n-1))))+f(b));
试试这个并告诉我你是否得到了正确的答案。正如@ADonda已经指出的那样,FWIW,MATLAB已经实现了trapz
的梯形积分。但是,在设置之前,您需要正确构建x
和y
值的内容。换句话说,您需要事先设置dx
,然后使用我在上面指定的x
等式计算您的x_i
点,然后使用这些点生成{{1}值。然后使用y
计算面积。换句话说:
trapz
您可以使用上面的代码作为参考,看看您是否正确实现了梯形规则。您的实现和使用上面的代码应该生成相同的结果。您所要做的就是更改dx = (b-a) / n;
x = a + dx*(0:n);
y = f(x);
trapezoidsum = trapz(x,y);
的值,然后运行此代码以生成曲线下方不同细分区域的近似值。
我弄明白为什么你的代码无效。原因如下:
n
循环是不必要的。看一下for
循环迭代。你有一个来自for
的循环但你不在你的循环中完全引用i = [3:n]
变量。因此,您根本不需要这个。
您没有正确计算连续的间隔。您需要做的是计算i
子区间的梯形和,然后递增此n
的值,然后再次计算梯形规则。在n
循环中,此值未正确递增,这就是您的区域永远无法改善的原因。
您需要将先前区域保存在while
循环内,然后在计算下一个区域时,确定区域之间的差异是否小于容差。我们也可以在开始时去掉那些尝试和计算while
区域的代码。这不是必需的,因为我们可以将它置于您的n = 2
循环中。因此,这就是您的代码应该是这样的:
while
通过运行代码,这就是我得到的:
function t=trapintegral(f,a,b,tol)
format long; %// Got rid of format compact. Useless
%// n starts at 2 - Also removed syms x - Useless statement
n = 2;
newtrap = ((b-a)/2)*(f(a) + f(b)); %// Initialize
oldtrap = 0; %// Initialize to 0
while (abs(newtrap-oldtrap)>=tol)
oldtrap = newtrap; %//Save the old area from the previous iteration
dx = (b-a)/n; %//Compute width
%//Determine sum
trapezoidsum = (dx/2)*(f(a) + (2*sum(f(a+dx*(1:n-1))))+f(b));
newtrap = trapezoidsum; % //This is the new sum
n = n + 1; % //Go to the next value of n
end
t = newtrap;
end
看看我定义你的功能的方式。 必须使用逐个元素的操作,因为循环内的trapezoidsum = trapintegral(@(x) (x+x.^2).^(1/3),1,4,0.00001)
trapezoidsum =
6.111776299189033
命令将被矢量化。请具体查看sum
操作。您需要在操作前加一个点。一旦你这样做,我得到了正确的答案。
你说你想要至少一个^
循环。这是非常低效的,并且在代码中指定有一个for
循环的人实际上不知道MATLAB如何工作。不过,您可以使用for
循环来累积for
项。就这样:
sum