收藏 分销(赏)

北航数值分析第一次大作业.doc

上传人:xrp****65 文档编号:6909320 上传时间:2024-12-23 格式:DOC 页数:11 大小:168.50KB
下载 相关 举报
北航数值分析第一次大作业.doc_第1页
第1页 / 共11页
北航数值分析第一次大作业.doc_第2页
第2页 / 共11页
点击查看更多>>
资源描述
一、算法的设计方案: (一)各所求值得计算方法 1、最大特征值λ501,最小特征值λ1,按模最小特征值λs的计算方法 首先使用一次幂法运算可以得到矩阵的按模最大的特征值λ,λ必为矩阵A的最大或最小特征值,先不做判断。对原矩阵A进行一次移项,即(A-λI),在进行一次幂法运算,可以得到另一个按模最大特征值λ0。比较λ和λ0的大小,较大的即为λ501,较小的即为λ1。 对矩阵A进行一次反幂法运算,即可得到按模最小特征值λs。 2、A与μk值最接近的特征值λik的计算方法 首先计算出k所对应的μk值,对原矩阵A进行一次移项,即(A-μkI),得到一个新的矩阵,对新矩阵进行一次反幂法运算,即可得到一个按模最小特征值λi。则原矩阵A与μk值最接近的特征值 λik=λi+μk。 3、A的(谱范数)条件数cond(A)2的计算方法 其中矩阵A的按模最大和按模最小特征值。 (二)程序编写思路。 由于算法要求A的零元素不存储,矩阵A本身为带状矩阵,所以本题的赋值,LU分解,反幂法运算过程中,均应采用Doolittle分解法求解带状线性方程组的算法思路。 幂法、反幂法和LU分解均是多次使用,应编写子程序进行反复调用。 二、源程序: #include<stdio.h> #include<iostream> #include<stdlib.h> #include<math.h> #include<float.h> #include<iomanip> /*头文件*/ /*定义全局变量*/ #define N 502 /*取N为502,可实现从1到501的存储,省去角标变换的麻烦*/ #define epsilon 1.0e-12 /*定义精度*/ #define r 2 /*r,s为带状矩阵的半带宽,本题所给矩阵二者都是2*/ #define s 2 double c[6][N]; /*定义矩阵存储压缩后的带状矩阵*/ double fuzhi(); /*赋值函数*/ void LUfenjie(); /*LU分解程序*/ int max(int a,int b); /*求两个数字中较大值*/ int min(int a,int b); /*求两个数字中较小值*/ double mifa(); /*幂法计算程序*/ double fanmifa(); /*反幂法计算程序*/ double fuzhi() /*赋值程序,按行赋值,行从1到5,列从1到501,存储空间 的第一行第一列不使用,角标可以与矩阵一一对应,方便书写程序*/ { int i,j; i=1; for(j=3;j<N;j++) {c[i][j]=-0.064;} i=2; for(j=2;j<N;j++) {c[i][j]=0.16;} i=3; for(j=1;j<N;j++) {c[i][j]=(1.64-0.024*j)*sin(0.2*j)-0.64*exp(0.1/j);} i=4; for(j=1;j<N-1;j++) {c[i][j]=0.16;} i=5; for(j=1;j<N-2;j++) {c[i][j]=-0.064;} return(c[i][j]); } int max(int a,int b) { return((a>b)?a:b); } int min(int a,int b) { return((a<b)?a:b); } void LUfenjie() /*LU分解程序,采用的是带状矩阵压缩存储后的LU分解法*/ { double temp; int i,j,k,t; for(k=1;k<N;k++) { for(j=k;j<=min(k+s,N-1);j++) { temp=0; for(t=max(1,max(k-r,j-s));t<=(k-1);t++) {temp=temp+c[k-t+s+1][t]*c[t-j+s+1][j];} c[k-j+s+1][j]=c[k-j+s+1][j]-temp; } for(i=k+1;i<=min(k+r,N-1);i++) { temp=0; for(t=max(1,max(i-r,k-s));t<=(k-1);t++) {temp=temp+c[i-t+s+1][t]*c[t-k+s+1][k];} c[i-k+s+1][k]=(c[i-k+s+1][k]-temp)/c[s+1][k]; } } } double mifa() /*幂法计算程序*/ { double u0[N],u1[N]; double temp,Lu,beta=0,beta0; int i,j; for(i=1;i<N;i++) /*选取迭代初始向量*/ {u0[i]=1;} do { beta0=beta; temp=0; for(i=1;i<N;i++) {temp=temp+u0[i]*u0[i]; } Lu=sqrt(temp); for(i=1;i<N;i++) { u1[i]=u0[i]/Lu; } for(i=1;i<N;i++) { temp=0; for(j=max(i-1,1);j<=min(i+2,N-1);j++) {temp=temp+c[i-j+s+1][j]*u1[j]; } u0[i]=temp; } temp=0; for(i=1;i<N;i++) {temp=temp+u1[i]*u0[i]; } beta=temp; }while(fabs(beta-beta0)/fabs(beta)>=epsilon); /*迭代运行条件判断*/ return(beta); } double fanmifa() /*反幂法计算程序*/ { double u0[N],u1[N],u2[N]; double temp,Lu,beta=0,beta0; int i,t; for(i=1;i<N;i++) /*选取迭代初始向量*/ {u0[i]=1;} do { beta0=beta; temp=0; for(i=1;i<N;i++) {temp=temp+u0[i]*u0[i]; } Lu=sqrt(temp); for(i=1;i<N;i++) { u1[i]=u0[i]/Lu; u2[i]=u1[i]; } fuzhi(); LUfenjie(); /*带状矩阵压缩存储并进行LU分解后,求解线性方程组得到迭代向量uk,即程序中的u0*/ for(i=2;i<N;i++) { temp=0; for(t=max(1,i-r);t<=(i-1);t++) {temp=temp+c[i-t+s+1][t]*u2[t];} u2[i]=u2[i]-temp; } u0[N-1]=u2[N-1]/c[s+1][N-1]; for(i=N-2;i>=1;i--) { temp=0; for(t=i+1;t<=min(i+s,N-1);t++) {temp=temp+c[i-t+s+1][t]*u0[t];} u0[i]=(u2[i]-temp)/c[s+1][i]; } temp=0; for(i=1;i<N;i++) {temp=temp+u1[i]*u0[i]; } beta=temp; beta=1/beta; /*beta即为所求特征值,可直接返回*/ }while(fabs(beta-beta0)/fabs(beta)>=epsilon); /*迭代运行条件判断*/ return(beta); } void main() { double u[40]; /*定义数组,存放k值运算得到的μk值*/ double lambda1,lambda501,lambdak,a,b,d,cond,det; int i,j,k; fuzhi(); a=mifa(); /*幂法计算按模最大值*/ fuzhi(); d=fanmifa(); /*反幂法计算按模最小值*/ fuzhi(); for(j=1;j<N;j++) { c[3][j]=c[3][j]-a; } b=mifa()+a; /*移项后幂法计算按模最大值*/ if(a>b) /*比较两个按模最大值大小,并相应输出最大特征值λ501和最小特征值λ1*/ { lambda1=b; lambda501=a; printf("矩阵A最小的特征值lambda1=%13.11e\n",lambda1); printf("矩阵A最大的特征值lambda501=%13.11e\n",lambda501); } else { lambda1=a; lambda501=b; printf("矩阵A最小的特征值lambda1=%13.11e\n",lambda1); printf("矩阵A最大的特征值lambda501=%13.11e\n",lambda501); } printf("矩阵A按模最小特征值lambdas=%13.11e\n",d); /*输出按模最小特征值λs*/ for(k=1;k<40;k++) /*对每一个进行移项反幂法运算,求出最接近μk的特征值并输出*/ { u[k]=(lambda501-lambda1)*k/40+lambda1; fuzhi(); for(j=1;j<N;j++) {c[3][j]=c[3][j]-u[k]; } lambdak=fanmifa()+u[k]; i=k; printf("矩阵A最接近uk特征值lambdak%d=%13.11e\n",i,lambdak); } cond=fabs(a/d); printf("A的条件数=%13.11e\n",cond); /*计算A条件数并输出*/ fuzhi(); /*计算A的行列式值并输出*/ LUfenjie(); det=1; for(i=1;i<N;i++) { det=det*c[3][i]; } printf("行列式的值detA=%13.11e\n",det); } 三、程序的运行结果: 四、初始向量的选取对计算结果的影响: (一)选取形式不变,数值变换 1、取u0为[0.5,0.5………..0.5],运行结果如下: 2、取u0为[50,50………..50],运行结果如下: 从运行结果来看,此类初始向量的选取对结果不会产生影响,即使选成0,结果也不变化。 (二)改变选取形式 取u0为[1,0………..0],运行结果如下: 可以看出,改变初始向量的类型之后,运行结果出现了明显的变化,说明迭代初始向量的选取对迭代运算的结果是有影响的。为了观察初始向量与运行结果之间的联系,下面以幂法为例进行试验。 1、取u0为[1,0………..0],运行幂法程序,运行结果为: 对特征值对应的特征向量uk进行输出,找出数据中最接近1的数据,在数组第22个位置,且第1位周围的数值与1比较接近。其他位置的数值对比1均为小量。如下图: 2、取u0为[0……1…..0],运行幂法程序,1位于第200个位置运行结果为: 对特征值对应的特征向量uk进行输出,找出数据中最接近1的数据,在数组第198个位置,且第200位周围的数值与1比较接近。其他位置的数值对比1均为小量。如下图: 3、取u0为[0……1…..0],运行幂法程序,1位于第300个位置运行结果为: 对特征值对应的特征向量uk进行输出,找出数据中最接近1的数据,在数组第288个位置,且第300位周围的数值与1比较接近。其他位置的数值对比1均为小量。如下图: 4、取u0为[0……1…..0],运行幂法程序,1位于第400个位置运行结果为: 对特征值对应的特征向量uk进行输出,找出数据中最接近1的数据,在数组第413个位置,且第400位周围的数值与1比较接近。其他位置的数值对比1均为小量。如下图: 5、取u0为[0……1…..0],运行幂法程序,1位于第500个位置运行结果为: 对特征值对应的特征向量uk进行输出,找出数据中最接近1的数据,在数组第477个位置,且第500位周围的数值与1比较接近。其他位置的数值对比1均为小量。如下图: 综上可以看出,迭代初始向量的选取对迭代结果有明显的影响。输出的最终迭代向量(即矩阵计算出特征值所对应的特征向量)与所选的迭代初始向量形式上很接近。因此可以总结如下: 当所选取的迭代初始向量与矩阵的特征向量uk最为接近时,那么,幂法迭代计算结果输出的应该就是特征向量uk对应所对应的特征值。 以上试验只是考虑了初始向量u0为[0……1…..0]的情况,如果已知一个矩阵的特征向量,那么以其中任一特征向量uk为迭代初始向量,进行幂法运算,输出结果必为特征向量uk对应的特征值λk,而不一定是按模最大特征值。例如:矩阵 A= 的特征值分别为-1,2,5,三者对应的特征向量分别为(-2,-2,-1)T,(-2,1,2)T,(1,-2,2)T,如果以(-2,-2,-1)T为初始迭代向量进行幂法运算,得到的按模最大特征值为-1,而不是5. 同理,在反幂法运算中也可以得到相同的结论。
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传
相似文档                                   自信AI助手自信AI助手

当前位置:首页 > 百科休闲 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服