收藏 分销(赏)

反幂法求矩阵特征值.docx

上传人:xrp****65 文档编号:6639067 上传时间:2024-12-18 格式:DOCX 页数:12 大小:321.55KB 下载积分:10 金币
下载 相关 举报
反幂法求矩阵特征值.docx_第1页
第1页 / 共12页
反幂法求矩阵特征值.docx_第2页
第2页 / 共12页


点击查看更多>>
资源描述
一. 问题描述 用幂法与反幂法求解矩阵特征值 求n阶方阵A的特征值和特征向量,是实际计算中常常碰到的问题,如:机械、结构或电磁振动中的固有值问题等。对于n阶矩阵A,若存在数和n维向量x满足 Ax=x (1) 则称为矩阵A的特征值,x为相应的特征向量。 由线性代数知识可知,特征值是代数方程 |I-A|=+a+…+a+a=0 (2) 的根。从表面上看,矩阵特征值与特征向量的求解问题似乎很简单,只需求解方程(2)的根,就能得到特征值,再解齐次方程组 (I-A)x=0 (3) 的解,就可得到相应的特征向量。 上述方法对于n很小时是可以的。但当n稍大时,计算工作量将以惊人的速度增大,并且由于计算带有误差,方程(2)未必是精确的特征方程,自然就不必说求解方程(2)与(3)的困难了。幂法与反幂法是一种计算矩阵主特征值及对应特征向量的迭代方法, 特别是用于大型稀疏矩阵。 这里用幂法与反幂法求解带状稀疏矩阵A[501][501]的特征值。 二. 算法设计 1. 幂法 (1)取初始向量u(例如取u=(1,1,…1)),置精度要求,置k=1. (2)计算 v=Au, m=max(v), u= v/ m (3)若| m-m|<,则停止计算(m作为绝对值最大特征值,u作为相应的特征向量)否则置k=k+1,转(2) 2. 反幂法 (1)取初始向量u(例如取u=(1,1,…1)),置精度要求,置k=1. (2)对A作LU分解,即A=LU (3)解线性方程组 Ly=u,Uv=y (4)计算 m=max(v), u= v/ m (5)若|m-m|<,则停止计算(1/m作为绝对值最小特征值,u作为相应的特征向量);否则置k=k+1,转(3). 三. 程序框图 1. 主程序 开始 设置二维数组Q[5][501]存放矩阵A的带内元素 平移求最大特征值和最小特征值 结束 fanmifa(A)反幂法求按模最小特征值 mifa(A)幂法求按模最大特征值 计算u[1]到u[39] 2. 子程序 (1). 幂法迭代程序框图 开始 计算幂法初始向量 fabs(b-c)/fabs(b)<=1e-12? Return(b)并 printf("幂法成功!") 返回 > b=sgn(h)*u[l]; 找到Max(fabs(u[i])) 迭代求u[i]=u[i]+A[i-j+2][j]*y[j]; y[i]=u[i]/fabs(h); c=b; (2). 反幂法迭代程序框图 开始 计算反幂法初始向量 Return(1/b)并 printf("反幂法成功") 返回 > LU分解前保存A[i][j]和y[i]的值 c=b; LU分解 fabs(b-c)/fabs(b)<=1e-12? 解线性方程组求出u[i] 迭代求b=b+y[i]*u[i]; 四. 结果显示 计算结果如下: 矩阵的按模最大特征值为:-1.070011361487e+001 矩阵的按模最小特征值为:-5.557910794230e-003 矩阵最大的特征值为:9.724634101479e+000 矩阵最小的特征值为:-1.070011361487e+001 与各 最接近的(用表示)的值如下: v[ 1]=-1.018293403315e+001 u[ 1]=-1.018949492196e+001 v[ 2]=-9.585707425068e+000 u[ 2]=-9.678876229054e+000 v[ 3]=-9.172672423928e+000 u[ 3]=-9.168257536145e+000 v[ 4]=-8.652284007898e+000 u[ 4]=-8.657638843237e+000 v[ 5]=-8.093483808675e+000 u[ 5]=-8.147020150328e+000 v[ 6]=-7.659405407692e+000 u[ 6]=-7.636401457419e+000 v[ 7]=-7.119684648691e+000 u[ 7]=-7.125782764510e+000 v[ 8]=-6.611764339397e+000 u[ 8]=-6.615164071601e+000 v[ 9]=-6.066103226595e+000 u[ 9]=-6.104545378693e+000 v[10]=-5.585101052628e+000 u[10]=-5.593926685784e+000 v[11]=-5.114083529812e+000 u[11]=-5.083307992875e+000 v[12]=-4.578872176865e+000 u[12]=-4.572689299966e+000 v[13]=-4.096470926260e+000 u[13]=-4.062070607058e+000 v[14]=-3.554211215751e+000 u[14]=-3.551451914149e+000 v[15]=-3.041090018133e+000 u[15]=-3.040833221240e+000 v[16]=-2.533970311130e+000 u[16]=-2.530214528331e+000 v[17]=-2.003230769563e+000 u[17]=-2.019595835422e+000 v[18]=-1.503557611227e+000 u[18]=-1.508977142514e+000 v[19]=-9.935586060075e-001 u[19]=-9.983584496049e-001 v[20]=-4.870426738850e-001 u[20]=-4.877397566962e-001 v[21]=2.231736249575e-002 u[21]=2.287893621262e-002 v[22]=5.324174742069e-001 u[22]=5.334976291214e-001 v[23]=1.052898962693e+000 u[23]=1.044116322030e+000 v[24]=1.589445881881e+000 u[24]=1.554735014939e+000 v[25]=2.060330460274e+000 u[25]=2.065353707848e+000 v[26]=2.558075597073e+000 u[26]=2.575972400756e+000 v[27]=3.080240509307e+000 u[27]=3.086591093665e+000 v[28]=3.613620867692e+000 u[28]=3.597209786574e+000 v[29]=4.091378510451e+000 u[29]=4.107828479483e+000 v[30]=4.603035378279e+000 u[30]=4.618447172392e+000 v[31]=5.132924283898e+000 u[31]=5.129065865300e+000 v[32]=5.594906348083e+000 u[32]=5.639684558209e+000 v[33]=6.080933857027e+000 u[33]=6.150303251118e+000 v[34]=6.680354092112e+000 u[34]=6.660921944027e+000 v[35]=7.293877448127e+000 u[35]=7.171540636935e+000 v[36]=7.717111714236e+000 u[36]=7.682159329844e+000 v[37]=8.225220014050e+000 u[37]=8.192778022753e+000 v[38]=8.648666065193e+000 u[38]=8.703396715662e+000 v[39]=9.254200344575e+000 u[39]=9.214015408571e+000 五. 程序 #include<stdio.h> #include<math.h> #define N 501 void main() { double Q[5][501]; double mifa(double A[5][501]); double fanmifa(double A[5][501]); double lm,lmax,lmin,ls,delta,u[39],v[39]; int i,j,k; double A[5][501]; A[0][0]=A[0][1]=A[1][0]=A[3][500]=A[4][499]=A[4][500]=0.0;//输入*501矩阵 for(i=2;i<N;i++) A[0][i]=-0.064; for(i=1;i<N;i++) A[1][i]=0.16; for(i=0;i<N;i++) A[2][i]=(1.64-0.024*(i+1))*sin(0.2*(i+1))-0.64*exp(0.1/(i+1)); for(i=0;i<500;i++) A[3][i]=0.16; for(i=0;i<499;i++) A[4][i]=-0.064; for(i=0;i<5;i++)//保存A for(j=0;j<501;j++) Q[i][j]=A[i][j]; lm=mifa(A);//按模最大特征值,函数mifa()不会改变矩阵A的值,不需还原 for(i=0;i<N;i++) //平移A { A[2][i]=A[2][i]-lm; } lmax=mifa(A);//平移后A的按模最大特征值 lmax=lmax+lm;//最大特征值或最小特征值 if(lmax<lm) { lmin=lmax; lmax=lm; } else lmin=lm; for(i=0;i<N;i++)//还原A for(j=0;j<5;j++) A[j][i]=Q[j][i]; ls=fanmifa(A);//按模最小特征值 for(i=0;i<N;i++)//还原A for(j=0;j<5;j++) A[j][i]=Q[j][i]; for(k=0;k<39;k++)//计算u1-u39 u[k]=lmin+(k+1)*((lmax-lmin)/40); for(k=0;k<39;k++) { for(j=0;j<N;j++) A[2][j]=A[2][j]-u[k]; v[k]=fanmifa(A)+u[k]; for(i=0;i<N;i++)//还原A for(j=0;j<5;j++) A[j][i]=Q[j][i]; } printf("矩阵的按模最大特征值为:%.12e",lm); printf("\n"); printf("矩阵的按模最小特征值为:%.12e",ls); printf("\n"); printf("矩阵最大的特征值为:%.12e",lmax); printf("\n"); printf("矩阵最小的特征值为:%.12e",lmin); printf("\n"); for(k=0;k<39;k++) { printf("v[%2d]=%.12e ",k+1,v[k]); printf("u[%2d]=%.12e",k+1,u[k]); printf("\n"); } } double sgn(double a)//符号函数 { if(a>0) return 1; else if(a=0) return 0; else return -1; } int max2(int a,int b) { return a>b?a:b; } int max3(int a,int b,int c) { return max2(a,b)>c?max2(a,b):c; } int min(int a,int b) { return a<b?a:b; } void LU(double A[5][501],double u[501],double B[501])//LU分解法 { double X[501]; int i,j,k,t,l; double m=0,n=0; for(k=1;k<=N;k++)//求L,U { for(j=k;j<=min(N,k+2);j++)//U { m=0; for(t=max3(1,k-2,j-2);t<=k-1;t++) { m+=A[k-t+2][t-1]*A[t-j+2][j-1]; } A[k-j+2][j-1]=A[k-j+2][j-1]-m; } for(i=k+1;i<=min(N,k+2);i++)//L if(k<N) { n=0; for(l=max3(1,i-2,k-2);l<=k-1;l++) { n+=A[i-l+2][l-1]*A[l-k+2][k-1]; } A[i-k+2][k-1]=(A[i-k+2][k-1]-n)/A[2][k-1]; } } for(i=2;i<=N;i++)//回代过程 { m=0; for(t=max2(1,i-2);t<=i-1;t++) m+=A[i-t+2][t-1]*B[t-1]; B[i-1]=B[i-1]-m; } X[N-1]=B[N-1]/A[2][N-1];//回代过程 for(i=N-1;i>=1;i--) { n=0; for(t=i+1;t<=min(N,i+2);t++) n+=A[i-t+2][t-1]*X[t-1]; X[i-1]=(B[i-1]-n)/A[2][i-1]; } for(i=1;i<=N;i++)//输出方程结果 { u[i-1]=X[i-1]; } } double mifa(double A[5][501])//幂法 { int i,j,l=0; double u[501],t[501]; double y[501]; double h,b,c; c=0; for(i=0;i<N;i++)//幂法初始向量 u[i]=1; while(1) { for(i=0;i<N;i++) t[i]=0; h=u[0]; for(i=0;i<N;i++)//无穷范数 { if(fabs(h)<fabs(u[i])) { h=u[i]; l=i; } } for(i=0;i<N;i++) y[i]=u[i]/fabs(h); for(i=2;i<499;i++) { for(j=i-2;j<=i+2;j++) { t[i]=t[i]+A[i-j+2][j]*y[j]; } u[i]=t[i]; } u[0]=A[2][0]*y[0]+A[1][1]*y[1]+A[0][2]*y[2]; u[1]=A[3][0]*y[0]+A[2][1]*y[1]+A[1][2]*y[2]+A[0][3]*y[3]; u[499]=A[4][497]*y[497]+A[3][498]*y[498]+A[2][499]*y[499]+A[1][N-1]*y[N-1]; u[N-1]=A[4][498]*y[498]+A[3][499]*y[499]+A[2][N-1]*y[N-1]; b=sgn(h)*u[l]; if((fabs(b-c)/fabs(b))<=1e-12) { //printf("幂法成功!"); //printf("\n"); break; } c=b; } return b; } double fanmifa(double A[5][501])//反幂法 { double u[501],y[501]; double P[5][501],Y[501];//LU分解前用于保存A和y的值 double m=0,n=0,b=0,c=0; int i,j; for(i=0;i<N;i++)//反幂法初始向量 u[0]=1; while(1) { b=0; n=0; for(i=0;i<N;i++) n=n+u[i]*u[i]; n=sqrt(n); for(i=0;i<N;i++) y[i]=u[i]/n; for(i=0;i<N;i++)//保存A和y { Y[i]=y[i]; for(j=0;j<5;j++) { P[j][i]=A[j][i]; } } LU(A,u,y);//LU分解法,会改变A,y,u的值(目的只需求出u) for(i=0;i<N;i++)//还原A和y { y[i]=Y[i]; for(j=0;j<5;j++) { A[j][i]=P[j][i]; } } for(i=0;i<N;i++) b=b+y[i]*u[i]; if((fabs(b-c)/fabs(b))<=1e-12) { //printf("反幂法成功!"); //printf("\n"); break; } c=b; } return 1/b; }
展开阅读全文

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


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

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

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

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

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

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

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

客服