我一直试图在MATLAB中实现以下积分
给定一个数字n,我编写了返回一个包含n个元素的数组的代码,其中包含每个积分的近似值。
首先,我尝试使用' for'循环和第一行的重复关系。但是从第20个积分以及上面的值是完全错误的(正确到0有效数字和错误符号)。
如果我在第二行使用显式公式,并且两次使用'环路。
随着n越大,近似值的误差也越大。
所以这里的主要问题是我没有找到尽可能减少错误的方法。
有什么想法吗?提前谢谢。
对于n的正值,该积分不能具有值> 1或<0
答案 0 :(得分:0)
首次尝试:
我尝试了迭代方法并找到了有趣的东西。所有n
的近似值可能都不正确。事实上,如果我在每个循环中跟踪(n-1)*I(n-1)
,我可以看到
I = zeros(20,3);
I(1,1) = 1-1/exp(1);
for ii = 2:20
I(ii,2) = ii-1;
I(ii,3) = (ii-1)*I(ii-1,1);
I(ii,1) = 1-I(ii,3);
end
n = 18附近有一些问题。事实上,I18 = 0.05719和18 * I18 = 1.029,大于1.我认为此程序中没有任何数字错误或数字溢出。
第二次尝试:
为了确保数学是正确的(我在纸上验证了两次)我使用trapz
来数值计算积分,而n = 18没有引起任何问题。
>> x = linspace(0,1,1+1e4);
>> f = @(n) exp(-1)*exp(x).*x.^(n-1);
>> f = @(n) exp(-1)*exp(x).*x.^(n-1)*1e-4;
>> trapz(f(5))
ans =
1.708934160520510e-01
>> trapz(f(17))
ans =
5.571936009790170e-02
>> trapz(f(18))
ans =
5.277113416899408e-02
>>
仔细看看如下。 I18与(稳定)数值方法和(不稳定)迭代方法之间略有不同(到第4位有效数字)。因此,18 * I18可能超过1。
I = zeros(20,3);
I(1,1) = 1-1/exp(1);
for ii = 2:20
I(ii,2) = ii-1;
I(ii,3) = (ii-1)*I(ii-1,1);
I(ii,1) = 1-I(ii,3);
end
J = zeros(20,3);
x = linspace(0,1,1+1e4);
f = @(n) exp(-1)*exp(x).*x.^(n-1)*1e-4;
J(1,1) = trapz(f(1));
for jj = 2:20
J(jj,1) = trapz(f(jj));
J(jj,2) = jj-1;
J(jj,3) = (jj-1)*J(jj-1,1);
end
我怀疑由于数值计算的性质,每个迭代步骤都有一个错误。如果迭代很长,则错误会传播,不幸的是,在这种情况下,会迅速放大。为了验证这一点,我将上述两种方法合并为一种混合算法。在大多数情况下,使用迭代方法,偶尔从头开始评估数值积分,而不依赖于先前的迭代。
K = zeros(40,4);
K(1,1) = 1-1/exp(1);
for kk = 2:40
K(kk,2) = trapz(f(kk));
K(kk,3) = (kk-1)*K(kk-1,1);
K(kk,4) = 1-K(kk,3);
if mod(kk,5) == 0
K(kk,1) = K(kk,2);
else
K(kk,1) = K(kk,4);
end
end
如果迭代持续超过4步,误差放大将足以反转符号,并开始不可恢复的振荡。
代码应该能够解释所有数据结构。无论如何,让我把重点放在这里。第二列是trapz
的结果,它是在I(n)的非迭代积分定义上完成的数值积分。第三列是(n-1)* I(n-1)并且应该总是正且小于1.第四列是1-(n-1)* I(n-1)并且应该总是正的。第一列是我在trapz
结果和迭代结果之间做出的选择,是I(n)的“真实”值。
从这里可以看出,在每次迭代中,与独立数值方式相比存在小的误差。错误在第3次和第4次迭代中增加,最终在第5次破坏。这是在n = 25附近观察到的,在我从头开始每5个循环中选择数值结果的情况下。
结论:对这个积分的任何定义都没有错。然而,不幸的是,在评估表达式时数值误差是聚合的,因此限制了您执行计算的方式。