中
中
南
南
林
林
业
业
科
科
技
技
大
大
学
学
电
电
子
子
与
与
信
信
息
息
工
工
程
程
学
学
院
院
《数值分析》
实
实
验
验
指
指
导
导
书
书
陈爱斌 编
计算机教研室
2006年2月
目 录
前 言................................................... 1
实验一 函数插值方法...................................... 2
实验二 函数逼近与曲线拟合................................ 3
实验三 数值积分与数值微分................................ 4
实验四 线方程组的直接解法................................ 5
实验五 解线性方程组的迭代法.............................. 7
实验六 非线性方程求根.................................... 8
实验七 矩阵特征值问题计算................................ 9
实验八 常微分方程初值问题数值解法....................... 11
附录一:实验报告内容要求................................ 12
附录二:部分程序示例.................................... 13
1、〖多项式系列程序〗................................. 13
2、〖最小二乘法曲线拟合程序〗......................... 15
3、〖Romberg算法计算数值积分程序〗................... 18
4、〖线方程组的直接解法系列程序〗..................... 19
5、〖Jacobi迭代法解线性方程组程序〗.................. 24
6、〖牛顿法非线性方程求根程序〗....................... 25
7、〖幂法求矩阵特征值程序〗........................... 26
8、〖四阶经典的龙格-库塔方法解常微分方程程序〗........ 27
数值分析实验指导书
1
前 言
第1页
结合课程教学,配备适当的上机实验(16个学时)以便加深课堂
教学的实践性,同时通过实验可以加强对数学模型的总体分析,算法
选取,程序结构,上机调试和结果分析等环节的训练。本实验指导书
共包含8个实验,要求学生在16个实验课时内完成。为使实验更为
有成效,需要写出实验报告(格式要求见附录),以此可作为《数值分
析》课程成绩评定的参考。
数值分析实验指导书
2
实验一 函数插值方法
一、问题提出
对于给定的一元函数 ( )xfy = 的n+1个节点值 ( )
jj
xf y = 。
试用Lagrange公式求其插值多项式或分段二次Lagrange插值多项式。
()nj ,,1,0L=
数据如下:
(1)
j
x
0.4 0.55 0.65 0.80 0.95 1.05
j
y
0.41075 0.57815 0.69675 0.90 1.00 1.25382
求五次Lagrange多项式L,和分段三次插值多项式,计算()x
5
( )(99.0,596.0 ff ) 的
值。(提示:结果为 ()≈596.0f 0.625732 ( )≈99.0f 1.05423 )
(2)
j
x
1 2 3 4 5 6 7
j
y
0.368 0.135 0.050 0.018 0.007 0.002 0.001
试构造Lagrange多项式L
6
,计算( )8.1f的值。 ( )x
结果()≈8.1f 0.164762 ( )≈15.6f 0.001266
二、要求
1、 利用Lagrange插值公式
()
k
n
ki
i ik
i
n
k
n
y
xx
xx
xL
?
?
?
?
?
?
?
?
?
?
?
?
∑=
∏
≠
=
=
0
0
编写出插值多项式程序;
2、 给出插值多项式或分段三次插值多项式的表达式;
3、 根据节点选取原则,对问题(2)用三点插值或二点插值,其结果如何;
4、 对此插值问题用Newton插值多项式其结果如何。Newton插值多项式如下:
()
∏
?
≠
=
=
??∑+=
1
0
0
1
0
)(],[)(
k
kj
j
jk
n
k
n
xxxxfxfxNL
其中:
∏
≠
=
=
?
∑=
k
ij
j
ji
i
k
i
k
xx
xf
xxf
0
0
0
)(
)(
],,[L
三、目的和意义
1、 学会常用的插值方法,求函数的近似表达式,以解决其它实际问题;
2、 明确插值多项式和分段插值多项式各自的优缺点;
3、 熟悉插值方法的程序编制;
第2页
4、 如果绘出插值函数的曲线,观察其光滑性。
数值分析实验指导书
3
实验二 函数逼近与曲线拟合
一、问题提出
从随机的数据中找出其规律性,给出其近似表达式的问题,在生产实践和科学实验
中大量存在,通常利用数据的最小二乘法求得拟合曲线。
在某冶炼过程中,根据统计数据的含碳量与时间关系,试求含碳量与时间t的拟
合曲线。
y
二、要求
1、用最小二乘法进行曲线拟合;
2、近似解析表达式为; ()
3
3
2
21
tatatat ++=?
3、打印出拟合函数()t?,并打印出( )
j
t?与( )
j
ty的误差,12,,2,1L=j;
4、另外选取一个近似表达式,尝试拟合效果的比较;
5、* 绘制出曲线拟合图。
三、目的和意义
1、掌握曲线拟合的最小二乘法;
2、最小二乘法亦可用于解超定线代数方程组;
3、探索拟合函数的选择与拟合精度间的关系
第3页
(t分)
0 5 10 15 20 25 30 35 40 45 50 55
( )
4
10
?
×y
0 1.27 2.16 2.86 3.44 3.87 4.15 4.37 4.51 4.58 4.02 4.64
数值分析实验指导书
4
实验三 数值积分与数值微分
一、问题提出
选用复合梯形公式,复合Simpson公式,Romberg算法,计算
(1) I = dxx
∫
?
4
1
0
2
sin4 ( )5343916.1≈I
(2) I = dx
x
x
∫
1
0
sin
()9460831.0,1)0( ≈= I f
(3) I = dx
x
e
x
∫
+
1
0
2
4
(4) I =
()
dx
x
x
∫
+
+
1
0
2
1
1ln
二、要求
1、 编制数值积分算法的程序;
2、 分别用两种算法计算同一个积分,并比较其结果;
3、 分别取不同步长( / ab h )?= n,试比较计算结果(如n = 10, 20等);
4、 给定精度要求ε,试用变步长算法,确定最佳步长。
三、目的和意义
1、 深刻认识数值积分法的意义;
2、 明确数值积分精度与步长的关系;
第4页
3、 根据定积分的计算方法,可以考虑二重积分的计算问题。
数值分析实验指导书
5
实验四 线方程组的直接解法
一、问题提出
给出下列几个不同类型的线性方程组,请用适当算法计算其解。
1、设线性方程组
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?????
?
???
??
??
???
???
???
??
??
13682438100
412029137264
221234179111016
1035243120
53621775868
3233761624
4911315120
1301231224
0010563568
0000121324
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
10
9
8
7
6
5
4
3
2
1
x
x
x
x
x
x
x
x
x
x
=
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
? 21
19
38
13
46
3
2
3
12
5
x = ( 1, -1, 0, 1, 2, 0, 3, 1, -1, 2 )
T
*
2、设对称正定阵系数阵线方程组
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
??
??
???
????
????
????
??
?
192433600
2141103520
411144334
3104221812
33416120
653811414
02312122
00420424
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
8
7
6
5
4
3
2
1
x
x
x
x
x
x
x
x
=
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
45
15
22
9
23
20
6
0
x = ( 1, -1, 0, 2, 1, -1, 0, 2 )
T
*
第5页
数值分析实验指导书
6
3、三对角形线性方程组
=
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
??
??
??
??
??
??
??
??
?
4100000000
1410000000
0141000000
0014100000
0001410000
0000141000
0000014100
0000001410
0000000141
0000000014
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
10
9
8
7
6
5
4
3
2
1
x
x
x
x
x
x
x
x
x
x
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
5
5
4
14
12
6
2
13
5
7
x = ( 2, 1, -3, 0, 1, -2, 3, 0, 1, -1 )
T
*
二、要求
1、 对上述三个方程组分别利用Gauss顺序消去法与Gauss列主元消去法;平方根法与
改进平方根法;追赶法求解(选择其一);
2、 应用结构程序设计编出通用程序;
3、 比较计算结果,分析数值解误差的原因;
4、 尽可能利用相应模块输出系数矩阵的三角分解式。
三、目的和意义
1、通过该课题的实验,体会模块化结构程序设计方法的优点;
2、运用所学的计算方法,解决各类线性方程组的直接算法;
3、提高分析和解决问题的能力,做到学以致用;
第6页
4、通过三对角形线性方程组的解法,体会稀疏线性方程组解法的特点。
数值分析实验指导书
7
实验五 解线性方程组的迭代法
一、问题提出
对实验四所列目的和意义的线性方程组,试分别选用Jacobi 迭代法,Gauss-Seidol
迭代法和SOR方法计算其解。
二、要求
1、体会迭代法求解线性方程组,并能与消去法做以比较;
2、分别对不同精度要求,如由迭代次数体会该迭代法的收敛快慢;
543
10,10,10
???
=ε
3、对方程组2,3使用SOR方法时,选取松弛因子ω =0.8,0.9,1,1.1,1.2等,试
看对算法收敛性的影响,并能找出你所选用的松弛因子的最佳者;
4、给出各种算法的设计程序和计算结果。
三、目的和意义
1、通过上机计算体会迭代法求解线性方程组的特点,并能和消去法比较;
2、运用所学的迭代法算法,解决各类线性方程组,编出算法程序;
3、体会上机计算时,终止步骤
∞
+
?
)()1( kk
xx < ε 或k >(予给的迭代次数),对迭
代法敛散性的意义;
第7页
4、体会初始解 x
(
,松弛因子的选取,对计算结果的影响。
)0
数值分析实验指导书
8
实验六 非线性方程求根
设方程f(x)=x - 3x –1=0 有三个实根 x
*
1
=1.8793 , x
*
=-0.34727 ,x =-1.53209
现采用下面六种不同计算格式,求 f(x)=0的根 x
*
1
或x
*
2
3
2
*
3
一、问题提出
1、 x =
2
13
x
x +
2、 x =
3
1
3
?x
3、 x =
3
13 +x
4、 x =
3
1
2
?x
5、 x =
x
1
3+
6、 x = x - ( )
1
13
3
1
2
3
?
??
x
xx
二、要求
1、编制一个程序进行运算,最后打印出每种迭代格式的敛散情况;
2、用事后误差估计
kk
xx ?
+1
? ε来控制迭代次数,并且打印出迭代的次数;
3、初始值的选取对迭代收敛有何影响;
4、分析迭代收敛和发散的原因。
三、目的和意义
1、通过实验进一步了解方程求根的算法;
2、认识选择计算格式的重要性;
3、掌握迭代算法和精度控制;
第8页
4、明确迭代收敛性与初值选取的关系。
数值分析实验指导书
9
实验七 矩阵特征值问题计算
一、问题提出
利用冪法或反冪法,求方阵A=(a )
n
的按模最大或按模最小特征值及其对应的特
征向量。
ij n×
设矩阵A的特征分布为:
nn
λλλλλ ≥≥≥?
?1321
L 且Ax =
j jj
xλ
试求下列矩阵之一
(1) A= 求
?
?
?
?
?
?
?
?
?
?
?
?
?
611
142
121
1
λ,及x
1
()
取= ( 1, 1, 1 ) ,
0
υ
T
ε = 10
5?
结果 λ
1
≈ -6.42106, x
1
≈ ( -0.046152, -0.374908, 1 )
T
(2) A= 求
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
??
421578
235341
156213
532717
741152
813724
1
λ ,
6
λ 及 x
1
()
取
0
υ
T
)1,0,0,1,0,1(≈
5
10
?
=ε
结果:
( )
T
16
1.0 0.4972, 0.5644, 0.9973, 0.5401, 0.8724, x 1.62139 ≈≈≈ λλ 30525.21
1
(3) A=
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
??
??
??
?
21
121
121
121
12
求
1
λ
及
x1
取
( )0
υ
=( 1, 1, 1, 1, 1 )
T
4
10
?
=ε
结果≈λ 3.7321
第9页
数值分析实验指导书
10
(4) A=
?
?
?
?
?
?
?
?
?
?
?
?
??
?
?
1254
2613
5131
4312
取
( )0
υ
=( 1, 1, 1, 1 )
T 2
10
?
=ε
这是一个收敛很慢的例子,迭代1200次才达到10
5?
结果
1
λ ≈ -8.02857835 x
1
T
)564212.2,757730.0,501460.2,1( ??≈
(5) A=
?
?
?
?
?
?
?
?
?
?
?
?
?
611
142
121
有一个近似特征值 –6.42,试用反冪法求对应的特征向量,并改进特征值(原点
平移法)。
取
()0
υ
= ( 1, 1, 1 )
T
4
10
?
=ε
结果 ≈λ -6.42107 x
T
)1,37918.0,0461465.0( ??≈
二、要求
1、掌握冪法或反冪法求矩阵部分特征值的算法与程序设计;
2、会用原点平移法改进算法,加速收敛;对矩阵B=A-PI取不同的P值,试求其效
果;
3、试取不同的初始向量,观察对结果的影响;
()0
υ
4、对矩阵特征值的其它分布,如
21
λλ = 且
321
λλλ ≥=如何计算。
三、目的和意义
1、求矩阵的部分特征值问题具有重要实际意义,如求矩阵谱半径()Aρ =max
1
λ,
稳定性问题往往归于求矩阵按模最小特征值;
2、进一步掌握冪法、反冪法及原点平移加速法的程序设计技巧;
第10页
3、问题中的题(5),反应了利用原点平移的反冪法可求矩阵的任何特征值及其特征
向量。
数值分析实验指导书
11
实验八 常微分方程初值问题数值解法
一、问题提出
科学计算中经常遇到微分方程(组)初值问题,需要利用Euler法,改进Euler
法,Rung-Kutta方法求其数值解,诸如以下问题:
(1)
()
?
?
?
?
=
?=′
0 y
xy
y
x
y
0
4
?
0 < x≤2
分别取h=0.1,0.2,0.4时数值解。
初值问题的精确解
2
54
x
ey
?
+=。
(2)用r=3的Adams显式和预 - 校式求解
()
?
?
?
?
? ?=′
=?
22
01
yxy
y
01 ≤≤? x
取步长h=0.1,用四阶标准R-K方法求值。
(3)用改进Euler法或四阶标准R-K方法求解
( )
()
()
?
?
?
?
?
=?=′
=?=′
?=′=′
10
33
00
12
10
121
3
y yy
2
y yy
y y y
10 ≤≤ x
取步长0.01,计算=h ( ) ( ) ( )15.0,10.0,05.0 y y y数值解,参考结果
() ( ) ( ) 8613125.015.0,9880787.015.0
1
≈,1493359.015.0
32
≈?≈ y y y
(4)利用四阶标准R- K方法求二阶方程初值问题的数值解
(I)
() ()
?
?
?
=′=
=+′?′′
10,00
023
yy
yyy
0.02h x =≤≤ 10
(II)
() ()
?
?
?
=′=
=+′??′′
00,10
0)1(1.0
2
y y
yyyy
0.1h x =≤≤ ,10
(III)
() ()
?
?
?
?
?
=′=
+
=′
00,10
1
yy
e
y
y
x
0.1h x =≤≤ ,20
(IV)
?
0
() ()
?
?
=′=
=+′′
00,10
0sin
yy
yy
2,4 0.h x =≤≤
二、要求
1、 根据初值问题数值算法,分别选择二个初值问题编程计算;
2、 试分别取不同步长,考察某节点处数值解的误差变化情况;
j
x
3、 试用不同算法求解某初值问题,结果有何异常;
4、 分析各个算法的优缺点。
三、目的和意义
1、 熟悉各种初值问题的算法,编出算法程序;
2、 明确各种算法的精度与所选步长有密切关系;
第11页
3、 通过计算更加了解各种算法的优越性。
数值分析实验指导书
12
附录一:实验报告内容要求
实验报告内容要求
一、课题名称
二、班级、姓名
三、目的和意义
方法的理论意义和实用价值,如解超越方程的弦截法,改进
了牛顿法,它适用于任意连续函数在大范围中求解,并且避免计
算导数值,使其更具有实用性。
四、计算公式
五、结构程序设计
六、结果讨论和分析
第12页
如初值对结果的影响;不同方法的比较;该方法的特点和改
进;整个实验过程中(包括程序编写,上机调试等)出现的问题
及其处理等广泛的问题,以此扩大知识面和对实验环节的认识。
数值分析实验指导书
13
附录二:部分程序示例
(本部分程序与本指导书配套而且均已采用Turbo C 2.0调试通过)
1、〖多项式系列程序〗
(1) Lagrange插值
第13页
#define N 5
float x[] = {0.4, 0.55, 0.65, 0.80, 0.95, 1.05};
float y[] = {0.41075, 0.57815, 0.69675, 0.90, 1.00, 1.25382};
float p(float xx)
{
int i,k;
float pp = 0, m1, m2;
for( i=0; i<=N; i++ )
{
m1 = 1; m2 = 1;
for( k=0; k<=N; k++ )
if( k != i ) {
m1 *= xx - x[k];
m2 *= x[i] - x[k]; }
pp += y[i] * m1/m2;
}
return pp;
}
main()
{
printf( "f(0.596)=%lf\n", p(0.596) );
printf( "f(0.99)=%lf\n", p(0.99) );
}
数值分析实验指导书
14
(2) 牛顿插值
第14页
#define N 6
float x[]={1,2,3,4,5,6,7};
float y[]={0.368,0.135,0.050,0.018,0.007,0.002,0.001};
float jc( int k ) /* 此函数实现求均差 f[x
0
,x
1
,...,x
k
] */
{
int i, j;
float s = 0, m;
for(i=0; i<=k; i++)
{
for(m=1,j=0; j<=k; j++)
if( j!=i ) m *= x[i]-x[j];
s += y[i] / m;
}
return s;
}
float newton( float X ) /* 此函数实现求牛顿插值函数N
n
(x) */
{
float nt=y[0], m;
int i, j;
for( i=1; i<=N; i++)
{
for( m=1,j=0; j<=i-1; j++)
m *= X-x[j];
nt += jc(i) * m;
}
return nt;
}
main()
{
float X=1.8;
printf("%lf",newton(X));
}
数值分析实验指导书
15
2、〖最小二乘法曲线拟合程序〗
第15页
/*曲线拟合*/
#include "stdio.h"
#include "math.h"
#define num 10
float neiji(float b[num],float c[num]) /*内积函数*/
{ int p;
float nj=0;
for (p=1;p<num;p++)
nj+=c[p]*b[p];
return nj;
}
float s[num],x[num],y[num],fai[num][num],afa[num];
float beida[num],a[num],xfai[num],yd[num],max,pcpfh;
void main()
{ int i,j,k,n,index,flag;
char conti;
conti=' ';
printf("请输入已知点的个数n=\n");
scanf("%d",&n);
printf("请输入x和y:");
for(i=1;i<=n;i++)
{ printf("x[%d]=",i);
scanf("%f",&x[i]);
printf("y[%d]=",i);
scanf("%f",&y[i]);
}
数值分析实验指导书
16
第16页
while(conti==' ')
{ printf("请输入拟和次数=");
scanf("%d",&index);
pcpfh=0;
afa[1]=0;
a[0]=0;
for(i=1;i<=n;i++)
{afa[1]+=x[i];
a[0]+=y[i];
fai[0][i]=1;
}
afa[1]=afa[1]/n;
a[0]=a[0]/n;
for (i=1;i<=n;i++)
{
fai[1][i]=x[i]-afa[1];
}
a[1]=neiji(fai[1],y)/neiji(fai[1],fai[1]);
for(k=1;k<index;k++)
{ for(i=1;i<=n;i++)
xfai[i]=x[i]*fai[k][i];
afa[k+1]=neiji(fai[k],xfai)/neiji(fai[k],fai[k]);
beida[k]=neiji(fai[k],fai[k])/neiji(fai[k-1],fai[k-1]);
for(j=1;j<=n;j++)
fai[k+1][j]=(x[j]-afa[k+1])*fai[k][j]-beida[k]*fai[k-1][j];
a[k+1]=neiji(fai[k+1],y)/neiji(fai[k+1],fai[k+1]);
}
printf("%d次拟和结果为\n",index);
for(i=0;i<=index;i++)
printf("a[%d]=%f\n",i,a[i]);
for(i=1;i<=index;i++)
printf("afa[%d]=%f\n",i,afa[i]);
for(i=1;i<index;i++)
printf("beida[%d]=%f\n",i,beida[i]);
数值分析实验指导书
17
第17页
< 接上页 >
for(i=1;i<=n;i++)
{ for(k=0;k<=index;k++)
s[i]+=a[k]*fai[k][i];
yd[i]=(float)(fabs(y[i]-s[i]));
pcpfh+=yd[i]*yd[i];
s[i]=0;
}
max=0;
for(i=1;i<=n;i++)
if(yd[i]>max)
{max=yd[i];
flag=i;
}
printf("当x=%f时,偏差最大=%f,偏差平方和为%f\n",x[flag],max,pcpfh);
printf("继续拟和请按space,按其他键退出");
conti=getchar();
conti=getchar();
}
}
数值分析实验指导书
18
3、〖Romberg算法计算数值积分程序〗
第18页
float f(float x)
{
return( exp( x ) / ( 4 + x*x ) );
}
main()
{
float a=0,b=1;
float h=b-a,T1,T2,s,x;
int i;
T1=h/2*(f(a)+f(b));
for(i=0;i<3;i++)
{ printf("h=%f,T=%f\n",h,T1);
s=0;
x=a+h/2;
while(x<b) {
s+=f(x);
x+=h; }
T2=T1/2+h/2*s;
h/=2;
T1=T2;
}
printf("h=%f,T=%f\n",h,T1);
return;
}
数值分析实验指导书
19
4、〖线方程组的直接解法系列程序〗
以下分别用Gauss消去法、平方根法、追赶法编程解线性方程组。这
几个程序中,数据文件格式分别如下:
8
4
2 2
-4 -1 14
0 -2 1 6
2 1 -8 -
4 3 -3 -
0 2 5 -
0 0 6 3
sqrt.dat
第19页
10
4 -1
-1 4
-1 4
-1 4
-1 4
-1 4
-1 4
-1 4
-1 4
-1 4
4 2 -3 -1 2 1 0 0 0 0 5
8 6 -5 -3 6 5 0 1 0 0 1
4 2 -2 -1 3 2 -1 0 3 1 3
0 -2 1 5 -1 3 -1 1 9 4 2
-4 2 6 -1 6 7 -3 3 2 3 3
8 6 -1 3 7 17 2 6 -3 5 4
0 2 -1 3 -4 2 5 3 0 1 1
16 10 -11 -9 17 34 2 -1 2 2
4 6 2 -7 13 9 2 0 12 4
0 0 -1 8 -3 -24 -8 6 3 -1 -
1 22
4 4 11
3 -10 1 14
-3 -4 2 19
zgf.dat
Gauss.dat
2
6
3
38
19
21
7
-1 5
-1 -13
-1 2
-1 6
-1 -12
-1 14
-1 -4
-1 5
-5
数值分析实验指导书
20
(1) Gauss消去法解线性方程组
第20页
#include "stdio.h"
main()
{
FILE *f;
double a[15][15];
double b[15],s;
int i,j,k,n;
f=fopen("Gauss.dat","r");
fscanf(f,"%d",&n);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
fscanf(f,"%lf",&a[i][j]);
fscanf(f,"%lf",&b[i]);
}
fclose(f);
k=1;
do
{
for (j=k+1;j<=n;j++) a[k][j]=a[k][j]/a[k][k];
b[k]=b[k]/a[k][k];
i=1;
for(i=k+1;i<=n;i++)
{
for (j=k+1;j<=n;j++) a[i][j]=a[i][j]-a[i][k]*a[k][j];
b[i]=b[i]-a[i][k]*b[k];
}
if(k==n) break;
k++;
}while(1);
for(i=n-1;i>=1;i--)
{ s=0;
for(j=i+1;j<=n;j++)
s=s+a[i][j]*b[j];
b[i]=b[i]-s;
}
for(i=1;i<=n;i++)
printf("b[%2d]=%lf\n",i,b[i]);
}
数值分析实验指导书
21
(2)平方根法求三角阵
第21页
/*************A=L*L
T
***************/
#include "stdio.h"
#include "math.h"
main()
{
FILE *f;
double a[15][15],l[15][15];
double s;
int i,j,k,n;
f=fopen("sqrt.dat","r");
fscanf(f,"%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
{
fscanf(f,"%lf",&a[i][j]);
}
fclose(f);
for(i=1;i<=n;i++)
{
for(j=1;j<=i-1;j++)
{
for(s=0,k=1;k<=j-1;k++) s+=l[i][k]*l[k][j];
l[i][j]=(a[i][j]-s)/l[j][j];
}
s=0;
for(s=0,k=1; k<=i-1; k++) s+=l[i][k]*l[i][k];
l[i][i]=sqrt(a[i][i]-s);
}
printf("\n=======================\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
printf("%lf ", l[i][j]);
printf("\n");
}
}
数值分析实验指导书
22
(3)改进的平方根法求解线性方程组
第22页
#include "stdio.h"
main()
{
FILE *f;
double a[15][15],b[15],d[15],l[15][15],x[15],y[15];
double s;
int i,j,k,n;
/******************************************************/
f=fopen("sqrt.dat","r");
fscanf(f,"%d",&n);
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++) fscanf(f,"%lf",&a[i][j]);
fscanf(f,"%lf",&b[i]);
}
fclose(f);
/*****************************************************/
for(i=1;i<=n;i++)
{
for(j=1;j<=i-1;j++)
{ for(s=0,k=1;k<=j-1;k++) s+=d[k]*l[i][k]*l[j][k];
l[i][j]=(a[i][j]-s)/d[j]; }
s=0;
for(s=0,k=1; k<=i-1; k++) s+=d[k]*l[i][k]*l[i][k];
d[i]=a[i][i]-s;
}
/***************************************************/
for(i=1;i<=n;i++)
{ for(s=0,k=1;k<=i-1;k++) s+=l[i][k]*y[k];
y[i]=b[i]-s; }
/****************************************************/
for(i=n;i>=1;i--)
{ for(s=0,k=i+1;k<=n;k++) s+=l[k][i]*x[k];
x[i]=y[i]/d[i]-s; }
/*****************************************************/
for(i=1;i<=n;i++)
printf("x[%d]=%lf\n",i,x[i]);
}
数值分析实验指导书
23
(4)追赶法求解线性方程组
第23页
#include "stdio.h"
main()
{
FILE *f;
double a[15],b[15],c[15],d[15];
double t;
int i,n;
/**********************************************/
f=fopen("zgf.dat","r");
fscanf(f,"%d",&n);
fscanf(f,"%lf%lf%lf",&b[1],&c[1],&d[1]);
for(i=2;i<=n-1;i++)
{
fscanf(f,"%lf%lf%lf%lf",&a[i],&b[i],&c[i],&d[i]);
}
fscanf(f,"%lf%lf%lf",&a[n],&b[n],&d[n]);
fclose(f);
/*********************************************/
c[1]=c[1]/b[1];
d[1]=d[1]/b[1];
for(i=2;i<=n-1;i++)
{
t=b[i]-c[i-1]*a[i];
c[i]=c[i]/t;
d[i]=(d[i]-d[i-1]*a[i])/t;
}
d[n]=(d[n]-d[n-1]*a[n])/(b[n]-c[n-1]*a[n]);
for(i=n-1;i>=1;i--) d[i]=d[i]-c[i]*d[i+1];
printf("\n********************************\n");
for(i=1;i<=n;i++)
printf("d[%2d]=%lf\n",i,d[i]);
}
数值分析实验指导书
24
5、〖Jacobi迭代法解线性方程组程序〗
第24页
#define M 3
#include "math.h"
main()
{
double a[M][M]={ {10,-1,-2},
{-1,10,-2},
{-1,-1, 5} };
double b[M] = { 7.2, 8.3, 4.2 };
double x[M] = {0,0,0},y[M];
double s, max, eps = 0.000000001;
int k, i, j, N = 100;
k = 1;
while( k<N )
{
for ( i=0; i<M ; i++ )
{ s = 0;
for ( j=0; j<M; j++ )
if( j-I ) s += a[i][j] * x[j];
y[i] = ( b[i]-s) / a[i][i];
}
max = 0;
for ( i=0; i<M; i++ )
if( max < fabs( x[i]-y[i] ) ) max = fabs( x[i] - y[i] );
if ( max < eps ) break;
printf( "\nk=%d, ", k );
for( i=0; i<M; i++ ) printf( "y[%d]=%lf ",i, y[i] );
k++;
for( i=0; i<M; i++ ) x[i] = y[i];
}
if(k == N) { printf( "ERROR!\n" ); return; }
printf( "\nk=%d, ", k );
for ( i=0; i < M; i++ ) printf( y[%d]=%lf ", i, y[ i ] );
}
数值分析实验指导书
25
6、〖牛顿法非线性方程求根程序〗
第25页
#include "math.h"
double f ( double x )
{
return( x - ( x - exp(-x) ) / (1+x) );
}
main()
{
double eps = 1e-10;
double x1, x2 = 0.5;
do{
x1 = x2;
x2 = f( x1 );
printf( "\nx=%20.16lf\n", x2 );
}while( fabs( x2 - x1 ) >= eps );
}
数值分析实验指导书
26
7、〖幂法求矩阵特征值程序〗
第26页
#include "math.h"
#define N 3
main()
{
double a[N][N]={ { - 1, 2, 1},{ 2, - 4, 1 },{ 1, 1, - 6 } };
double s, mu0, mu = -1000, v[N], u[N] = { 1,1,1 };
double eps = 1e-5;
int i, j;
do{
mu0 = mu;
for( i=0; i<N; i++ )
{ s = 0;
for( j=0; j<N; j++ ) s += a[i][j] * u[j];
v[i] = s;
}
mu = fabs( v[0] );
for( i=0; i<N; i++ )
if( mu< fabs( v[i] ) ) mu = fabs( v[i] );
for( i=0 ; i<N; i++ )
u[i] = v[i] / mu;
}while( fabs( mu-mu0 ) >= eps );
printf( "\nu=%lf\n[", mu ];
for( i=0; i<N; i++ ) printf( "%lf ", u[i] );
printf(") \n" );
}
数值分析实验指导书
27
8、〖四阶经典的龙格-库塔方法解常微分方程程序〗
第27页
float f(float x,float y)
{
return( 4*x / y – x*y );
}
main()
{
float x0=0,y0=0,x1,y1;
float h=0.1,k1,k2,k3,k4;
int n=1,N=5;
do
{
x1=x0+h;
k1=f(x0,y0);
k2=f(x0+h/2,y0+h/2*k1);
k3=f(x0+h/2,y0+h/2*k2);
k4=f(x1,y0+h*k3);
y1=y0+h/6*(k1+2*k2+2*k3+k4);
printf("n=%d,x1=%f,y1=%f\n",n,x1,y1);
n++;
x0=x1;y0=y1;
}while(n<N+1);
return;
}