logo资料库

C#编程多种方法求矩阵的特征值的计算实习报告.doc

第1页 / 共12页
第2页 / 共12页
第3页 / 共12页
第4页 / 共12页
第5页 / 共12页
第6页 / 共12页
第7页 / 共12页
第8页 / 共12页
资料共12页,剩余部分请下载后查看
计算实习报告 姓名:涂高波 姓名:林鑫 姓名:张庆 姓名:赵海洲 学号:2007302490 班级:11010701 学号: 学号: 学号: 班级: 班级: 班级: 一 实习目的 (1)了解矩阵特征值与相应特征向量求解的意义,理解幂法和反幂法的原理, 能编制此算法的程序,并能求解实际问题。 (2)通过对比非线性方程的迭代法,理解线性方程组迭代解法的原理,学会编 写Jacobi 迭代法程序,并能求解中小型非线性方程组。初始点对收敛性质及收 敛速度的影响。 (3)理解 QR 法计算矩阵特征值与特征向量的原理,能编制此算法的程序,并 用于实际问题的求解。 二 问题定义及题目分析 1. 分别用幂法和幂法加速技术求矩阵 2.5 0.0 0.5  2.5  A        2.5  5.0 0.5  2.5  0.5 3.0 2.0 2.0  2.5 4.0 5.0 3.5       的主特征值和特征向量. 2. 对于实对称矩阵 n nA R ,用 Jacobi 方法编写其程序,并用所编程序求下列矩阵的全部 特征值. 4 1  1  4 1  1  4 A              4 1  1  4 1          1    4  15 15  1 n nA R ,用 QR 方法编写其程序,并用所编程序求下列矩阵的全部特征值: 3. 对于实矩阵 1 1 2 n 1 1 3 n     1 1 n  3,4,5,6                     1 2  1 n n  A  n 1    1
三 概要设计 (1) 幂法用于求按模最大的特征值及其对应的特征向量的一种数值算法, 它要求矩阵 A的特征值有如下关系: 1   2    ...  n ,对于相应 的特征向量。其算法如下: , Step 0:初始化数据 k  1 . k Step 1:计算 y m Step 2:令 k z  Step 3:令 k 。 1 0   , A z A z  k y  k y m k k 。 ;如果 m m  1 k k  或 z k z  1 k ,则 goto Step 4;否则 , k = k + 1 ,goto Step 1。 Step 4:输出结果 算法说明与要求 输入参数为实数矩阵、初始向量、误差限与最大迭代次数。输出 参数为特征值及相对应的特征向量。注意初始向量不能为“0”向量。 (2) 迭代法的原理 如果能将方程 Ax=b 改写成等价形式:x=Bx+f。如果B 满足:ρ(B)<1, 则对于任意初始向量 x (0) ,由迭代 x( k + 1) = Bx(k ) + f 产生的序列均 收敛到方程组的精确解。迭代法中两种最有名的迭代法就是Jacobi 迭代法,它 的迭代矩阵 B 为: D L U  1 f D b   1(  J ) , 其中,D 为系数矩阵 A 的对角元所组成对角矩阵,L 为系数矩阵 A 的对角元下 方所有元素所组成的下三角矩阵,U 为系数矩阵 A 的对角元上方所有元素所组 成的上三角矩阵。 算法如下: Step 0:初始化数据 k  0, , A b x  , , 0 和 。 Step 1:计算D,L,U,J或G, 得到迭代矩阵B.  f Step 2: : k 1 k   x B x 0 x x 0 x  Step 2。 Step 3:输出结果。 如果 x  0  或   f x  ,goto Step 3;否则 goto
程序说明与要求 程序的输入参数为系数矩阵与常量、初始向量及误差控制,输出参数 为方程组的近似解。要求输入系数 A 中对角元不能存在 0,如果对角元出 现 0 元素,则可以通过交换方程组中方程的次序解决。 (3) QR法原理 QR算法是求实对称矩阵全部特征的最有效方法。其基本过程就是利用矩 阵的QR分解,即将任一实数矩阵分解为一个正交矩阵Q 与一个上三角矩 阵 R 的乘积。 QR 算法的计算过程如下 Step 0:初始化数据 A Q R , , 0 , A 0  Q R k , 0 0  1 Step 1:令 A k  Q R 1 k k  1 。  A Step 2:计算 k Step 3:令 km 为 kR 所有对角元下方元素绝对值之和; Q R k k 如果 km  ,则 goto Step 4; 否则, k = k + 1 ,goto Step 1。 Step 4:输出结果。 算法的要求与说明 先利用函数 house 将对称矩阵 A 通过Householder 相似变换为对 称三对角阵 T,然后通过程序 QR_method 求出矩阵 T 的特征值。程序 输入参数为矩阵 A,输出参数为矩阵 A 的所有特征值。 四 详细设计 源程序 (1) #include"math.h" #include"stdio.h" void main() {int i,j; int n=4,k=0; float /*主函数*/ a[4][4]={{2.5,-2.5,3.0,0.5},{0.0,5.0,-2.0,2.0},{-0.5,-0.5,4.0,2.5},{-2. 5,-2.5,5.0,3.5}},x[4]={1,1,1,1}; double max,m,y[4],z[4],ej=0.0001,e; printf("k max(xk) y(k)=x(k)/max(x(k)) x(k+1)=a*y(k)\n"); /*输出格式*/
cyclo: {for(i=0;imax) max=fabs(x[i]); } for(i=0;iej) goto cyclo; else {printf("at last %f ",max); /*输出循环中止时的最终结果,即矩阵 的主特征值和对应的特征向量y[]*/ printf("("); for(i=0;i
} (2) #include #include //a 存放n阶实对称阵,返回时对角线存放n个特征值 //n 矩阵阶数 //v //eps 控制精度 //jt 最大迭代次数 n阶矩阵,第j列为对应第j个特征值的特征向量 //返回值:大于0则计算成功,小于0则失败 int jacobi(double *a,int n,double *v,double eps,int jt) { int i,j,p,q,u,w,t,s,l; double fm,cn,sn,omega,x,y,d; l=1; for (i=0; i<=n-1; i++) { v[i*n+i]=1.0; for (j=0; j<=n-1; j++) if (i!=j) v[i*n+j]=0.0; } while (1) { fm=0.0; for (i=1; i<=n-1; i++) for (j=0; j<=i-1; j++) { d=fabs(a[i*n+j]); if ((i!=j)&&(d>fm)) { fm=d; p=i; q=j;} } if (fmjt) return(-1); l=l+1; u=p*n+q; w=p*n+p; t=q*n+p; s=q*n+q; x=-a[u]; y=(a[s]-a[w])/2.0; omega=x/sqrt(x*x+y*y); if (y<0.0) omega=-omega; sn=1.0+sqrt(1.0-omega*omega); sn=omega/sqrt(2.0*sn); cn=sqrt(1.0-sn*sn); fm=a[w]; a[w]=fm*cn*cn+a[s]*sn*sn+a[u]*omega;
a[s]=fm*sn*sn+a[s]*cn*cn-a[u]*omega; a[u]=0.0; a[t]=0.0; for (j=0; j<=n-1; j++) if ((j!=p)&&(j!=q)) { u=p*n+j; w=q*n+j; fm=a[u]; a[u]=fm*cn+a[w]*sn; a[w]=-fm*sn+a[w]*cn; } for (i=0; i<=n-1; i++) if ((i!=p)&&(i!=q)) { u=i*n+p; w=i*n+q; fm=a[u]; a[u]=fm*cn+a[w]*sn; a[w]=-fm*sn+a[w]*cn; } for (i=0; i<=n-1; i++) { u=i*n+p; w=i*n+q; fm=v[u]; v[u]=fm*cn+v[w]*sn; v[w]=-fm*sn+v[w]*cn; } } return(1); } int main(){ int i,j; double a[15][15]; double v[15][15]; printf("示例矩阵:\n"); for(i=0;i<=14;i++) { for(j=0;j<=14;j++) { if(i==j) a[i][j]=4; else if(fabs(i-j)==1) a[i][j]=-1; else a[i][j]=0; printf("%lf\t",a[i][j]); } printf("\n");
} jacobi((double*)a,15,(double*)v,0.0001,100); for(i=0;i<=14;i++) {printf("特征值为:%lf\t",a[i][i]);} return 0; } (3) #include #include #include using namespace std; #include #define N 3 //矩阵的维数 #define NUM 15 //QR分解次数 #define SNUM 13 //用来控制输出格式 void Print(long double A[N][N],long double Q[N][N],long double R[N][N]); //矩阵输出 void QR(long double A[N][N],long double Q[N][N],long double R[N][N]); //QR分解 void Multiplicate(long double A[N][N],long double R[N][N],long double Q[N][N]); //迭代,获得下一次矩阵A=QR int main() { int i,j; long double A[N][N]; long double Q[N][N]={0}; long double R[N][N]={0}; cout<<"*************************************************************"<< endl; cout<<"输入初始矩阵:\n"; cout<<"-------------------------------------------------------------"<< endl; for(i=0;i>A[i][j];
cout<<"*************************************************************"<< endl; cout<<"输出每一步迭代过程: \n"; cout<<"*************************************************************"<< endl; for(i=1;i<=NUM;i++) { QR(A,Q,R); cout<<"第"<
分享到:
收藏