北航数值分析大作业一
北航数值分析大作业 第一题 幂法与反幂法
数 值 分 析(B ) 大 作 业(一)姓名: 学号: 电话:1、算法设计:①求1λ、501λ和s λ的值:s λ:s λ表示矩阵的按模最小特征值,为求得s λ直接对待求矩阵A 应用反幂法即可。
1λ、501λ:若矩阵A 的特征值满足关系 1n λλ<<且1n λλ≠,要求1λ、及501λ时,可按如下方法求解: a . 对矩阵A 用幂法,求得按模最大的特征值1m λ。
b . 按平移量1m λ对矩阵A 进行原点平移得矩阵1m BA I λ=+,对矩阵B 用反幂法求得B 的按模最小特征值2m λ。
c . 321m m m λλλ=-则:113min(,)m m λλλ=,13max(,)n m m λλλ=即为所求。
②求和A 的与数5011140k k λλμλ-=+最接近的特征值ik λ(k=0,1,…39):求矩阵A 的特征值中与P 最接近的特征值的大小,采用原点平移的方法:先求矩阵 B=A-PI 对应的按模最小特征值k β,则k β+P 即为矩阵A 与P 最接近的特征值。
在本次计算实习中则是先求平移矩阵k B A I μ=-,对该矩阵应用反幂法求得s λ,则与k μ最接近的A 的特征值为:s P λ+重复以上过程39次即可求得ik λ(k=0,1,…39)的值。
③求A 的(谱范数)条件数2cond()A 和行列式det A :在(1)中用反幂法求矩阵A 的按模最小特征值时,要用到Doolittle 分解方法,在Doolittle 分解完成后得到的两个矩阵分别为L 和U ,则A 的行列式可由U 阵求出,即:det(A)=det(U)。
求得det(A)不为0,因此A 为非奇异的实对称矩阵,则: max 2()scond A λλ=,max λ和s λ分别为模最大特征值与模最小特征值。
2、程序源代码:#include "Stdio.h"#include "Conio.h"#include "math.h"//****************************************************************************// // 在存储带状矩阵时,下面的几个量在程序中反复用到,为方便编程故把它们定义成宏.// // M :转换后的矩阵的行数,M=R+S+1。
北航数值分析实验报告
北航数值分析实验报告篇一:北航数值分析报告第一大题《数值分析》计算实习报告第一大题学号:DY1305姓名:指导老师:一、题目要求已知501*501阶的带状矩阵A,其特征值满足?1?2...?501。
试求:1、?1,?501和?s的值;2、A的与数?k??1?k?501??140最接近的特征值?ik(k=1,2,...,39);3、A的(谱范数)条件数c nd(A)2和行列式de tA。
二、算法设计方案题目所给的矩阵阶数过大,必须经过去零压缩后进行存储和运算,本算法中压缩后的矩阵A1如下所示。
?0?0?A1??a1??b??c0b a2bcc bb c............c bb ccb a500b0a 3...a499c?b??a501??0?0??由矩阵A的特征值满足的条件可知?1与?501之间必有一个最大,则采用幂法求出的一个特征值必为其中的一个:当所求得的特征值为正数,则为?501;否则为?1。
在求得?1与?501其中的一个后,采用带位移的幂法则可求出它们中的另一个,且位移量即为先求出的特征值的值。
用反幂法求得的特征值必为?s。
由条件数的性质可得,c nd(A)2为模最大的特征值与模最小的特征值之比的模,因此,求出?1,?501和?s的值后,则可以求得c nd(A)2。
北航研究生数值分析编程大作业1
数值分析大作业一、算法设计方案1、矩阵初始化矩阵[]501501⨯=ij a A 的下半带宽r=2,上半带宽s=2,设置矩阵[][]5011++s r C ,在矩阵C 中检索矩阵A 中的带内元素ij a 的方法是:j s j i ij c a ,1++-=。
这样所需要的存储单元数大大减少,从而极大提高了运算效率。
2、利用幂法求出5011λλ,幂法迭代格式:0111111nk k k k kk T k k k u R y u u Ay y u ηηβ------⎧∈⎪⎪=⎪=⎨⎪=⎪⎪=⎩非零向量 当1210/-≤-k k βββ时,迭代终止。
首先对于矩阵A 利用幂法迭代求出一个λ,然后求出矩阵B ,其中I A B λ-=(I 为单位矩阵),对矩阵B 进行幂法迭代,求出λ',之后令λλλ+'='',比较的大小与λλ'',大者为501λ,小者为1λ。
3、利用反幂法求出ik s λλ,反幂法迭代格式:0111111nk k k k kk T k k k u R y u Au y y u ηηβ------⎧∈⎪⎪=⎪=⎨⎪=⎪⎪=⎩非零向量 当1210/-≤-k k βββ时,迭代终止,1s k λβ=。
每迭代一次都要求解一次线性方程组1-=k k y Au ,求解过程为:(1)作分解LU A =对于n k ,...,2,1=执行[][]s k n r k k k i c c c c c n s k k k j c cc c k s ks k t k s k r i t t s t i k s k i k s k i js j t k s j r k t t s t k j s j k j s j k <+++=-=++=-=+++----=++-++-++-++----=++-++-++-∑∑);,min(,...,2,1/)(:),min(,...,1,:,1,11),,1max(,1,1,1,11),,1max(,1,1,1(2)求解y Ux b Ly ==,(数组b 先是存放原方程组右端向量,后来存放中间向量y))1,...,2,1(/)(:/:),...,3,2(:,1),min(1.1.11),1max(,1--=-===-=+++-++-+--=++-∑∑n n i c x c b x c b x n i b c b b i s t n s i i t t s t i i i ns n n ti r i t t s t i i i使用反幂法,直接可以求得矩阵按模最小的特征值s λ。
北航数值分析计算实习1
《数值分析》计算实习题目110091013 劳云杰一、算法设计方案根据提示的算法,首先使用幂法求出按模最大的特征值λt1,再根据已求出的λt1用带原点平移的幂法求出另一个特征值λt2,比较两个λ的大小,根据已知条件,可以得出λ1和λ501.至于λs,由于是按模最小的特征值,使用反幂法求之,由于反幂法需要解线性方程组,故对矩阵进行Doolittle分解。
再通过带原点平移的反幂法求跟矩阵的与数最接近的特征值。
对非奇异的矩阵A,根据条件数定义,取λt1/λs的绝对值,两个特征值在之前步骤中均以求得。
由于对矩阵进行了Doolittle分解,所以矩阵的行列式det A可由分解得出的上三角阵U 的对角线上元素相乘求得。
为了使A的所有零元素都不存储,使用书本25页的压缩存储法对A进行存储,在计算时通过函数在数组C中检索A中元素即可。
由于A是501*501矩阵,C应取为5*501矩阵。
由于数据不大,为了方便起见,在程序中取502*502矩阵或者502向量,C也取为6*502矩阵。
程序编写参考《数值分析》颜庆津著和[C数值算法].(美国)W ILLIAM.H.P RESS.扫描版。
二、全部源程序#include <stdio.h>#include <math.h>#define XS 1.0e-12//精度水平void fz_a();//对矩阵A赋值double js(int,int);//在压缩矩阵中检索A的元素double mf(double);//幂法double fmf(double);//反幂法int lu(double);//Doolittle分解int jfc(double[],double[]);//解方程int max(int,int);int min(int,int);double (*u)[502]=new double[502][502];//上三角阵double (*l)[502]=new double[502][502];//单位下三角阵double a[6][502];//压缩存储矩阵int max(int x,int y)//比大小函数×2{ return (x>y?x:y);}int min(int x,int y)//精度关系,比较下标用{ return (x<y?x:y);}int main(){printf("请耐心等待,先看看中间过程吧~\n");int i,k;double ldt1,ldt2,ld1,ld501,lds,mu[40],det;double ld[40];fz_a();//对A赋值ldt1=mf(0);//幂法求模最大的特征值ldt2=mf(ldt1);//以第一次求得的特征值进行平移ld1=ldt1<ldt2?ldt1:ldt2;//大的就是λ501ld501=ldt1<ldt2?ldt2:ldt1;lu(0);lds=fmf(0);//反幂法求λsdet=1;//初始化行列式for(i=1;i<=501;i++)det=det*u[i][i];//用U的对角元素求行列式for(k=1;k<=39;k++){mu[k]=ld1+k*(ld501-ld1)/40;//与数lu(mu[k]);ld[k]=fmf(mu[k]);}printf("\n 列出结果\n");printf("λ1=%1.12e λ501=%1.12e\n",ld1,ld501);printf("λs=%1.12e \n",lds);printf("cond(A)=%1.12e \n",fabs(ldt1/lds));printf("detA=%1.12e \n",det);for(k=1;k<=39;k++)//列出跟与数最接近特征值{printf("λi%d=%1.12e\t",k,ld[k]);if(k%2==0)printf("\n");}//界面友好性delete []u;delete []l;getchar();return 0;}void fz_a()//对A赋值{int i;for(i=3;i<=501;i++)a[1][i]=a[5][502-i]=-0.064;//原A矩阵的cfor(i=2;i<=501;i++)a[2][i]=a[4][502-i]=0.16;//原A矩阵的bfor(i=1;i<=501;i++)a[3][i]=(1.64-0.024*i)*sin(0.2*i)-0.64*exp(0.1/i);//原对角线元素}double js(int i,int j)//对压缩矩阵检索A的元素{if(abs(i-j)<=2)return a[i-j+3][j];else return 0;}double mf(double offset)//幂法{int i,x1;double u[502],y[502];double beta=0,prebeta=-1000,yita=0;//用幂法的第一种迭代方法for(i=1;i<=501;i++) //用到了2-范数u[i]=1,y[i]=0;for(int k=1;k<=10000;k++)//对迭代次数进行限制{yita=0;for(i=1;i<=501;i++)yita=sqrt(yita*yita+u[i]*u[i]);for(i=1;i<=501;i++)y[i]=u[i]/yita;for(x1=1;x1<=501;x1++){u[x1]=0;for(int x2=1;x2<=501;x2++)u[x1]=u[x1]+((x1==x2)?(js(x1,x2)-offset):js(x1,x2))*y[x2];}prebeta=beta;beta=0;for(i=1;i<=501;i++)beta=beta+y[i]*u[i];if(fabs((prebeta-beta)/beta)<=XS){printf("offset=%f lb=%f err=%e k=%d\n",offset,(beta+offset),fabs((prebeta-beta)/beta),k);break;};}//满足误差条件后,迭代终止,并输出平移量,误差和迭代次数return(beta+offset);//加上平移量,方便比较}double fmf(double offset)//反幂法{ int i;double u[502],y[502];double beta=0,prebeta=0,yita=0;for(i=1;i<=501;i++)u[i]=1,y[i]=0; //相关量初始化for(int k=1;k<=10000;k++)//限制迭代次数{yita=0;for(i=1;i<=501;i++)yita=sqrt(yita*yita+u[i]*u[i]);for(i=1;i<=501;i++)y[i]=u[i]/yita;jfc(u,y);prebeta=beta;beta=0;for(i=1;i<=501;i++)beta=beta+y[i]*u[i];beta=1/beta;if(fabs((prebeta-beta)/beta)<=XS){printf("offset=%f lb=%f err=%ek=%d\n",offset,(beta+offset),fabs((prebeta-beta)/beta),k);break;};}//满足误差条件后,迭代终止,并输出平移量,误差和迭代次数return(beta+offset);}int lu(double offset)//Doolittle分解{int i,j,k,t;double sum;//中间量for(k=1;k<=501;k++)for(j=1;j<=501;j++){u[k][j]=l[k][j]=0;if(k==j)l[k][j]=1;}//对LU矩阵初始化for(k=1;k<=501;k++)//对式(2.12)的程序实现{for(j=k;j<=min(k+2,501);j++){sum=0;for(t=max(1,max(k-2,j-2));t<=(k-1);t++)sum=sum+l[k][t]*u[t][j];//j=k,k+1,……,nu[k][j]=((k==j)?(js(k,j)-offset):js(k,j))-sum;}if(k==501)continue;for(i=k+1;i<=min(k+2,501);i++)//i=k+1,……,n{sum=0;for(t=max(1,max(i-2,k-2));t<=(k-1);t++)sum=sum+l[i][t]*u[t][k];l[i][k]=(((i==k)?(js(i,k)-offset):js(i,k))-sum)/u[k][k];}}return 0;}int jfc(double x[],double b[])//解方程{int i,t;double y[502];double sum;y[1]=b[1];for(i=2;i<=501;i++){sum=0;for(t=max(1,i-2);t<=i-1;t++)sum=sum+l[i][t]*y[t];y[i]=b[i]-sum;}x[501]=y[501]/u[501][501];for(i=500;i>=1;i--){sum=0;for(t=i+1;t<=min(i+2,501);t++)sum=sum+u[i][t]*x[t];x[i]=(y[i]-sum)/u[i][i];}return 0;}三、结果λ1=-1.070011361502e+001λ501=9.724634098777e+000λs=-5.557910794230e-003cond(A)=1.925204273902e+003detA=2.772786141752e+118λi1=-1.018293403315e+001 λi2=-9.585707425068e+000 λi3=-9.172672423928e+000λi4=-8.652284007898e+000 λi5=-8.0934********e+000 λi6=-7.659405407692e+000λi7=-7.119684648691e+000 λi8=-6.611764339397e+000 λi9=-6.0661********e+000λi10=-5.585101052628e+000 λi11=-5.114083529812e+000 λi12=-4.578872176865e+000λi13=-4.096470926260e+000 λi14=-3.554211215751e+000 λi15=-3.0410********e+000 λi16=-2.533970311130e+000 λi17=-2.003230769563e+000 λi18=-1.503557611227e+000 λi19=-9.935586060075e -001 λi20=-4.870426738850e -001 λi21=2.231736249575e -002 λi22=5.324174742069e -001 λi23=1.052898962693e+000 λi24=1.589445881881e+000 λi25=2.060330460274e+000 λi26=2.558075597073e+000 λi27=3.080240509307e+000 λi28=3.613620867692e+000 λi29=4.0913********e+000 λi30=4.603035378279e+000 λi31=5.132924283898e+000 λi32=5.594906348083e+000 λi33=6.080933857027e+000 λi34=6.680354092112e+000 λi35=7.293877448127e+000 λi36=7.717111714236e+000 λi37=8.225220014050e+000 λi38=8.648666065193e+000 λi39=9.254200344575e+000四、讨论迭代初始向量的选取对计算结果的影响1.在反幂法中取迭代向量u[1]=1,u[i]=0,i=2,……,501,最后得出的结果中λs=2.668886923785e -002,cond(A)也随之改变成4.009204556274e+0022.在幂法中取迭代向量u[1]=1,u[i]=2,i=2,……,501,最后得出的结果不变。
数值分析大作业一
数值分析大作业一一、算法设计方案1、求λ1和λ501的值:思路:采用幂法求出按模最大特征值λmax,该值必为λ1或λ501,若λmax小于0,则λmax=λ1;否则λmax=λ501。
再经过原点平移,使用幂法迭代出矩阵A-λmax I的特征值,此时求出的按模最大特征值即为λ1和λ501的另一个值。
2、求λs的值:采用反幂法求出按模最小的特征值λmin即为λs,其中的方程组采用LU分解法进行求解。
3、求与μk最接近的特征值:对矩阵A采用带原点平移的反幂法求解最小特征值,其中平移量为:μk。
4、A的条件数cond(A)=| λmax/λmin|;5、A的行列式的值:先将A进行LU分解,再求U矩阵对角元素的乘积即为A 行列式的值。
二、源程序#include<iostream>#include<iomanip>#include<math.h>#define N 501#define E 1.0e-12 //定义精度常量#define r 2#define s 2using namespace std;double a[N];double cc[5][N];void init();double mifa();double fmifa();int max(int aa,int bb);int min(int aa,int bb);int max_3(int aa,int bb,int cc);void LU();void main(){double a1,a2,d1,d501=0,ds,det=1,miu[39],lamta,cond;int i,k;init();/*************求λ1和λ501********************/a1=mifa();if(a1<0)d1=a1; //若小于0则表示λ1的值elsed501=a1; //若大于0则表示λ501的值for(i=0;i<N;i++)a[i]=a[i]-a1;a2=mifa()+a1;if(a2<0)d1=a2; //若小于0则表示λ1的值elsed501=a2; //若大于0则表示λ501的值cout<<"λ1="<<setiosflags(ios::scientific)<<setprecision(12)<<d1<<"\t";cout<<"λ501="<<setiosflags(ios::scientific)<<setprecision(12)<<d501<<endl;/**************求λs*****************/init();ds=fmifa();cout<<"λs="<<setiosflags(ios::scientific)<<setprecision(12)<<ds<<endl;/**************求与μk最接近的特征值λik**************/cout<<"与μk最接近的特征值λik:"<<endl;for(k=0;k<39;k++){miu[k]=d1+(k+1)*(d501-d1)/40;init();for(i=0;i<N;i++)a[i]=a[i]-miu[k];lamta=fmifa()+miu[k];cout<<"λi"<<k+1<<"\t\t"<<setiosflags(ios::scientific)<<setprecision(12)<<lamta<<en dl;}/**************求A的条件数**************/cout<<"矩阵A的条件式";cond=abs(max(abs(d1),abs(d501))/ds);cout<<"cond="<<setiosflags(ios::scientific)<<setprecision(12)<<cond<<endl;/**************求A的行列式**************/cout<<"矩阵A的行列式";init();LU();for(i=0;i<N;i++){det*=cc[2][i];}cout<<"det="<<setiosflags(ios::scientific)<<setprecision(12)<<det<<endl;system("pause");}/**************初始化函数,给a[N]赋值*************/void init(){int i;for(i=1;i<=501;i++)a[i-1]=(1.64-0.024*i)*sin((double)(0.2*i))-0.64*exp((double)(0.1/i)); }/**************幂法求最大绝对特征值**************/double mifa(){int i,k=0;double u[N],y[N]={0},b=0.16,c=-0.064,Beta_=0,error;for(i=0;i<501;i++)u[i]=1; //令u[N]=1for(k=1;k<2000;k++) //控制最大迭代次数为2000{/***求y(k-1)***/double sum_u=0,gh_sum_u;for(i=0;i<N;i++){sum_u+=u[i]*u[i]; }gh_sum_u=sqrt(sum_u);for(i=0;i<N;i++){y[i]=u[i]/gh_sum_u;}/****求新的uk****/u[0]=a[0]*y[0]+b*y[1]+c*y[2];u[1]=b*y[0]+a[1]*y[1]+b*y[2]+c*y[3]; //前两列和最后两列单独拿出来求中D间的循环求for(i=2;i<N-2;i++){u[i]=c*y[i-2]+b*y[i-1]+a[i]*y[i]+b*y[i+1]+c*y[i+2];}u[N-2]=c*y[N-4]+b*y[N-3]+a[N-2]*y[N-2]+b*y[N-1];u[N-1]=c*y[N-3]+b*y[N-2]+a[N-1]*y[N-1];/***求beta***/double Beta=0;for(i=0;i<N;i++){Beta+=y[i]*u[i];}//cout<<"Beta"<<k<<"="<<Beta<<"\t"; 输出每次迭代的beta /***求误差***/error=abs(Beta-Beta_)/abs(Beta);if(error<=E) //若迭代误差在精度水平内则可以停止迭代{return Beta;} //控制显示位数Beta_=Beta; //第个eta的值都要保存下来,为了与后个值进行误差计算 }if(k==2000){cout<<"error"<<endl;return 0;} //若在最大迭代次数范围内都不能满足精度要求说明不收敛}/**************反幂法求最小绝对特¬征值**************/double fmifa(){int i,k,t;double u[N],y[N]={0},yy[N]={0},b=0.16,c=-0.064,Beta_=0,error;for(i=0;i<501;i++)u[i]=1; //令u[N]=1for(k=1;k<2000;k++){double sum_u=0,gh_sum_u;for(i=0;i<N;i++){sum_u+=u[i]*u[i]; }gh_sum_u=sqrt(sum_u);for(i=0;i<N;i++){y[i]=u[i]/gh_sum_u;yy[i]=y[i]; //用重新赋值,避免求解方程组的时候改变y的值}/****LU分解法解方程组Au=y,求新的***/LU();for(i=2;i<=N;i++){double temp_b=0;for(t=max(1,i-r);t<=i-1;t++)temp_b+=cc[i-t+s][t-1]*yy[t-1];yy[i-1]=yy[i-1]-temp_b;}u[N-1]=yy[N-1]/cc[s][N-1];for(i=N-1;i>=1;i--){double temp_u=0;for(t=i+1;t<=min(i+s,N);t++)temp_u+=cc[i-t+s][t-1]*u[t-1];u[i-1]=(yy[i-1]-temp_u)/cc[s][i-1];}double Beta=0;for(i=0;i<N;i++){Beta+=y[i]*u[i];}error=abs(Beta-Beta_)/abs(Beta);if(error<=E){return (1/Beta);}Beta_=Beta;}if(k==2000){cout<<"error"<<endl;return 0;} }/**************求两数最大值的子程序**************/int max(int aa,int bb){return(aa>bb?aa:bb);}/**************求两数最小值的子程序**************/int min(int aa,int bb){return(aa<bb?aa:bb);}/**************求三数最大值的子程序**************/int max_3(int aa,int bb,int cc){ int tt;if(aa>bb)tt=aa;else tt=bb;if(tt<cc) tt=cc;return(tt);}/**************LU分解**************/void LU(){int i,j,k,t;double b=0.16,c=-0.064;/**赋值压缩后矩阵cc[5][501]**/for(i=2;i<N;i++)cc[0][i]=c;for(i=1;i<N;i++)cc[1][i]=b;for(i=0;i<N;i++)cc[2][i]=a[i];for(i=0;i<N-1;i++)cc[3][i]=b;for(i=0;i<N-2;i++)cc[4][i]=c;for(k=1;k<=N;k++){for(j=k;j<=min(k+s,N);j++){double temp=0;for(t=max_3(1,k-r,j-s);t<=k-1;t++)temp+=cc[k-t+s][t-1]*cc[t-j+s][j-1];cc[k-j+s][j-1]=cc[k-j+s][j-1]-temp;}//if(k<500){for(i=k+1;i<=min(k+r,N);i++){double temp2=0;for(t=max_3(1,i-r,k-s);t<=k-1;t++)temp2+=cc[i-t+s][t-1]*cc[t-k+s][k-1];cc[i-k+s][k-1]=(cc[i-k+s][k-1]-temp2)/cc[s][k-1];}}}}三、程序结果。
北航数值分析大作业一
《数值分析B》大作业一SY1103120 朱舜杰一.算法设计方案:1.矩阵A的存储与检索将带状线性矩阵A[501][501]转存为一个矩阵MatrixC[5][501] .由于C语言中数组角标都是从0开始的,所以在数组MatrixC[5][501]中检索A的带内元素a ij的方法是:A的带内元素a ij=C中的元素c i-j+2,j2.求解λ1,λ501,λs①首先分别使用幂法和反幂法迭代求出矩阵按摸最大和最小的特征值λmax和λmin。
λmin即为λs;如果λmax>0,则λ501=λmax;如果λmax<0,则λ1=λmax。
②使用带原点平移的幂法(mifa()函数),令平移量p=λmax,求出对应的按摸最大的特征值λ,max,如果λmax>0,则λ1=λ,max+p;如果λmax<0,则λ501=λ,max+p。
3.求解A的与数μk=λ1+k(λ501-λ1)/40的最接近的特征值λik (k=1,2,…,39)。
使用带原点平移的反幂法,令平移量p=μk,即可求出与μk最接近的特征值λik。
4.求解A的(谱范数)条件数cond(A)2和行列式d etA。
①cond(A)2=|λ1/λn|,其中λ1和λn分别是矩阵A的模最大和最小特征值。
②矩阵A的行列式可先对矩阵A进行LU分解后,detA等于U所有对角线上元素的乘积。
二.源程序#include<stdio.h>#include<iostream.h>#include<stdlib.h>#include<math.h>#include<float.h>#include<iomanip.h>#include<time.h>#define E 1.0e-12 /*定义全局变量相对误差限*/int max2(int a,int b) /*求两个整型数最大值的子程序*/{if(a>b)return a;elsereturn b;}int min2(int a,int b) /*求两个整型数最小值的子程序*/{if(a>b)return b;elsereturn a;}int max3(int a,int b,int c) /*求三整型数最大值的子程序*/{ int t;if(a>b)t=a;else t=b;if(t<c) t=c;return(t);}void assignment(double array[5][501]) /*将矩阵A转存为数组C[5][501]*/{int i,j,k;//所有元素归零for(i=0;i<=4;){for(j=0;j<=500;){array[i][j]=0;j++;}i++;}//第0,4行赋值for(j=2;j<=500;){k=500-j;array[0][j]=-0.064;array[4][k]=-0.064;j++;}//第1,3行赋值for(j=1;j<=500;){k=500-j;array[1][j]=0.16;array[3][k]=0.16;j++;}//第2行赋值for(j=0;j<=500;){ k=j;j++;array[2][k]=(1.64-0.024*j)*sin((double)(0.2*j))-0.64*exp((double)(0.1/j));}}double mifa(double u[501],double array[5][501],double p) /*带原点平移的幂法*/ {int i,j; /* u[501]为初始迭代向量*/double a,b,c=0; /* array[5][501]为矩阵A的转存矩阵*/double y[501]; /*p为平移量*/for(;;){a=0;b=0;/*选用第一种迭代格式*///求ηk-1for(i=0;i<=500;i++){a=a+u[i]*u[i];}a=sqrt(a);//求y k-1for(i=0;i<=500;i++){y[i]=u[i]/a;}//求u kfor(i=0;i<=500;i++){u[i]=0;for(j=max2(i-2,0);j<=min2(i+2,500);j++){u[i]+=array[i-j+2][j]*y[j];}u[i]=u[i]-p*y[i]; /*引入平移量*/}//求βkfor(i=0;i<=500;i++){b+=y[i]*u[i];}if(fabs((b-c)/b)<=E) /*达到精度水平,迭代终止*/break;c=b;}return (b+p); /*直接返回A的特征值*/}void chuzhi(double a[]) /*用随机数为初始迭代向量赋值*/ {int i;srand((int)time(0));for(i=0;i<=500;i++){a[i]=(10.0*rand()/RAND_MAX); /*生成0~10的随机数*/}}void chuzhi2(double a[],int j) /*令初始迭代向量为e i*/{int i;for(i=0;i<=500;i++){a[i]=0;}a[j]=1;}void LU(double array[5][501]) /*对矩阵A进行Doolittle分解*/{ /*矩阵A转存在C[5][501]中*/int j,k,t; /*分解结果L,U分别存在C[5][501]的上半部与下半部*/ for(k=0;k<=500;k++){for(j=k;j<=min2((k+2),500);j++){for(t=max3(0,k-2,j-2);t<=(k-1);t++){array[k-j+2][j]-=array[k-t+2][t]*array[t-j+2][j];}}if(k<500)for(j=k+1;j<=min2((k+2),500);j++){for(t=max3(0,k-2,j-2);t<=(k-1);t++){array[j-k+2][k]-=array[j-t+2][t]*array[t-k+2][k];}array[j-k+2][k]=array[j-k+2][k]/array[2][k];}}}double fmifa(double u[501],double array[5][501],double p){ /*带原点平移的反幂法*/ int i,j;double a,b,c=0;double y[501];//引入平移量for(i=0;i<=500;i++){array[2][i]-=p;}//先将矩阵Doolittle分解LU(array);for(;;){a=0;b=0;//求ηk-1for(i=0;i<=500;i++){a=a+u[i]*u[i];}a=sqrt(a);//求y k-1for(i=0;i<=500;i++){y[i]=u[i]/a;}//回带过程,求解u kfor(i=0;i<=500;i++){u[i]=y[i];}for(i=1;i<=500;i++){for(j=max2(0,(i-2));j<=(i-1);j++){u[i]-=array[i-j+2][j]*u[j];}}u[500]=u[500]/array[2][500];for(i=499;i>=0;i--){for(j=i+1;j<=min2((i+2),500);j++){u[i]-=array[i-j+2][j]*u[j];}u[i]=u[i]/array[2][i];}//求βkfor(i=0;i<=500;i++){b+=y[i]*u[i];}if(fabs((b-c)/b)<=E) /*达到精度要求,迭代终止*/break;c=b;}return (p+(1/b)); /*直接返回距离原点P最接近的A的特征值*/ }//主函数main(){ int i;double d1,d501,ds,d,a;double u[501];double MatrixC[5][501];printf(" 《数值分析》计算实习题目第一题\n");printf(" SY1103120 朱舜杰\n");//将矩阵A转存为MatrixCassignment(MatrixC);//用带原点平移的幂法求解λ1,λ501chuzhi(u);d=mifa(u,MatrixC,0);chuzhi(u);a=mifa(u,MatrixC,d);if(d<0){d1=d;d501=a;}else{d501=d;d1=a;}printf("λ1=%.12e\n",d1);printf("λ501=%.12e\n",d501);//用反幂法求λschuzhi(u);ds=fmifa(u,MatrixC,0);printf("λs=%.12e\n",ds);//用带原点平移的反幂法求λikfor(i=1;i<=39;i++){a=d1+(i*(d501-d1))/40;assignment(MatrixC);chuzhi(u);d=fmifa(u,MatrixC,a);printf("与μ%02d=%+.12e最接近的特征值λi%02d=%+.12e\n",i,a,i,d);}//求A的条件数d=fabs((d1/ds));printf("A的(谱范数)条件数cond<A>2=%.12e\n",d);//求detAassignment(MatrixC);LU(MatrixC);a=1;for(i=0;i<=500;i++){a*=MatrixC[2][i];}printf("行列式detA=%.12e\n",a);//测试不同迭代初始向量对λ1计算结果的影响。
北航数值分析大作业一
北京航空航天大学数值分析大作业一学院名称自动化专业方向控制工程学号ZY*******学生姓名许阳教师孙玉泉日期2021 年11月26 日设有501501⨯的实对称矩阵A ,⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎣⎡=5011A a b c b c c b c b a其中,064.0,16.0),501,,2,1(64.0)2.0sin()024.064.1(1.0-==⋅⋅⋅=--=c b i e i i a ii 。
矩阵A 的特征值为)501,,2,1(⋅⋅⋅=i i λ,并且有||min ||,501150121i i s λλλλλ≤≤=≤⋅⋅⋅≤≤1λ,501λ和s λ的值。
A 的与数4015011λλλμ-+=kk 最接近的特征值)39,,2,1(⋅⋅⋅=k k i λ。
A 的(谱范数)条件数2)A (cond 和行列式detA 。
一 方案设计1 求1λ,501λ和s λ的值。
s λ为按模最小特征值,||min ||5011i i s λλ≤≤=。
可使用反幂法求得。
1λ,501λ分别为最大特征值及最小特征值。
可使用幂法求出按模最大特征值,如结果为正,即为501λ,结果为负,那么为1λ。
使用位移的方式求得另一特征值即可。
2 求A 的与数4015011λλλμ-+=kk 最接近的特征值)39,...,2,1(=k k i λ。
题目可看成求以k μ为偏移量后,按模最小的特征值。
即以k μ为偏移量做位移,使用反幂法求出按模最小特征值后,加上k μ,即为所求。
3 求A 的(谱范数)条件数2)(A cond 和行列式detA 。
矩阵A 为非奇异对称矩阵,可知,||)(min max2λλ=A cond(1-1)其中m ax λ为按模最大特征值,min λ为按模最小特征值。
detA 可由LU 分解得到。
因LU 均为三角阵,那么其主对角线乘积即为A 的行列式。
二 算法实现1 幂法使用如下迭代格式:⎪⎪⎩⎪⎪⎨⎧⋅===⋅⋅⋅=------||max |)|sgn(max ||max /),,(111111)0()0(10k k k k k k k k Tn u u Ay u u u y u u u β任取非零向量 (2-1)终止迭代的控制理论使用εβββ≤--||/||1k k k , 实际使用εβββ≤--||/||||||1k k k(2-2)由于不保存A 矩阵中的零元素,只保存主对角元素a[501]及b,c 值。
北航数值分析计算实习第一题编程
i − t + s +1,t t − k + s +1, k t = max(1,i − r ,k − s )
∑c
c
) / cs +1, k
[i = k + 1, k + 2,⋯ , min( k + r , n); k < n]
(2) 求解 Ly = b,Ux = y (数组 b 先是存放原方程右端向量,后来存放中间向量 y)
0 b a2
b c
c b a3 b c
⋯ ⋯ ⋯ ⋯ ⋯
c b a499 b c
c b a500 b 0
c ⎤ b ⎥ ⎥ a501 ⎥ ⎥ 0 ⎥ 0 ⎥ ⎦
在数组 C 中检索矩阵 A 的带内元素 aij 的方法是: A 的带内元素 aij =C 中的元素 ci − j + s +1, j
2
数值分析计算实习题目一
i −1
bi := bi −
பைடு நூலகம்
i − t + s +1,t t t = max(1,i − r )
∑c
b
(i = 2,3,⋯ , n)
xn := bn / cs +1, n
min( i + s )
xi := (bi −
t = i +1
∑c
i −t + s +1,t t
x ) / cs +1,i
(i = n − 1, n − 2,⋯ ,1)
3、Doolittle 分解求解 n 元带状线性方程组(doolittle()函数)
按照上述对带状矩阵 A 的存储方法和元素 aij 的检索方法,并且把三角分解的结果 ukj 和 lik 分 别存放在 akj 和 aik 原先的存储单元内,那么用 Doolittle 分解法求解 n 元带状线性方程组的算法 可重新表述如下(其中“:=”表示赋值) : (1) 作分解 A = LU 。 对于 k=1,2, ……,n 执行
数值分析第一次大作业
《数值分析》计算实习报告第一题院系:机械工程及自动化学院_学号: _____姓名: _ ______2017年11月7日一、算法设计方案1、求λ1,λ501和λs 的值1)利用幂法计算出矩阵A 按模最大的特征值,设其为λm 。
2)令矩阵B =A −λm I (I 为单位矩阵),同样利用幂法计算出矩阵B 按模最大的特征值λm ′。
3)令λm ′′=λm ′+λm 。
由计算过程可知λm 和λm ′′分别为矩阵A 所有特征值按大小排序后,序列两端的值。
即,λ1=min{λm ,λm ′′},λ501=max{λm ,λm ′′}。
4) 利用反幂法计算λs 。
其中,反幂法每迭代一次都要求解线性方程组1k k Au y -=,由于矩阵A 为带状矩阵,故可用三角分解法解带状线性方程组的方法求解得到k u 。
2、求A 的与数μk =λ1+k λ501−λ140最接近的特征值λi k (k =1,2, (39)1) 令矩阵D k =A −μk I ,利用反幂法计算出矩阵D k 按模最小的特征值λi k ′,则λi k =λi k ′+μk 。
3、求A 的(谱范数)条件数cond(A )2和行列式det A1) cond(A)2=|λm λs |,前文已算出m λ和s λ,直接带入即可。
2) 反幂法计算λs 时,已经对矩阵A 进行过Doolittle 分解,得到A=LU 。
而L 为对角线上元素全为1的下三角矩阵,U 为上三角矩阵,可知det 1L =,5011det ii i U u ==∏,即有5011det det det ii i A L U u ====∏。
最后,为节省存储量,需对矩阵A 进行压缩,将A 中带内元素存储为数组C [5][501]。
二、源程序代码#include<windows.h>#include<iostream>#include<iomanip>#include<math.h>using namespace std;#define N 501#define K 39#define r 2#define s 2#define EPSI 1.0e-12//求两个整数中的最大值int int_max2(int a, int b){return(a>b ? a : b);}//求两个整数中的最小值int int_min2(int a, int b){return(a<b ? a : b);}//求三个整数中的最大值int int_max3(int a, int b, int c){int t;if (a>b)t = a;else t = b;if (t<c) t = c;return(t);}//定义向量内积double dianji(double x[], double y[]) {double sum = 0;for (int i = 0; i<N; i++)sum = sum + x[i] * y[i];return(sum);}//计算两个数之间的相对误差double erro(double lamd0, double lamd1){double e, d, l;e = fabs(lamd1 - lamd0);d = fabs(lamd1);l = e / d;return(l);}//矩阵A的压缩存储初始化成Cvoid init_c(double c[][N]){int i, j;for (i = 0; i<r + s + 1; i++)for (j = 0; j<N; j++)if (i == 0 || i == 4)c[i][j] = -0.064;else if (i == 1 || i == 3)c[i][j] = 0.16;elsec[i][j] = (1.64 - 0.024*(j + 1))*sin(0.2*(j + 1)) - 0.64*exp(0.1 / (j + 1)); }//矩阵复制void fuzhi_c(double c_const[][N], double c[][N]){int i, j;for (i = 0; i<r + s + 1; i++)for (j = 0; j<N; j++)c[i][j] = c_const[i][j];}//LU三角分解void LUDet_c(double c_const[][N], double c_LU[][N]){double sum;int k, i, j;fuzhi_c(c_const, c_LU);for (k = 1; k <= N; k++){for (j = k; j <= int_min2(k + s, N); j++){sum = 0;for (i = int_max3(1, k - r, j - s); i <= k - 1; i++)sum += c_LU[k - i + s][i - 1] * c_LU[i - j + s][j - 1];c_LU[k - j + s][j - 1] -= sum;}for (j = k + 1; j <= int_min2(k + r, N); j++){sum = 0;for (i = int_max3(1, j - r, k - s); i <= k - 1; i++)sum += c_LU[j - i + s][i - 1] * c_LU[i - k + s][k - 1];c_LU[j - k + s][k - 1] = (c_LU[j - k + s][k - 1] - sum) / c_LU[s][k - 1];}}}//三角分解法解带状线性方程组void jiefc(double c_const[][N], double b_const[], double x[]){int i, j;double b[N], c_LU[r + s + 1][N], sum;for (i = 0; i<N; i++)b[i] = b_const[i];LUDet_c(c_const, c_LU);for (i = 2; i <= N; i++){sum = 0;for (j = int_max2(i - 2, 1); j <= i - 1; j++)sum += c_LU[i - j + 2][j - 1] * b[j - 1];b[i - 1] -= sum;}x[N - 1] = b[N - 1] / c_LU[2][N - 1];for (i = N - 1; i >= 1; i--){sum = 0;for (j = i + 1; j <= int_min2(i + 2, N); j++)sum += c_LU[i - j + 2][j - 1] * x[j - 1];x[i - 1] = (b[i - 1] - sum) / c_LU[2][i - 1];}}//幂法求按模最大特征值double mifa_c(double c_const[][N]){double u[N], y[N];double sum, length_u, beta0, beta1;int i, j;for (i = 0; i<N; i++)//迭代初始向量u[i] = 0.5;length_u = sqrt(dianji(u, u));for (i = 0; i<N; i++)y[i] = u[i] / length_u;for (i = 1; i <= N; i++){sum = 0;for (j = int_max2(i - 2, 1); j <= int_min2(i + 2, N); j++)sum = sum + c_const[i - j + 2][j - 1] * y[j - 1];u[i - 1] = sum;}beta1 = dianji(u, y);do{beta0 = beta1;length_u = sqrt(dianji(u, u));for (i = 0; i<N; i++)y[i] = u[i] / length_u;for (i = 1; i <= N; i++){sum = 0;for (j = int_max2(i - 2, 1); j <= int_min2(i + 2, N); j++)sum = sum + c_const[i - j + 2][j - 1] * y[j - 1];u[i - 1] = sum;}beta1 = dianji(u, y);} while (erro(beta0, beta1) >= EPSI);return(beta1);}//反幂法求按模最小特征值double fmifa_c(double c_const[][N]){double u[N], y[N];double length_u, beta0, beta1;int i;for (i = 0; i<N; i++)//迭代初始向量u[i] = 0.5;length_u = sqrt(dianji(u, u));for (i = 0; i<N; i++)y[i] = u[i] / length_u;jiefc(c_const, y, u);beta1 = dianji(y, u);do{beta0 = beta1;length_u = sqrt(dianji(u, u));for (i = 0; i<N; i++)y[i] = u[i] / length_u;jiefc(c_const, y, u);beta1 = dianji(y, u);} while (erro(beta0, beta1) >= EPSI);beta1 = 1 / beta1;return(beta1);}//计算lamd_1、lamd_501、lamd_svoid calculate1(double c_const[][N], double &lamd_1, double &lamd_501, double &lamd_s) {int i;double lamd_mifa0, lamd_mifa1, c[r + s + 1][N];lamd_mifa0 = mifa_c(c_const);fuzhi_c(c_const, c);for (i = 0; i<N; i++)c[2][i] = c[2][i] - lamd_mifa0;lamd_mifa1 = mifa_c(c) + lamd_mifa0;if (lamd_mifa0<lamd_mifa1){lamd_1 = lamd_mifa0;lamd_501 = lamd_mifa1;}else{lamd_501 = lamd_mifa0;lamd_1 = lamd_mifa1;}lamd_s = fmifa_c(c_const);}//平移+反幂法求最接近u_k的特征值void calculate2(double c_const[][N], double lamd_1, double lamd_501, double lamd_k[]){int i, k;double c[r + s + 1][N], h, temp;temp = (lamd_501 - lamd_1) / 40;for (k = 1; k <= K; k++){h = lamd_1 + k*temp;fuzhi_c(c_const, c);for (i = 0; i<N; i++)c[2][i] = c[2][i] - h;lamd_k[k - 1] = fmifa_c(c) + h;}}//计算cond(A)和det(A)void calculate3(double c_const[][N], double lamd_1, double lamd_501, double lamd_s, double &cond_A, double &det_A){int i;double c_LU[r + s + 1][N];if (fabs(lamd_1)>fabs(lamd_501))cond_A = fabs(lamd_1 / lamd_s);elsecond_A = fabs(lamd_501 / lamd_s);LUDet_c(c_const, c_LU);det_A = 1;for (i = 0; i<N; i++)det_A *= c_LU[2][i];}//*主程序*//int main(){int i, count = 0;double c_const[5][N], lamd_k[K];double lamd_1, lamd_501, lamd_s;double cond_A, det_A;//设置白背景黑字system("Color f0");//矩阵A压缩存储到c[5][501]init_c(c_const);cout << setiosflags(ios::scientific) << setiosflags(ios::right) << setprecision(12) << endl;//计算lamd_1、lamd_501、lamd_scalculate1(c_const, lamd_1, lamd_501, lamd_s);cout << " 矩阵A的最小特征值:λ1 = " << setw(20) << lamd_1 << endl;cout << " 矩阵A的最大特征值:λ501 = " << setw(20) << lamd_501 << endl;cout << " 矩阵A的按模最小的特征值:λs = " << setw(20) << lamd_s << endl;//求最接近u_k的特征值calculate2(c_const, lamd_1, lamd_501, lamd_k);cout << endl << " 与数u_k最接近的特征值:" << endl;for (i = 0; i<K; i++){cout << " λ_ik_" << setw(2) << i + 1 << " = " << setw(20) << lamd_k[i] << " ";count++;if (count == 2){cout << endl;count = 0;}}//计算cond_A和det_Acalculate3(c_const, lamd_1, lamd_501, lamd_s, cond_A, det_A);cout << endl << endl;cout << " 矩阵A的条件数:cond(A) = " << setw(20) << cond_A << endl;cout << " 矩阵A的行列式的值:det(A) = " << setw(20) << det_A << endl << endl;return 0;}三,计算结果四,分析初始向量选择对计算结果的影响当选取初始向量0(1,1,,1)Tu=时,计算的结果如下:此结果即为上文中的正确计算结果。
北航《数值分析》习题
北航《数值分析》习题习题一1. 下列各数都是经过四舍五入得到的近似数,试指出它们有几位有效数字以及它们的绝对误差限、相对误差限。
(1);(2);(3);(4);(5);(6);(7);1. (1)5,,;(2)2,,;(3)4,,;(4)5,,;(5)1,,;(6)2,,;(7)6,,2. 为使下列各数的近似值的相对误差限不超过,问各近似值分别应取几位有效数字?2. ;;3. 设均为第1题所给数据,估计下列各近似数的误差限。
(1);(2);(3)3. (1);(2);(3)4. 计算,取,利用下列等价表达式计算,哪一个的结果最好?为什么?(1);(2);(3)(4)4. 第(3)个结果最好。
5. 序列满足递推关系式若(三位有效数字),计算时误差有多大?这个计算过程稳定吗?5. 不稳定。
从计算到时,误差约为6. 求方程的两个根,使其至少具有四位有效数字(要求利用。
6. ,7. 某生产部门生产的一件产品需用七个零件,而这七个零件的质量取决于零件参数的标定值,它们的参数允许有一定的误差:若每一零件的标定值取做区间中点,在生产过程中每一零件的参数都有可能产生误差。
由此将零件分成不同的等级:A,B,C三等,等级由标定值的相对误差限表示,A等为1%,B等为5%,C等为10%。
试确定三个等级的零件分别满足的区间。
8. 将一个八位二进制数(10111101)2转换成十进制数时,可以用公式:(1)用多项式求值的秦九韶方法求C的值;(2)写出将任意一个八位二进制数(b1b2b3b4b5b6b7b8)2转化为十进制数的算法。
9. 利用等式变换使下列表达式的计算结果比较精确。
(1);(2)(3);(4)9. (1);(2);(3);(4)10. 设,求证:(1)(2)利用(1)中的公式正向递推计算时误差增大;反向递推时误差函数减小。
习题二1. 判断下列方程有几个实根,并求出其隔根区间。
(1);(2)(3);(4)1. (1),,;(2);(3),,;(4)为根。
北航数值分析大作业第一题
1 算法方案 1.1 λ1,λ501,λs 的计算
(1) (2) (3) (4) (5) 将矩阵 A[501][501]以压缩存储后的形式 C[5][501]输入 使用一次幂法得到按模最大的特征值 矩阵向左平移 λm 距离(A-λmI) ,再使用一次幂法得到按模最大的特征值 s,则 λm1=s-λm1 比较 λm1 和 λm2 的大小与正负,得到 λ 和 λ501 对 A 使用一次反幂法得到按模最小的特征值 λs
while (e>=pow(10,-12)); return 1/be;//返回 1/be2 作为矩阵 m[5][501]的按模最小向量 } //333333333333333333333333333333333333333333333333333333333333333333333333 33333333333333333333333333333333333333333333333333333333333333333333333 double det(double c[1+r+s][q]) { int max3(int a,int b,int c); int fmax2(int a,int b); int fmin2(int a,int b); int i,j,k,t; double sum,det=1; for(k=1;k<=q;k++) { for(j=k;j<=fmin2(k+s,q);j++)//求 ukj { sum=0; for(t=max3(1,k-r,j-s);t<=k-1;t++) { sum=sum+c[k-t+s][t-1]*c[t-j+s][j-1]; } c[k-j+s][j-1]=c[k-j+s][j-1]-sum; }
北航数值分析第一次大作业
b2[i-1]=b[i-1]-sum3; } x[n-1]=b2[n-1]/C[s][n-1]; for(i=n-1;i>=1;i--) { double sum4=0; for(int t=i+1;t<=min(i+s,n);t++) { sum4+=C[i-t+s][t-1]*x[t-1]; } x[i-1]=(b2[i-1]-sum4)/C[s][i-1]; } } /*反幂法*/ double FMF(double C[m][n]) { LU(C); for(int k=1;k<=n;k++) u[k-1]=1; /*为迭代初始向量赋值*/ beta1=beta2=0; do { ent=0; for(int i=1;i<=n;i++) ent+=u[i-1]*u[i-1]; ent=sqrt(ent); for(i=1;i<=n;i++) y[i-1]=u[i-1]/ent; HD(C,y,u); beta1=beta2; beta2=0; for(i=1;i<=n;i++) { beta2+=y[i-1]*u[i-1]; } }while(fabs(1/beta2-1/beta1)/fabs(1/beta2)>1.0e-12); return 1/beta2; } /*求 detA*/ double det(double C[m][n]) { LU(C); double detA=1; for(int j=1;j<=n;j++)
数值分析第一次作业
姓名:吴少波 学号:SY1105513
一、算法的设计方案 1.将带状矩阵 A 压缩为矩阵 C 存储。先用幂法算出 A 按模最大的特征值,记为 maxLambda, 再 将 其 平 移 ,用 带 原点 平 移 的 幂 法求 A-maxLambdaI 按模 最 大的 特 征 值 , 记为 p1 , 记 p2=p1+maxLambda,比较 maxLambda 和 p2 的大小,大的为λ 501,小的为λ 1。 用反幂法求解λ s 时,其中需解方程 Auk=yk-1,先把矩阵 A LU 分解(不列主元) ,再在每次循环 迭代时回代求解。 2.将 A 平移μ k(k=1,2,…,39)个单位,用带原点平移的反幂法求与μ k(k=1,2,…,39) 最接近的 39 个特征值。 3.cond(A)2=│maxLambda / λ s│ A 的行列式等于把 A LU 分解后 A 所有对角线上元素的乘积。 二、源程序(VC6.0 环境下的 C 语言) #include<stdio.h> #include<stdlib.h> #include<math.h> #include<malloc.h> #define m 5 #define n 501 #define r 2 #define s 2 double C[m][n]; double u[n]; double y[n]; double ent,beta1,beta2; void YS(); /*将带状矩阵 A 压缩为 C*/ int max(int a,int b); /*两数求较大的一个*/ int min(int a,int b); /*两数求较小的一个*/ double MF(double C[m][n]); /*幂法*/ double FMF(double C[m][n]); /*反幂法*/ void LU(double C[m][n]); /*LU 分解*/ void HD(double C[m][n],double b[n],double x[n]); /*回代过程*/ double det(double C[m][n]); /*求 detA*/ double Move_MF(double C[m][n],double maxLambda); /*带原点平移的幂法*/ double Move_FMF(double C[m][n],double p); /*带原点平移的反幂法*/ /**主函数**/ void main() { /*定义变量*/ double maxLambda=0,minLambda=0,condA,detA,Lambda1,Lambda501,p1,p2,Mu_k,Lambdaik; /*算第一题*/
北航数分大作业一
《数值分析》计算实习题第一题姓名:学号:一、 算法的设计方案 ⒈矩阵A 的存储由于A[501][501]是带状矩阵,并且阶数远大于带宽5,为节省内存空间,设置一个二维数组C[5][501]用于存放A 的带内元素。
A 中元素与C 数组中元素的对应关系,即A 的检索方式为: A 的元素ij a =C 中的元素1,i j s j C -++ 2.求解特征值λ1,λ501,λs①由于λ1‹λ2‹…‹λ501,所以在以所有特征值建立的数轴上,λ1、λ50⒊1位于数轴的两端,两者之一必为按模最大。
利用幂法,可以求出来按模最大的特征值λM ,即为λ1和λ501中一个;然后将原矩阵平移λM,再利用幂法求一次平移后矩阵的按模最大的特征值λM ′。
比较λM 和λM+λM ′大小,大者为λ501,小的为λ1。
②利用反幂法,求矩阵A 的按模最小的特征值λs 。
但是反幂法中要用到线性方程组的求解,而原矩阵A 又是带状矩阵,采用LU 分解。
所以在这之前要定义一个LU 分解子程序,将A 矩阵分解为单位下三角矩阵L 和上三角矩阵U 的乘积。
⒊求解A 的与数μk =λ1+k (λ501-λ1)/40的最接近的特征值λik(k=1,2,…,39)。
先使k 从1到39循环,求出μk 的值,然后使用带原点平移的反幂法,令平移量p=μk 。
计算过程需调用LU 分解子程序对A-u k I 矩阵进行LU 分解。
最终反幂法求出的值加上μk 即为与μk 最接近的特征值λik4.求解A的(谱范数)条件数cond(A)2和行列式detAcond(A)2=|λ1/λn|,其中λ1和λn分别是矩阵A的模最大和最小特征值,上边已经求出,可直接调用。
detA等于对A记性LU分解以后U的所有对角线上元素的乘积。
二、全部源程序#include<stdio.h>#include <math.h>/***全局变量、函数申明***/#define N 501#define EMS 1.0e-12double U[N],Y[N];double c[5][N] ;double fuzhi(); /*对A进行压缩存储*/ void DLU(double C[5][N]); /*对矩阵A进行LU分解*/ double pingyi(double C[5][N],double b); /*求矩阵的平移矩阵*/ double mifa(double c[5][N]); /*幂法计算矩阵A按模最大的特征值*/ double fmifa(double c[5][N],double b); /*反幂法求矩阵A按模最小的特征值*/void main(){double lamuda_m1,lamuda_m2,lamuda_max,lamuda_min,lamuda_sum,lamuda_s;fuzhi();lamuda_m1=mifa(c);pingyi(c, lamuda_m1);lamuda_m2 =mifa(c);lamuda_sum= lamuda_m1+ lamuda_m2;if (lamuda_m1>lamuda_sum){lamuda_max=lamuda_m1;lamuda_min=lamuda_sum;}else{lamuda_max=lamuda_sum;lamuda_min=lamuda_m1;}printf("矩阵的最大特征值为:\n lamuda_501=%.11e\n",lamuda_max); printf("矩阵的最小特征值为:\n lamuda_1=%.11e\n",lamuda_min); int i;double conda,u[39];for(i=1;i<40;i++)u[i]=lamuda_min+(lamuda_max-lamuda_min)*i/40;lamuda_s=fmifa(c,0);printf("矩阵的按模最小特征值为:\n lamuda_s=%.11e\n", lamuda_s); printf("与uk最接近的特征值如下:\n");/*求与uk接近的特征值*/for(i=1;i<40;i++)printf("u[%2d]=%.11e 与其最接近的特征值为lamuda_%2d=%.11e\n",i,u[i],i,fmifa(c,u[i]));/*求矩阵A的条件数*/conda=fabs(lamuda_m1/lamuda_s);printf("矩阵A的(谱范数)条件数为:\n cond(A)=%.11e\n", conda); /*求矩阵A的行列式*/fuzhi();double detA=1.0;DLU(c);for(i=0;i<N;i++)detA*=c[2][i];printf("矩阵A的行列式为:\n detA=%.11e\n", detA);}/*建立矩阵A的压缩存储二维数组,并对其赋值*/double fuzhi(){int i;c[0][0]=0;c[0][1]=0;c[1][0]=0;c[3][500]=0;c[4][499]=0;c[4][500]=0;for(i=2;i<N;i++)c[0][i]=-0.064;for(i=1;i<N;i++)c[1][i]=0.16;for(i=1;i<N+1;i++)c[2][i-1]=(1.64-0.024*i)*sin(0.2*i)-0.64*exp(0.1/i); for(i=0;i<N-1;i++)c[3][i]=0.16;for(i=0;i<N-2;i++)c[4][i]=-0.064;return (c[5][N]);}/*求最大值*/int max(int a,int b){if(a>b) return a;else return b;}/*求最小值*/int min(int a,int b){if(a<b) return a;else return b;}/*向量乘以向量*/double xiangliangji(double G[N],double H[N]) {int i;double sum;sum=0;for(i=0;i<N;i++)sum+=G[i]*H[i];return sum;}/*向量除数*/void xlcs (double G[N],double yita){int i;for(i=0;i<N;i++)Y[i]=G[i]/yita;}/*矩阵乘向量*/void juchengxiang(double c[N][N],double G[N])int i,j;double m;for(i=0;i<N;i++)U[i]=0;for(i=0;i<N;i++){m=max(0,i-2);for(j=min(i+2,N-1);j>=m;j--)U[i]+=c[i+2-j][j]*G[j];}}/*矩阵的主对角线元素平移*/ double pingyi(double C[5][N],double b) {int i;for(i=0;i<N;i++)C[2][i]=C[2][i]-b;return C[5][N];}/*幂法求按模最大特征值*/double mifa(double c[5][N])int i,q;double sum,yita,beita,beita1,cancha; beita=0;for(i=0;i<N;i++)U[i]=1;for (q=1;;q++){beita1=beita;sum= xiangliangji(U,U);yita=sqrt(sum);xlcs (U,yita);juchengxiang (c,Y);beita=xiangliangji(Y,U);cancha=fabs((beita1-beita)/beita); if (cancha<EMS) break;}return beita;}/*矩阵的Doolittle分解*/void DLU(double C[5][N]){ int k,i,j,t;int m,l;for(k=0;k<N;k++){m=min(k+2,N-1);for(j=k;j<=m;j++){double sum=0;l=max(max(0,k-2),j-2);for(t=l;t<=k-1;t++)sum+=C[k-t+2][t]*C[t-j+2][j];C[k-j+2][j]=C[k-j+2][j]-sum;}if(k<N-1){m=min(k+2,N-1);for(i=k+1;i<=m;i++){double sum=0;l=max(max(0,i-2),k-2);for(t=l;t<=k-1;t++)sum+=C[i-t+2][t]*C[t-k+2][k];C[i-k+2][k]=(C[i-k+2][k]-sum)/C[2][k];}}}}/*反幂法求按模最小特征值*/double fmifa(double c[5][N],double b){int i,q;int m,t,p;double sum,yita,beita,beita1,cancha,lamuda;double G[N];beita=0;for(i=0;i<N;i++) /*设置初始向量U0*/{U[i]=1;}for (q=1;;q++){beita1=beita;sum=xiangliangji (U,U);yita=sqrt(sum);xlcs (U,yita);fuzhi();pingyi(c,b);DLU(c);for(i=0;i<N;i++)G[i]=Y[i];for(i=1;i<N;i++){double sum=0;m=max(0,i-2);for(t=m;t<=i-1;t++)sum+=c[i-t+2][t]*G[t];G[i]=G[i]-sum;}U[N-1]=G[N-1]/c[2][N-1]; for(i=N-2;i>=0;i--){double sum=0;p=min(i+2,N-1);for(t=i+1;t<=p;t++)sum+=c[i-t+2][t]*U[t];U[i]=(G[i]-sum)/c[2][i]; }beita=xiangliangji(Y,U);lamuda=1/beita+b;cancha=fabs((beita1-beita)/beita);if (cancha<1.0e-12) break;}printf("迭代次数%d\n",q);return lamuda;}三、计算结果矩阵的最大特征值为:lamuda_501=9.72463409878e+000矩阵的最小特征值为:lamuda_1=-1.07001136150e+001迭代次数70, 矩阵的按模最小特征值为:lamuda_s=-5.55791079423e-003与uk最接近的特征值如下:迭代次数7, u[ 1]=-1.01894949222e+001lamuda_1=-1.01829340331e+001 迭代次数226, u[ 2]=-9.67887622933e+000lamuda_ 2=-9.58570742507e+000迭代次数7, u[ 3]=-9.16825753648e+000lamuda_ 3=-9.17267242393e+000迭代次数8, u[ 4]=-8.65763884364e+000lamuda_ 4=-8.65228400790e+000迭代次数118, u[ 5]=-8.14702015079e+000lamuda_ 5=-8.0934*******e+000迭代次数16, u[ 6]=-7.63640145795e+000lamuda_ 6=-7.65940540769e+000迭代次数15, u[ 7]=-7.12578276510e+000lamuda_ 7=-7.11968464869e+000迭代次数19, u[ 8]=-6.61516407226e+000lamuda_ 8=-6.61176433940e+000迭代次数28, u[ 9]=-6.10454537941e+000lamuda_ 9=-6.0661*******e+000迭代次数21, u[10]=-5.59392668657e+000lamuda_10=-5.58510105263e+000lamuda_11=-5.11408352981e+000迭代次数13, u[12]=-4.57268930088e+000 lamuda_12=-4.57887217687e+000迭代次数290, u[13]=-4.06207060803e+000 lamuda_13=-4.09647092626e+000迭代次数13, u[14]=-3.55145191519e+000 lamuda_14=-3.55421121575e+000迭代次数6, u[15]=-3.04083322234e+000 lamuda_15=-3.0410*******e+000迭代次数1606, u[16]=-2.53021452950e+000 lamuda_16=-2.53397031113e+000迭代次数72, u[17]=-2.01959583665e+000 lamuda_17=-2.00323076956e+000迭代次数19, u[18]=-1.50897714381e+000 lamuda_18=-1.50355761123e+000迭代次数17, u[19]=-9.98358450965e-001 lamuda_19=-9.93558606008e-001迭代次数11, u[20]=-4.87739758120e-001 lamuda_20=-4.87042673885e-001迭代次数10, u[21]=2.28789347246e-002 lamuda_21=2.23173624957e-002迭代次数13, u[22]=5.33497627570e-001 lamuda_22=5.32417474207e-001迭代次数15, u[23]=1.04411632041e+000 lamuda_23=1.05289896269e+000迭代次数29, u[24]=1.55473501326e+000 lamuda_24=1.58944588188e+000迭代次数81, u[25]=2.06535370610e+000 lamuda_25=2.06033046027e+000迭代次数40, u[26]=2.57597239895e+000 lamuda_26=2.55807559707e+000迭代次数13, u[27]=3.08659109179e+000 lamuda_27=3.08024050931e+000迭代次数23, u[28]=3.59720978464e+000 lamuda_28=3.61362086769e+000迭代次数16, u[29]=4.10782847748e+000 lamuda_29=4.0913*******e+000迭代次数23, u[30]=4.61844717033e+000 lamuda_30=4.60303537828e+000迭代次数12, u[31]=5.12906586317e+000 lamuda_31=5.132********e+000迭代次数30, u[32]=5.63968455602e+000 lamuda_32=5.59490634808e+000lamuda_33=6.08093385703e+000迭代次数18, u[34]=6.66092194171e+000lamuda_34=6.68035409211e+000迭代次数74, u[35]=7.17154063455e+000lamuda_35=7.29387744813e+000迭代次数30, u[36]=7.68215932740e+000lamuda_36=7.71711171424e+000迭代次数11, u[37]=8.19277802024e+000lamuda_37=8.22522001405e+000迭代次数38, u[38]=8.70339671309e+000lamuda_38=8.64866606519e+000迭代次数10, u[39]=9.21401540593e+000lamuda_39=9.25420034458e+000矩阵A的(谱范数)条件数为:cond(A)=1.92520427390e+003矩阵A的行列式为:detA=2.77278614175e+118四、讨论迭代初始向量的选取对于计算结果的影响:1.影响迭代速度。
北航数值分析第一次大作业
一、算法的设计方案:(一)各所求值得计算方法1、最大特征值λ501,最小特征值λ1,按模最小特征值λs的计算方法首先使用一次幂法运算可以得到矩阵的按模最大的特征值λ,λ必为矩阵A的最大或最小特征值,先不做判断。
对原矩阵A进行一次移项,即(A-λI),在进行一次幂法运算,可以得到另一个按模最大特征值λ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 2double 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;} //新的u0temp=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分解后,求解线性方程组得到迭代向量u k,即程序中的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,结果也不变化。
北航数值分析作业第一题
数值分析作业第一题一、 算法设计方案利用带状Dollittle 分解,将A[501][501]转存到数组C[5][501],以节省存储空间1、计算λ1和λ501首先使用幂法求出矩阵的按模最大的特征值λ0:如果λ0>0,则其必为按模最大值,因此λ501=λ0,然后采用原点平移法,平移量为λ501,使用幂法迭代求出矩阵A -λ501I 的按模最大的特征值,其特征值按从小到大排列应为λ1-λ501、λ2-λ501、……、0。
因此A-λ501I 的按模最大的特征值应为λ1-λ501。
又因为λ501的值已求得,由此可直接求出λ1。
2、计算λSλS 为矩阵A 按模最小的特征值,可以通过反幂法直接求出。
3、计算λikλik 是对矩阵A 进行λik 平移后,再用反幂法求出按模最小的特征值λmin ,λik =λik +λmin 。
4、计算矩阵A 的条件数计算cond (A )2和行列式det(A)矩阵A 的条件数为n12cond λλ)( A ,其中λ1和λn 分别是矩阵A 的模最大和最小特征值,直接利用上面求得的结果直接计算。
矩阵A 的行列式可先对矩阵A 进行LU 分解后,det(A)等于U 所有对角线上元素的乘积。
二、源程序:#include<math.h>#include<stdio.h>#include<stdlib.h>#include<iostream.h>#define s 2#define r 2int Max(int v1,int v2);int Min(int v1,int v2);int maxt(int v1,int v2,int v3);void storage(double C[5][501],double b,double c);double mifa(double C[5][501]);void LU(double C[5][501]);double fmifa(double C[5][501]);int Max(int v1,int v2) //求两个数的最大值{ return((v1>v2)?v1:v2);}int Min(int v1,int v2) //求两个数最小值{ return ((v1<v2)?v1:v2);}int maxt(int v1,int v2,int v3) //求三个数最大值{ int t;if(v1>v2) t=v1;else t=v2;if(t<v3) t=v3;return(t);}/***将矩阵值转存在一个数组里,以节省存储空间***/void storage(double C[5][501],double b,double c){ int i=0,j=0;C[i][j]=0,C[i][j+1]=0;for(j=2;j<=500;j++)C[i][j]=c;i++;j=0;C[i][j]=0;for(j=1;j<=500;j++)C[i][j]=b;i++;for(j=0;j<=500;j++)C[i][j]=(1.64-0.024*(j+1))*sin(0.2*(j+1))-0.64*exp(0.1/(j+1));i++;for(j=0;j<=499;j++)C[i][j]=b;C[i][j]=0;i++;for(j=0;j<=498;j++)C[i][j]=c;C[i][j]=0,C[i][j+1]=0;}//用于求解最大的特征值,幂法double mifa(double C[5][501]){ int m=0,i,j;double b2,b1=0,sum;double u[501],y[501];for (i=0;i<501;i++){ u[i] = 1.0;}do{ sum=0;if(m!=0)b1=b2;m++;for(i=0;i<=500;i++)sum+=u[i]*u[i];for(i=0;i<=500;i++)y[i]=u[i]/sqrt(sum);for(i=0;i<=500;i++){ u[i]=0;for(j=Max(i-r,0);j<=Min(i+s,500);j++)u[i]=u[i]+C[i-j+s][j]*y[j];}b2=0;for(i=0;i<=500;i++)b2=b2+y[i]*u[i];}while(fabs(b2-b1)/fabs(b2)>=1.0e-12);return b2;}/*****行列式LU分解*****/void LU(double C[5][501]){ double sum;int k,i,j;for(k=1;k<=501;k++){ for(j=k;j<=Min(k+s,501);j++){ sum=0;for(i=maxt(1,k-r,j-s);i<=k-1;i++)sum+=C[k-i+s][i-1]*C[i-j+s][j-1];C[k-j+s][j-1]-=sum;}for(j=k+1;j<=Min(k+r,501);j++){ sum=0;for(i=maxt(1,j-r,k-s);i<=k-1;i++)sum+=C[j-i+s][i-1]*C[i-k+s][k-1];C[j-k+s][k-1]=(C[j-k+s][k-1]-sum)/C[s][k-1];}}}/***带状DOOLITE分解,并且求解出方程组的解***/void solve(double C[5][501],double x[501],double b[501]){ int i,j,k,t;double B[5][501],c[501];for(i=0;i<=4;i++){ for(j=0;j<=500;j++)B[i][j]=C[i][j];}for(i=0;i<=500;i++)c[i]=b[i];for(k=0;k<=500;k++){ for(j=k;j<=Min(k+s,500);j++){ for(t=Max(0,Max(k-r,j-s));t<=k-1;t++)B[k-j+s][j]=B[k-j+s][j]-B[k-t+s][t]*B[t-j+s][j];}for(i=k+1;i<=Min(k+r,500);i++){ for(t=Max(0,Max(i-r,k-s));t<=k-1;t++)B[i-k+s][k]=B[i-k+s][k]-B[i-t+s][t]*B[t-k+s][k];B[i-k+s][k]=B[i-k+s][k]/B[s][k];}}for(i=1;i<=500;i++)for(t=Max(0,i-r);t<=i-1;t++)c[i]=c[i]-B[i-t+s][t]*c[t];x[500]=c[500]/B[s][500];for(i=499;i>=0;i--){ x[i]=c[i];for(t=i+1;t<=Min(i+s,500);t++)x[i]=x[i]-B[i-t+s][t]*x[t];x[i]=x[i]/B[s][i];}}//用于求解模最大的特征值,反幂法double fmifa(double C[5][501]){ int m=0,i;double b2,b1=0,sum=0,u[501],y[501];for (i=0;i<=500;i++){ [i] = 1.0;}do{ if(m!=0)b1=b2;m++;sum=0;for(i=0;i<=500;i++)sum+=u[i]*u[i];for(i=0;i<=500;i++)y[i]=u[i]/sqrt(sum);solve(C,u,y);b2=0;for(i=0;i<=500;i++)b2+=y[i]*u[i];}while(fabs(b2-b1)/fabs(b2)>=1.0e-12);return 1/b2;}/***主程序***/void main(){ double b=0.16,c=-0.064,det=1.0;int i;double C[5][501],cond;storage(C,b,c); //进行C的赋值cout.precision(12); //定义输出精度double k1=mifa(C); //利用幂法计算矩阵的最大特征值和最小特征值if(k1<0)printf("λ1=%.12e\n",k1);else if(k1>=0)printf("λ501=%.12e\n",k1);for(i=0;i<501;i++)C[2][i]=C[2][i]-k1;double k2=mifa(C)+k1;if(k2<0)printf("λ1=%.12e\n",k2);else if(k2>=0)printf("λ501=%.12e\n",k2);storage(C,b,c);double k3=fmifa(C); //利用反幂法计算矩阵A的按模最小特征值printf("λs=%.12e\n",k3);storage(C,b,c); //计算最接近特征值double u[39]={0};for(i=0;i<39;i++){ u[i]=k1+(i+1)*(k2-k1)/40;C[2][i]=C[2][i]-u[i];u[i]=fmifa(C)+u[i];printf("与数u%d 最接近的特征值λ%d: %.12e\n",i+1,i+1,u[i]);}if(k1>0) //计算矩阵A的条件数,取2范数cond=fabs(k1/k3);else if(k1<0)cond=fabs(k2/k3);storage(C,b,c);LU(C); //利用LU分解计算矩阵A的行列式for(i=0;i<501;i++)det*=C[2][i];printf("\ncond(A)=%.12e\n",cond);printf("\ndet(A)=%.12e\n",det);}三、计算结果:四、结果分析迭代初始向量的选择对果有一定的影响,选择不同的初始向量可能会得到不同阶的特征值。
北航硕士研究生数值分析大作业一
数值分析—计算实习作业一学院:17系专业:精密仪器及机械姓名:张大军学号:DY14171142014-11-11数值分析计算实现第一题报告一、算法方案算法方案如图1所示。
(此算法设计实现完全由本人独立完成)图1算法方案流程图二、全部源程序全部源程序如下所示#include <iostream.h>#include <iomanip.h>#include <math.h>int main(){double a[501];double vv[5][501];double d=0;double r[3];double uu;int i,k;double mifayunsuan(double *a,double weiyi);double fanmifayunsuan(double *a,double weiyi);void yasuo(double *A,double (*C)[501]);void LUfenjie(double (*C)[501]);//赋值语句for(i=1;i<=501;i++){a[i-1]=(1.64-0.024*i)*sin(0.2*i)-0.64*exp(0.1/i);}//程序一:使用幂方法求绝对值最大的特征值r[0]=mifayunsuan(a,d);//程序二:使用幂方法求求平移λ[0]后绝对值最大的λ,得到原矩阵中与最大特征值相距最远的特征值d=r[0];r[1]=mifayunsuan(a,d);//比较λ与λ-λ[0]的大小,由已知得if(r[0]>r[1]){d=r[0];r[0]=r[1];r[1]=d;}//程序三:使用反幂法求λr[2]=fanmifayunsuan(a,0);cout<<setiosflags(ios::right);cout<<"λ["<<1<<"]="<<setiosflags(ios::scientific)<<setprecision(12)<<r[0]<<endl;cout<<"λ["<<501<<"]="<<setiosflags(ios::scientific)<<setprecision(12)<<r[1]<<endl;cout<<"λ[s]="<<setiosflags(ios::scientific)<<setprecision(12)<<r[2]<<endl;//程序四:求A的与数u最接近的特征值for(k=1;k<40;k++){uu=r[0]+k*(r[1]-r[0])/40;cout<<"最接近u["<<k<<"]"<<"的特征值为"<<setiosflags(ios::scientific)<<setprecision(12)<<fanmifayunsuan(a,uu)<<endl;}//程序五:谱范数的条件数是绝对值最大的特征值除以绝对值最小的特征值的绝对值cout<<"cond(A)2="<<fabs(r[0]/r[2])<<endl;//程序六:A的行列式的值就是A分解成LU之U的对角线的乘积yasuo(a,vv);LUfenjie(vv);uu=1;for(i=0;i<501;i++){uu=uu*vv[2][i];}cout<<"Det(A)="<<uu<<endl;return 1;}double mifayunsuan(double *a,double weiyi){int i,k;double b=0.16;double c=-0.064;double ee,w,v1,v2,mm,sum;double u[501];double y[505]={0};for(i=0;i<501;i++)u[i]=1;//给u赋初值if (weiyi!=0){for (i=0;i<501;i++)a[i]-=weiyi;}ee=1;k=0;//使得初始计算时进入循环语句while(ee>1e-12){mm=0;for(i=0;i<501;i++){mm=mm+u[i]*u[i];}w=sqrt(mm);for(i=0;i<501;i++){y[i+2]=u[i]/w;//注意此处编程与书上不同,之后会解释它的巧妙之处1 }for(i=0;i<501;i++){u[i]=c*y[i]+b*y[i+1]+a[i]*y[i+2]+b*y[i+3]+c*y[i+4];//1显然巧妙之处凸显出来}sum=0;for(i=0;i<501;i++){sum+=y[i+2]*u[i];}v1=v2;v2=sum;//去除特殊情况,减少漏洞if(k==0){k++;}else{ee=fabs(v2-v1)/fabs(v2);}}if (weiyi!=0){for (i=0;i<501;i++)a[i]+=weiyi;}//还原A矩阵return (v2+weiyi);}double fanmifayunsuan(double *a,double weiyi){int i,k;double b=0.16;double c=-0.064;double ee,w,v1,v2,mm,sum;double u[501];double y[501];double C[5][501];void yasuo(double *A,double (*C)[501]);void LUfenjie(double (*C)[501]);void qiuU(double (*C)[501],double *y,double *u);//把A阵压缩到C阵中for(i=0;i<501;i++)u[i]=1;//给u赋初值if (weiyi!=0){for (i=0;i<501;i++)a[i]-=weiyi;}yasuo(a,C);LUfenjie(C);ee=1;k=0; //使得初始计算时进入循环语句while(ee>1e-12){mm=0;for(i=0;i<501;i++){mm=mm+u[i]*u[i];}w=sqrt(mm);for(i=0;i<501;i++){y[i]=u[i]/w;}qiuU(C,y,u);sum=0;for(i=0;i<501;i++){sum+=y[i]*u[i];}v1=v2;v2=sum;//去除特殊情况,减少漏洞if(k==0){k++;}else{ee=fabs(1/v2-1/v1)/fabs(1/v2);}}if (weiyi!=0){for (i=0;i<501;i++)a[i]+=weiyi;}//还原A矩阵return (1/v2+weiyi);}void yasuo(double *A,double (*C)[501]){double b=0.16;double c=-0.064;int i;for(i=0;i<501;i++){C[0][i]=c;C[1][i]=b;C[2][i]=A[i];C[3][i]=b;C[4][i]=c;}}void LUfenjie(double (*C)[501]){int k,t,j;int r=2,s=2;double sum;int minn(int ,int );int maxx(int ,int );for(k=0;k<501;k++){for(j=k;j<=minn(k+s,501-1);j++){if(k==0)sum=0;else{sum=0;for(t=maxx(k-r,j-s);t<k;t++){sum=sum+C[k-t+s][t]*C[t-j+s][j];}}C[k-j+s][j]=C[k-j+s][j]-sum;}for(j=k+1;j<=minn(k+r,501-1);j++){if(k<501-1){if(k==0)sum=0;else{sum=0;for(t=maxx(j-r,k-s);t<k;t++){sum=sum+C[j-t+s][t]*C[t-k+s][k];}}C[j-k+s][k]=(C[j-k+s][k]-sum)/C[s][k];}}}}void qiuU(double (*C)[501],double *y,double *u){int i,t;double b[501];double sum;int r=2,s=2;int minn(int ,int );int maxx(int ,int );for(i=0;i<501;i++){b[i]=y[i];}for(i=1;i<501;i++){sum=0;for(t=maxx(0,i-r);t<i;t++){sum=sum+C[i-t+s][t]*b[t];}b[i]=b[i]-sum;}u[500]=b[500]/C[s][500];for(i=501-2;i>=0;i--){sum=0;for(t=i+1;t<=minn(i+s,500);t++){sum=sum+C[i-t+s][t]*u[t];}u[i]=(b[i]-sum)/C[s][i];}}int minn(int x,int y){int min;if(x>y)min=y;elsemin=x;return min;}int maxx(int b,int c){int max;if(b>c){if(b>0)max=b;elsemax=0;}else{if(c>0)max=c;elsemax=0;}return max;}三、特征值以及的值λ[1]=-1.070011361502e+001 λ[501]=9.724634098777e+000λ[s]=-5.557910794230e-003最接近u[1]的特征值为-1.018293403315e+001最接近u[2]的特征值为-9.585707425068e+000最接近u[3]的特征值为-9.172672423928e+000最接近u[4]的特征值为-8.652284007898e+000最接近u[5]的特征值为-8.0934********e+000最接近u[6]的特征值为-7.659405407692e+000最接近u[7]的特征值为-7.119684648691e+000最接近u[8]的特征值为-6.611764339397e+000最接近u[9]的特征值为-6.0661********e+000最接近u[10]的特征值为-5.585101052628e+000最接近u[11]的特征值为-5.114083529812e+000最接近u[12]的特征值为-4.578872176865e+000最接近u[13]的特征值为-4.096470926260e+000最接近u[14]的特征值为-3.554211215751e+000最接近u[15]的特征值为-3.0410********e+000最接近u[16]的特征值为-2.533970311130e+000最接近u[17]的特征值为-2.003230769563e+000最接近u[18]的特征值为-1.503557611227e+000最接近u[19]的特征值为-9.935586060075e-001最接近u[20]的特征值为-4.870426738850e-001最接近u[21]的特征值为2.231736249575e-002最接近u[22]的特征值为5.324174742069e-001最接近u[23]的特征值为1.052898962693e+000最接近u[24]的特征值为1.589445881881e+000最接近u[25]的特征值为2.060330460274e+000最接近u[26]的特征值为2.558075597073e+000最接近u[27]的特征值为3.080240509307e+000最接近u[28]的特征值为3.613620867692e+000最接近u[29]的特征值为4.0913********e+000最接近u[30]的特征值为4.603035378279e+000最接近u[31]的特征值为5.132924283898e+000最接近u[32]的特征值为5.594906348083e+000最接近u[33]的特征值为6.080933857027e+000最接近u[34]的特征值为6.680354092112e+000最接近u[35]的特征值为7.293877448127e+000最接近u[36]的特征值为7.717111714236e+000最接近u[37]的特征值为8.225220014050e+000最接近u[38]的特征值为8.648666065193e+000最接近u[39]的特征值为9.254200344575e+000cond(A)2=1.925204273902e+003 Det(A)=2.772786141752e+118四、现象讨论在大作业的程序设计过程当中,初始向量的赋值我顺其自然的设为第一个分量为1,其它分量为0的向量,计算结果与参考答案存在很大差别,计算结果对比如下图2所示(左侧为正确结果,右侧为错误结果),导致了我花了很多的时间去检查程序算法。
北航数值分析第一次大作业
一、算法的设计方案1、求矩阵最大特征值,最小特征值与按模最小特征值的方法首先用幂法求出矩阵A 的一个特征值λ,则其必为最大特征值与最小特征值二者其一,之后对矩阵A 进行一次移项,即A-λI ,然后再次用幂法求出另一个按模最大特征值,再比较这两个值的大小,则较大的为矩阵A 的最大特征值,较小的为矩阵A 的最小特征值。
用反幂法可以求得矩阵的按模最小特征值λs 2、求矩阵A 与k μ最接近的特征值k i λ可以先对矩阵A 进行移项,即A-k μI ,对这个移项后的矩阵用反幂法求出按模最小的特征值,然后再加上k μ,就求出所要求的k i λ。
3、求矩阵A 的条件数cond(A)2和行列式detA由于矩阵A 是非奇异的实对称矩阵,所以可以用以下公式方便地求出矩阵A 的条件数cond(A)2=sλλ501对于矩阵A 行列式的求法也比较简单。
由于在用反幂法的过程中对A 进行了Doolittle LU 分解,所以detA=detL*detU ,而detL=1,detU 可以用对角线元素相乘方便地算出,所以detA 就是U 阵对角线元素的乘积。
4、几点说明由于A 中的零元素都不存储,所以在存储矩阵的时候采用书上26页的压缩存储方式。
在反幂法中采用LU 分解求解带状线性方程组的算法来求解每一次迭代的方程组,由于每一次方程左边的系数都相同,所以只要进行一次LU 分解即可。
因为幂法,反幂法,LU 分解,求最大值与最小值在程序编写的过程中多次用到,所以这几项作为子函数单独进行编写。
二、源程序如下:#include "stdio.h"#include "math.h"# define s 2# define r 2# define N 501double c[5][N]={0};double lameda[40];double max(double x,double y);double min(double x,double y);double mifa();double fanmifa();void LUfenjie();void main(){int i=0,j=0;/*============对数组进行赋值==============*/ for(j=3;j<=N;j++)c[0][j-1]=-0.064;for(j=2;j<=N;j++)c[1][j-1]=0.16;for(j=1;j<=N;j++)c[2][j-1]=(1.64-0.024*j)*sin(0.2*j)-0.64*exp(0.1/j);for(j=1;j<=N-1;j++)c[3][j-1]=0.16;for(j=1;j<=N-2;j++)c[4][j-1]=-0.064;/*========幂法求最大和最小特征值==============*/ double a=mifa();for(j=1;j<=N;j++)c[2][j-1]-=a;double b=mifa()+a;double lameda501=max(a,b);double lameda1=min(a,b);printf("矩阵A最大的特征值=%13.11e\n",lameda501);printf("矩阵A最小的特征值=%13.11e\n",lameda1);/*========反幂法求绝对值最小特征值===========*/for(j=1;j<=N;j++)c[2][j-1]+=a;double lamedas=fanmifa();printf("矩阵A按模最小的特征值=%13.11e\n",lamedas);/*========求条件数和行列式的值===========*/double detA=1;for(j=1;j<=N;j++)detA*=c[2][j-1];printf("矩阵A的行列式=%13.11e\n",detA);double condA=fabs(lameda501/lamedas);printf("矩阵A的条件数=%13.11e\n",condA);/*========反幂法求与uk最接近的特征值========*/for(int k=1;k<40;k++){ for(j=3;j<=N;j++)c[0][j-1]=-0.064;for(j=2;j<=N;j++)c[1][j-1]=0.16;for(j=1;j<=N;j++)c[2][j-1]=(1.64-0.024*j)*sin(0.2*j)-0.64*exp(0.1/j);for(j=1;j<=N-1;j++)c[3][j-1]=0.16;for(j=1;j<=N-2;j++)c[4][j-1]=-0.064;for(j=1;j<=N;j++)c[2][j-1]-=(lameda1+k*(lameda501-lameda1)/40);lameda[k]=fanmifa()+(lameda1+k*(lameda501-lameda1)/40);printf("矩阵A最接近u%d的特征值=%13.11e\n",k,lameda[k]);}}double max(double x,double y) //求两数中的最大值{double z;z=x>y ? x:y;return(z);}double min(double x,double y) //求两数中的最小值{double z;z=x<y ? x:y;return(z);}double mifa() //幂法求按模最大特征值{double u[N]={0};double sum=0;double zero=0;double y[N]={0};double b1=0,b2=0;int i=0,j=0;for(i=0;i<N;i++)u[i]=1;do{ sum=0;for(i=0;i<N;i++)sum+=u[i]*u[i];for(i=0;i<N;i++)y[i]=u[i]/sqrt(sum);for(i=0;i<N;i++){ u[i]=0;for(j=max(0,i-2);j<=min(i+2,N-1);j++){u[i]+=c[i-j+s][j]*y[j];}}b2=b1;zero=0;for(i=0;i<N;i++)zero+=y[i]*u[i];b1=zero;}while((fabs(b1-b2)/fabs(b1))>1e-12);return(b1);}double fanmifa() //反幂法求按模最小特征值{double u[N]={0};double sum=0;double zero=0;double y[N]={0};double b[N]={0};double b1=0,b2=0;int i=0,j=0,t=0;for(i=0;i<N;i++)u[i]=1;LUfenjie();do{ sum=0;for(i=0;i<N;i++)sum+=u[i]*u[i];for(i=0;i<N;i++){b[i]=u[i]/sqrt(sum);y[i]=b[i];}for(i=1;i<N;i++)for(t=max(0,i-r);t<i;t++)y[i]-=c[i-t+s][t]*y[t];u[N-1]=y[N-1]/c[s][N-1];for(i=N-2;i>=0;i--){ for(t=i+1;t<=min(i+s,N-1);t++)y[i]-=c[i-t+s][t]*u[t];u[i]=y[i]/c[s][i];}b2=b1;zero=0;for(i=0;i<N;i++)zero+=b[i]*u[i];b1=1/zero;}while((fabs(b1-b2)/fabs(b1))>1e-12);return(b1);}void LUfenjie() //对矩阵做LU分解{ int k=0;int j=0;int i=0;int t=0;for(k=0;k<N;k++){ for(j=k;j<=min(k+s,N-1);j++)for(t=max(max(0,k-r),j-s);t<k;t++)c[k-j+s][j]-=c[k-t+s][t]*c[t-j+s][j];for(i=k+1;i<=min(k+r,N-1);i++){ for(t=max(max(0,i-r),k-s);t<k;t++)c[i-k+s][k]-=c[i-t+s][t]*c[t-k+s][k];c[i-k+s][k]/=c[s][k];}}}三、运行结果如下四、初始向量对计算结果的影响在本程序的编写中,为了方便起见,所以迭代向量的初值选为u=[1 1 1 ...1]。
北航数值分析第一次大作业(幂法反幂法)
一、问题分析及算法描述1. 问题的提出:(1)用幂法、反幂法求矩阵A =[a ij ]20×20的按摸最大和最小特征值,并求出相应的特征向量。
其中 a ij ={sin (0.5i +0.2j ) i ≠j 1.5cos (i +1.2j ) i =j要求:迭代精度达到10−12。
(2)用带双步位移的QR 法求上述的全部特征值,并求出每一个实特征值相应的特征向量。
2. 算法的描述:(1) 幂法幂法主要用于计算矩阵的按摸为最大的特征值和相应的特征向量。
其迭代格式为:{ 任取非零向量u 0=(h 1(0),⋯,h n (0))T|h r (k−1)|=max 1≤j≤n |h r (k−1)| y ⃑ k−1=u ⃑ k−1|h r (k−1)| u ⃑ k =Ay ⃑ k−1=(h 1(k ),⋯,h n (k ))T βk =sgn (h r (k−1))h r (k ) (k =1,2,⋯) 终止迭代的控制选用≤ε。
幂法的使用条件为n ×n 实矩阵A 具有n 个线性无关的特征向量x 1,x 2,⋯,x n ,其相应的特征值λ1,λ2,⋯,λn 满足不等式|λ1|>|λ2|≥|λ3|≥⋯≥|λn |或λ1=λ2=⋯=λm|λ1|>|λm+1|≥|λm+2|≥⋯≥|λn |幂法收敛速度与比值|λ2λ1|或|λm+1λ1|有关,比值越小,收敛速度越快。
(2) 反幂法反幂法用于计算n ×n 实矩阵A 按摸最小的特征值,其迭代格式为:{任取非零向量u 0∈R nηk−1=√u ⃑ k−1T u ⃑ k−1 y ⃑ k−1=u ⃑ k−1ηk−1⁄ Au ⃑ k =y ⃑ k−1 βk =y ⃑ k−1u ⃑ k (k =1,2,⋯) 每迭代一次都要求解一次线性方程组Au ⃑ k =y ⃑ k−1。
当k 足够大时,λn ≈1βk ,y ⃑ k−1可近似的作为矩阵A 的属于λn 的特征向量。
北航数值分析-实习作业1(C语言详细注释)
《数值分析》计算实习作业《一》北航第一题 设有501501⨯的矩阵⎥⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡=501500499321a bc b a b cc b a b ccb a bc c b a b c b a A其中.064.0,16.0);501,2,1(64.0)2.0sin()024.064.1(1.0-===--=c b i e i i a i i 矩阵的特征值)501,,2,1( =i i λ满足||min ||,501150121i i s λλλλλ≤≤=<<<试求1. 5011,λλ和s λ的值2. 的与数4015011λλκλμ-+=k 最接近的特征值)39,,2,1( =K κλi3. 的(谱范数)条件数2)A (cond 和行列式A det要求1. 算法的设计方案(A 的所有零元素都不能存储)2. 全部源程序(详细注释)。
变量为double ,精度-1210=ε,输出为e 型12位有效数字3. 特征值s 5011,,λλλ和)39,,2,1( =K κλi 以及A cond det ,)A (2的值 4. 讨论迭代初始向量的选取对计算结果的影响,并说明原因解答:1. 算法设计对于s λ满足||min ||5011i i s λλ≤≤=,所以s λ是按模最小的特征值,直接运用反幂法可求得。
对于5011,λλ,一个是最大的特征值,一个是最小的特征值,不能确定两者的绝对值是否相等,因此必须首先假设||||5011λλ≠,然后运用幂法,看能否求得一个特征值,如果可以求得一个,证明A 是收敛的,求得的结果是正确的,然后对A 进行带原点平移的幂法,偏移量是前面求得的特征值,可以求得另一个特征值,最后比较这两个特征值,较大的特征值是501λ,较小的特征值就是1λ。
如果在假设的前提下,无法运用幂法求得按模最大的特征值,即此时A 不收敛,则需要将A 进行带原点平移的幂法,平移量可以选取1,再重复上述步骤即可求得两个特征值。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
—计算实习作业一
学 姓 学
院: xxx 名: xxx 号: xxx
2014-11-16
1. 设计方案
观察矩阵 A,结构为带状,且与主对角线相邻的两个带的值 b 和 c 都是常数。从 而可以用带原点平移的幂法或反幂法计算 λ1 和 λ501。 所以算法的设计方案如下: 1.求按模最大的特征值,并记为 lamda1; 2.平移矩阵得到 A’=A-lamda1I,再次用幂法,这次求出的 A’的按模大的特征值 lamda2 就是与步骤 1 求出的特征值相差最大的特征值。即两者一个为最大的特 征值,另一个为最小的特征值。 3.根据 lamda1 和 lamda2 的正负性,直接确定 λ1,和 λ501。 4.对原矩阵 A 用反幂法,求出其按模最小的特征值,记为 lamdas,此即 λs。
end do gama=sqrt(sum) sum=0.0 do i=1,n ue(i)=u(i)/gama end do f=ue if(g==1)then do k=1,n do j=k,min(k+s,n) do t=max(1,k-r,j-s),k-1 sum=sum+a(k-t+s+1,t)*a(t-j+s+1,j) end do a(k-j+s+1,j)=a(k-j+s+1,j)-sum sum=0.0 end do if(abs(a(s+1,k)-0.0)<=1e-6)then write(*,*)"算法失效" exit end if!算法失效的判断 do i=k+1,min(k+r,n) do t=max(1,i-r,k-s),k-1 sum=sum+a(i-t+s+1,t)*a(t-k+s+1,k) end do a(i-k+s+1,k)=(a(i-k+s+1,k)-sum)/a(s+1,k) sum=0.0 end do end do end if !-------------求解Ly=b,Ux=y方程,求出u-----------do i=2,n do t=max(1,i-r),i-1 sum=sum+a(i-t+s+1,t)*f(t) end do f(i)=f(i)-sum sum=0.0 end do u(n)=f(n)/a(s+1,n) do i=n-1,1,-1 do t=i+1,min(i+s,n) sum=sum+a(i-t+s+1,t)*u(t) end do u(i)=(f(i)-sum)/a(s+1,i)
deta=sum sum=1.0 !-----------------输出所有结果----------------------------------open(11,file='所有结果.txt') write(11,'(A,e20.12)')'最小特征值:',lamda(1) write(11,'(A,e20.12)')'最大特征值:',lamda(n) write(11,'(A,e20.12)')'按模最小特征值:',lamdas write(11,'(A,e20.12)')'按模最大特征值:',lamdam1 write(11,'(A,e20.12)')"与数mu最接近的特征值:" do i=1,39 write(11,'(I2,e20.12)')i,lamdai(i) end do write(11,'(A,e20.12)')'条件数cond(A):',conda write(11,'(A,e20.12)')'行列式的值detA:',deta close(11) pause end program !*************************************************** !---------------幂法求按模最大特征值-------------subroutine mimethod(a,lamda) use array implicit none real(8),intent(in)::a(m,n) real(8),intent(out)::lamda!a为传递进来的矩阵,lamda为传递进来的特征值 integer::k,i,j,t real(8)::sum=0.0D0 real(8)::u(n),ue(n)!u单位化变为ue real(8)::belta=0.0D0,gama,belta0!belta为特征值的迭代近似值,gama为u的 模,belta0在做误差选择中用到 real(8),parameter::epsu=1e-12 k=1 u=1.0D0 u(1)=1.0D0 do while (.true.) write(*,*)'幂法迭代次数K=',k k=k+1 do i=1,n sum=sum+u(i)*u(i) end do gama=sqrt(sum) sum=0.0D0
cond ( A2 )
6.根据公式 其中 λmax 和 λmin 分别是矩阵 A 的按模最大和按 模最小的特征值。将 lamda1 和 lamdas 分别代入 λmax 和 λmin,就可以求出 cond(A) 。 7.对矩阵 A 做三角分解,A=LU。则有
det A u (i, i )
任取非零向量u 0 R n T k 1 u k 1u k 1 y k 1 u k 1 / k 1 Au k y k 1 T k y k 1u k (k 1,2, )
在反幂法的求解过程中,每迭代一次都要求满足解线性方程组 Auk=yk-1。本题 中矩阵 A 上半带宽为 2, 下半带宽也为 2 。 故选择采用三角分解法求解方程组: 先将原矩阵改写成 5 行 501 列的矩阵 C(不存储 A 的 0 元素) A 的带内元素 aij=c 中的元素 ci-j+3。 再对 C 矩阵做 LU 分解。对于 k=1,2,…,n,执行
c(s+2,i-1)=b end do do i=3,n c(s+3,i-2)=cc end do do i=1,n-1 c(s,i+1)=b end do do i=1,n-2 c(s-1,i+2)=cc end do!输入系数矩阵C do i=1,m write(10,*)(c(i,j),j=1,n) end do close(10) !--------------第一问:求最小最大特征值和按模最小特征值----------call mimethod(c,lamdam1)!lamda1是矩阵A的按模最大的特征值 tempc=c do i=1,n tempc(s+1,i)=c(s+1,i)-lamdam1 end do call mimethod(tempc,lamdam2) lamda(1)=min(lamdam1,lamdam1+lamdam2) lamda(n)=max(lamdam1,lamdam1+lamdam2) tempc=c call antimimethod(tempc,lamdas) tempc=c!反幂法会使tempc发生变化 !-----------------第二问:求中间39个特征值------------------------do k=1,39 mu(k)=lamda(1)+k*(lamda(n)-lamda(1))/40.0D0 end do do k=1,39 do i=1,n tempc(s+1,i)=c(s+1,i)-mu(k) end do call antimimethod(tempc,lamdai(k)) lamdai(k)=lamdai(k)+mu(k) tempc=c end do !-----------------第三问:求A的条件数和行列式---------------------conda=abs(lamdam1/lamdas) do i=1,n sum=sum*ukk(i) end do
do i=1,n ue(i)=u(i)/gama end do do i=1,n do t=max(1,i-r),min(i+s,n) sum=sum+a(i-t+s+1,t)*ue(t) end do u(i)=sum sum=0.0 end do do i=1,n sum=sum+ue(i)*u(i) end do belta0=belta belta=sum sum=0.0 if (abs(belta-belta0)/abs(belta)<=epsu)then exit end if end do lamda=belta return end subroutine mimethod !**********************反幂法求按模最小特征值**************** subroutine antimimethod(a,lamda) use array implicit none real(8)::a(m,n) real(8),intent(out)::lamda!a为传递进来的矩阵,lamda为传递进来的特征值 integer::k,i,j,g,t real(8)::sum=0.0 real(8)::u(n),ue(n),f(n)!u单位化变为ue real(8)::belta,gama,belta0!belta为特征值的迭代近似值,gama为u的模,belta0 在做误差选择中用到 real(8),parameter::epsu=1e-12 g=1 belta=0.0D0 u=1.0 do while (.true.) write(*,*)'反幂法迭代次数G=',g do i=1,n sum=sum+u(i)*u(i)