在MATLAB中通过梯形和进行积分

时间:2014-08-16 18:05:34

标签: matlab math sum integration integral

我需要帮助找到使用梯形和的函数的积分。

程序应该使用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

1 个答案:

答案 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;  ,

其中i1升级到N-1。请注意,这从 1 开始,而不是3.原因是f(a)已经考虑了第一部分,我们只计算N-1作为一部分Nf(b)计算。对于等式,这从2变为N并且通过这种方式修改代码,这正是我们最终所做的。

因此,您的陈述实际上需要是:

trapezoidsum = (dx/2)*(f(a) + (2*sum(f(a+dx*(1:n-1))))+f(b));

试试这个并告诉我你是否得到了正确的答案。正如@ADonda已经指出的那样,FWIW,MATLAB已经实现了trapz的梯形积分。但是,在设置之前,您需要正确构建xy值的内容。换句话说,您需要事先设置dx,然后使用我在上面指定的x等式计算您的x_i点,然后使用这些点生成{{1}值。然后使用y计算面积。换句话说:

trapz

您可以使用上面的代码作为参考,看看您是否正确实现了梯形规则。您的实现和使用上面的代码应该生成相同的结果。您所要做的就是更改dx = (b-a) / n; x = a + dx*(0:n); y = f(x); trapezoidsum = trapz(x,y); 的值,然后运行此代码以生成曲线下方不同细分区域的近似值。


编辑 - 2014年8月17日

我弄明白为什么你的代码无效。原因如下:

  1. n循环是不必要的。看一下for循环迭代。你有一个来自for的循环但你在你的循环中完全引用i = [3:n]变量。因此,您根本不需要这个。

  2. 您没有正确计算连续的间隔。您需要做的是计算i子区间的梯形和,然后递增n的值,然后再次计算梯形规则。在n循环中,此值未正确递增,这就是您的区域永远无法改善的原因。

  3. 您需要将先前区域保存在while循环内,然后在计算下一个区域时,确定区域之间的差异是否小于容差。我们也可以在开始时去掉那些尝试和计算while区域的代码。这不是必需的,因为我们可以将它置于您的n = 2循环中。因此,这就是您的代码应该是这样的:


  4. 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操作。您需要在操作前加一个点。一旦你这样做,我得到了正确的答案。

    编辑#2 - 2014年8月18日

    你说你想要至少一个^循环。这是非常低效的,并且在代码中指定有一个for循环的人实际上不知道MATLAB如何工作。不过,您可以使用for循环来累积for项。就这样:

    sum

    祝你好运!