在 MATLAB 中逼近积分
Approximating an integral in MATLAB
我一直在尝试在 MATLAB 中实现以下积分
给定一个数字 n,我写了代码 returns 一个有 n 个元素的数组,包含每个积分的近似值。
首先,我尝试使用 'for' 循环和第一行的递推关系。但是从第20个积分及以上的数值就完全错误了(正确为0位有效数字和错误的符号)。
如果我在第二行和两个 'for' 循环中使用显式公式,情况也是如此。
随着 n 变大,近似值的误差也会变大。
所以这里的主要问题是我还没有找到尽可能减少错误的方法。
有什么想法吗?提前致谢。
下面是代码示例和结果值,使用第二个公式:
对于 n 的正值,此积分的值不能 >1 或 <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) 的 "true" 值。
从这里可以看出,与独立数值方式相比,每次迭代都有一个小误差。错误在第 3 次和第 4 次迭代中增长,并最终在第 5 次时破坏了它。这是在 n=25 附近观察到的,在我从一开始就每 5 个循环中选择数值结果的情况下。
结论:这个积分的任何定义都没有错。然而,不幸的是,评估表达式时的数值错误是聚合的,因此限制了您可以执行计算的方式。
我一直在尝试在 MATLAB 中实现以下积分
首先,我尝试使用 'for' 循环和第一行的递推关系。但是从第20个积分及以上的数值就完全错误了(正确为0位有效数字和错误的符号)。
如果我在第二行和两个 'for' 循环中使用显式公式,情况也是如此。
随着 n 变大,近似值的误差也会变大。
所以这里的主要问题是我还没有找到尽可能减少错误的方法。
有什么想法吗?提前致谢。
下面是代码示例和结果值,使用第二个公式:
对于 n 的正值,此积分的值不能 >1 或 <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) 的 "true" 值。
从这里可以看出,与独立数值方式相比,每次迭代都有一个小误差。错误在第 3 次和第 4 次迭代中增长,并最终在第 5 次时破坏了它。这是在 n=25 附近观察到的,在我从一开始就每 5 个循环中选择数值结果的情况下。
结论:这个积分的任何定义都没有错。然而,不幸的是,评估表达式时的数值错误是聚合的,因此限制了您可以执行计算的方式。