误差传播与算法稳定性试验报告
《数值计算方法》
专业班级
姓 名
学 号 08083117
时 间 2010年10月20日星期三
一. 实验目的
体会稳定性在选择算法中的地位,误差扩张的算法是不稳定的,是
我们所不期望的;误差衰减的算法是稳定的,是我们努力寻求的,这是贯穿本课程的目标。
二. 问题的提出
考虑一个简单的由积分定义的序列
I n =⎰x n e n -1dx , n =1, 2, ⋯
x -1
=1时,I 1=⎰0x e dx =1/e 。当n ≥2时,利
1
1
显然 I n >0, n =1, 2, ⋯当n
用部分积分易得
I n =⎰x e dx =x e
1
n -1
n x -11
n
x -1
-⎰nx n -1e x -1dx =1-nI n -1, n =2, 3⋯,
10
1
另一方面,有I n =
⎰
x e
dx ≤⎰x n dx =1/(n +1)
三. 试验内容
依次用一下两种迭代方法计算指定范围内的序列值。 (Ⅰ) 、I 1
(Ⅱ) 、I N
=1/e , I n =1-nI n -1, n =2, 3⋯,
=0, I n -1
1-I n
=, n =N , N -1, N -2,. ⋯, 3, 2
n
四. 主程序流程
五. 源程序
#include
#include
//根据初始值origin 按照递推公式I(n)=1-nI(n-1) //计算各项的值, 并输出 //1/e=0.3678794412
void funcOne(double origin) {
int i,n=0;//迭代次数, 及下标号 char oper;//操作符号
double value;
value=origin; while (1) { for (i=0;i=-10e6&&value
return; }
//根据参数n 确定初值I(n)=0 //计算n-1、n-2...0的值 void funcTwo(int n) {
int i; //循环变量 char oper; //操作符 double value=0; //初始值为0 while (1) { for (i=1;i1) value=(1-value)/n; else return; //如果n 为0可以直接返回 n--; //个数减一 } printf("\tq停止迭代或按其他任意键继续:");
oper=getch(); printf("\n"); if (oper=='q'||oper=='Q') break; //如果放弃了, 则退出迭代 } }
//测试第一个迭代函数 void testFunOne() {
printf("\n\t*******初值是5位有效数字******\n"); funcOne(0.36788);
printf("\n\t*******初值是6位有效数字*******\n"); funcOne(0.367879);
printf("\n\t*******初值是7位有效数字*******\n"); funcOne(0.3678794); }
//测试第二个迭代函数 void testFunTwo() {
int originN; //N的初始值
printf("\n\t输入N 的值(I(N)=0):"); scanf("%d",&originN);
if(originN
void main() {
char sel; //选项 while(1) { printf("\n\t选择迭代公式:"); printf("\n\t1.迭代公式:I(n)=1-n*I(n-1)"); printf("\n\t2.迭代公式:I(n-1)=(1-I(n))/n\n\t"); sel=getch(); if (sel=='1')testFunOne(); else testFunTwo(); printf("\n\t按任一键继续:"); getch(); } }
六. 程序运行结果
1、第一种迭代方式
(1)、五位有效数字:
程序运行,选择要测试的函数,选择第一个:
程序在迭代的过程中每次输出6项的值,如上图所示,初值I(1)=0.36788,可以看到,到此就已经存在误差较大的值,因为我们研究的积分序列一定满足0
从以上的各项中更可以看出,I(n)的迭代值已经出现严重的扭曲,简而言之,由于初值I(1)的误差,使得按它计算的其他项的误差是放大的,下面给出初值是六位的迭代过程。 (2)、六位有效数字:
尽管6位有效数字比5位的精确,但是计算的各项仍然出现严重的扭曲,出现误差放大。下面给出有效数字是7位的结果。 (3)、七位有效数字:
由此可以得出和六位有效数字时一样的结论,虽然7位有效数字较5位或6位的
要精确,但是结果中仍然有误差放大现象,结果出现严重失真。 (4)、迭代方式一的结论: 综合上面的(1)、(2)、(3)三点可知方式一的递推形式是不稳定的。
2、第二种迭代方式
运行结果如下图所示,给出N 的值,从N 开始计算N-1,N-2,…,1 各项的值,每次计算输出10项,按退出输出。 这里我输入
N=200
下面截取其中的一部分结果, 130-101项的。
70-51项的值:
最后给出20-1的值:
可以看出计算I(1)的结果与精确值=0.3678794相当,为了保证结论的可靠性,可以输入其他的N 值来估计I(1)的值。总之,算法二的递推形式是稳定的。
七. 结论与分析
(1)、分别用算法(Ⅰ) ,(Ⅱ) 计算,在计算中分别采用5位,6位,7位有效数字,
结果已经在上面的程序结果中给出。有结果我们知道算法(Ⅰ) 是不稳定的算法,而算法(Ⅱ) 是稳定的。 (2)、比较两种算法的优劣,从理论上推导结果。
对算法(Ⅰ) 中:
I 1的计算误差为e 1,由I 1递推计算I n 的误差是e n 中的I N 的计算误差为εN
=I n -I n
^
;算法(Ⅱ)
=I N -I N
^
,有I N 向前递推计算I n (n
N ) 的误
差为εn ,如果在上述两种算法中都假定后面的计算不再引入其他的误差,下面给出e n 与e 1的关系和εn 与εN 的关系。
I n =1-nI n -1, n =2, 3⋯
^
设I n 的准确值为I n ,
则有 I n
^
=1-n I n -1, n =2, 3⋯
^
^
将上面两式想减可得:
|I n -I n |=n |I n -1-I n -1|
^
也即,e n 从而,e n
=ne n -1, n =2, 3,....
=ne n -1=... =n ! e 1, n =2, 3,....
由此结论可知,当初始值I 1产生的误差e 1会经过迭代之后不断的放
大,最终估计的值将失真,即误差e 1对后面的影响是扩张的。因此算
法(Ⅰ) 是不稳定的算法。
对算法(Ⅱ) 有,
I N =0, I n -1
1-I n =, n =N , N -1, N -2,. ⋯, 3, 2
n
^
设I n 的准确值为I n ,
1-I n
, n =N , N -1, ⋯2 则有, I n -1=n
^
^
将以上两式相减可得,
εn -1=
εn
n
, n =N , N -1,...., 2
εN
N (N -1) ⋯(n +1)
,n =N -1, N -2, ⋯, 1
从而可知,εn =
有这个公司可以看出,当给出初值
I N
时,由于存在误差
εN =I N -I N
^
,当向前递推时,误差会逐级缩小,而且当N 较大是往后
^
的误差将趋向于0,误差不会放大,误差εN 衰减的,故此算法是稳定的。
=I N -I N
对后面的影响是
八. 收获与感想
这次试验通过一个积分式所对应的两种递推计算方法,从具体的数
据出发,深刻的感受了初始值的扰动对后面的计算值的影响,对于不稳定的算法,当初始值出现较小的扰动时,后面的值的误差将出现扩张,而对于稳定的算法,即使初值出现扰动,它后面的计算中误差将不会增大或者是衰减的。
在实践中,当我们选择计算方法时要选择稳定的算法,否则结果将出现严重的失真。
误差传播与算法稳定性试验报告
《数值计算方法》
专业班级
姓 名
学 号 08083117
时 间 2010年10月20日星期三
一. 实验目的
体会稳定性在选择算法中的地位,误差扩张的算法是不稳定的,是
我们所不期望的;误差衰减的算法是稳定的,是我们努力寻求的,这是贯穿本课程的目标。
二. 问题的提出
考虑一个简单的由积分定义的序列
I n =⎰x n e n -1dx , n =1, 2, ⋯
x -1
=1时,I 1=⎰0x e dx =1/e 。当n ≥2时,利
1
1
显然 I n >0, n =1, 2, ⋯当n
用部分积分易得
I n =⎰x e dx =x e
1
n -1
n x -11
n
x -1
-⎰nx n -1e x -1dx =1-nI n -1, n =2, 3⋯,
10
1
另一方面,有I n =
⎰
x e
dx ≤⎰x n dx =1/(n +1)
三. 试验内容
依次用一下两种迭代方法计算指定范围内的序列值。 (Ⅰ) 、I 1
(Ⅱ) 、I N
=1/e , I n =1-nI n -1, n =2, 3⋯,
=0, I n -1
1-I n
=, n =N , N -1, N -2,. ⋯, 3, 2
n
四. 主程序流程
五. 源程序
#include
#include
//根据初始值origin 按照递推公式I(n)=1-nI(n-1) //计算各项的值, 并输出 //1/e=0.3678794412
void funcOne(double origin) {
int i,n=0;//迭代次数, 及下标号 char oper;//操作符号
double value;
value=origin; while (1) { for (i=0;i=-10e6&&value
return; }
//根据参数n 确定初值I(n)=0 //计算n-1、n-2...0的值 void funcTwo(int n) {
int i; //循环变量 char oper; //操作符 double value=0; //初始值为0 while (1) { for (i=1;i1) value=(1-value)/n; else return; //如果n 为0可以直接返回 n--; //个数减一 } printf("\tq停止迭代或按其他任意键继续:");
oper=getch(); printf("\n"); if (oper=='q'||oper=='Q') break; //如果放弃了, 则退出迭代 } }
//测试第一个迭代函数 void testFunOne() {
printf("\n\t*******初值是5位有效数字******\n"); funcOne(0.36788);
printf("\n\t*******初值是6位有效数字*******\n"); funcOne(0.367879);
printf("\n\t*******初值是7位有效数字*******\n"); funcOne(0.3678794); }
//测试第二个迭代函数 void testFunTwo() {
int originN; //N的初始值
printf("\n\t输入N 的值(I(N)=0):"); scanf("%d",&originN);
if(originN
void main() {
char sel; //选项 while(1) { printf("\n\t选择迭代公式:"); printf("\n\t1.迭代公式:I(n)=1-n*I(n-1)"); printf("\n\t2.迭代公式:I(n-1)=(1-I(n))/n\n\t"); sel=getch(); if (sel=='1')testFunOne(); else testFunTwo(); printf("\n\t按任一键继续:"); getch(); } }
六. 程序运行结果
1、第一种迭代方式
(1)、五位有效数字:
程序运行,选择要测试的函数,选择第一个:
程序在迭代的过程中每次输出6项的值,如上图所示,初值I(1)=0.36788,可以看到,到此就已经存在误差较大的值,因为我们研究的积分序列一定满足0
从以上的各项中更可以看出,I(n)的迭代值已经出现严重的扭曲,简而言之,由于初值I(1)的误差,使得按它计算的其他项的误差是放大的,下面给出初值是六位的迭代过程。 (2)、六位有效数字:
尽管6位有效数字比5位的精确,但是计算的各项仍然出现严重的扭曲,出现误差放大。下面给出有效数字是7位的结果。 (3)、七位有效数字:
由此可以得出和六位有效数字时一样的结论,虽然7位有效数字较5位或6位的
要精确,但是结果中仍然有误差放大现象,结果出现严重失真。 (4)、迭代方式一的结论: 综合上面的(1)、(2)、(3)三点可知方式一的递推形式是不稳定的。
2、第二种迭代方式
运行结果如下图所示,给出N 的值,从N 开始计算N-1,N-2,…,1 各项的值,每次计算输出10项,按退出输出。 这里我输入
N=200
下面截取其中的一部分结果, 130-101项的。
70-51项的值:
最后给出20-1的值:
可以看出计算I(1)的结果与精确值=0.3678794相当,为了保证结论的可靠性,可以输入其他的N 值来估计I(1)的值。总之,算法二的递推形式是稳定的。
七. 结论与分析
(1)、分别用算法(Ⅰ) ,(Ⅱ) 计算,在计算中分别采用5位,6位,7位有效数字,
结果已经在上面的程序结果中给出。有结果我们知道算法(Ⅰ) 是不稳定的算法,而算法(Ⅱ) 是稳定的。 (2)、比较两种算法的优劣,从理论上推导结果。
对算法(Ⅰ) 中:
I 1的计算误差为e 1,由I 1递推计算I n 的误差是e n 中的I N 的计算误差为εN
=I n -I n
^
;算法(Ⅱ)
=I N -I N
^
,有I N 向前递推计算I n (n
N ) 的误
差为εn ,如果在上述两种算法中都假定后面的计算不再引入其他的误差,下面给出e n 与e 1的关系和εn 与εN 的关系。
I n =1-nI n -1, n =2, 3⋯
^
设I n 的准确值为I n ,
则有 I n
^
=1-n I n -1, n =2, 3⋯
^
^
将上面两式想减可得:
|I n -I n |=n |I n -1-I n -1|
^
也即,e n 从而,e n
=ne n -1, n =2, 3,....
=ne n -1=... =n ! e 1, n =2, 3,....
由此结论可知,当初始值I 1产生的误差e 1会经过迭代之后不断的放
大,最终估计的值将失真,即误差e 1对后面的影响是扩张的。因此算
法(Ⅰ) 是不稳定的算法。
对算法(Ⅱ) 有,
I N =0, I n -1
1-I n =, n =N , N -1, N -2,. ⋯, 3, 2
n
^
设I n 的准确值为I n ,
1-I n
, n =N , N -1, ⋯2 则有, I n -1=n
^
^
将以上两式相减可得,
εn -1=
εn
n
, n =N , N -1,...., 2
εN
N (N -1) ⋯(n +1)
,n =N -1, N -2, ⋯, 1
从而可知,εn =
有这个公司可以看出,当给出初值
I N
时,由于存在误差
εN =I N -I N
^
,当向前递推时,误差会逐级缩小,而且当N 较大是往后
^
的误差将趋向于0,误差不会放大,误差εN 衰减的,故此算法是稳定的。
=I N -I N
对后面的影响是
八. 收获与感想
这次试验通过一个积分式所对应的两种递推计算方法,从具体的数
据出发,深刻的感受了初始值的扰动对后面的计算值的影响,对于不稳定的算法,当初始值出现较小的扰动时,后面的值的误差将出现扩张,而对于稳定的算法,即使初值出现扰动,它后面的计算中误差将不会增大或者是衰减的。
在实践中,当我们选择计算方法时要选择稳定的算法,否则结果将出现严重的失真。