2016级数值分析实验课题大作业
- 格式:pdf
- 大小:780.99 KB
- 文档页数:9
数值分析课程实验设计——数值线性代数
实习题
1. 实验目的
本实验的主要目的是进一步加深对数值线性代数的理解,熟悉
常见矩阵分解方法,并在此基础上解决实际问题。
2. 实验内容
本次实验将任务分为两个部分,分别是矩阵分解与求解线性方
程组。
2.1 矩阵分解
首先,我们需要熟悉三种常见的矩阵分解:QR分解、LU分解
和奇异值分解。
我们需要通过Python语言实现这三种分解方法,
并利用这些方法解决实际问题。
2.2 求解线性方程组
其次,我们需要学会用矩阵分解的方法来求解线性方程组。
我
们将通过两个例子来进行说明,并利用Python语言实现这些方法。
3. 实验要求
本次实验要求熟悉矩阵分解的基本方法,在此基础上解决实际问题;能够运用多种方法来求解线性方程组,并分析比较它们的优缺点。
4. 实验总结
本次实验通过矩阵分解和求解线性方程组两个部分的学习,巩固了我们对于数值线性代数的知识,并在实际问题的解决中得到了应用。
感谢老师的指导,我们会在今后的学习中持续探索数值分析方面的知识。
《数值分析》课程实验报告《数值分析》课程实验报告姓名:学号:学院:机电学院日期:2015年X月X日目录实验一函数插值方法1实验二函数逼近与曲线拟合5实验三数值积分与数值微分7实验四线方程组的直接解法9实验五解线性方程组的迭代法15实验六非线性方程求根19实验七矩阵特征值问题计算21实验八常微分方程初值问题数值解法24实验一函数插值方法一、问题提出对于给定的一元函数的n+1个节点值。
试用Lagrange公式求其插值多项式或分段二次Lagrange插值多项式。
数据如下:(1)0.40.550.650.800.951.050.410750.578150.696750.901.001.25382求五次Lagrange多项式,和分段三次插值多项式,计算,的值。
(提示:结果为,)(2)12345670.3680.1350.0500.0180.0070.0020.001试构造Lagrange多项式,计算的,值。
(提示:结果为,)二、要求1、利用Lagrange插值公式编写出插值多项式程序;2、给出插值多项式或分段三次插值多项式的表达式;3、根据节点选取原则,对问题(2)用三点插值或二点插值,其结果如何;4、对此插值问题用Newton插值多项式其结果如何。
Newton插值多项式如下:其中:三、目的和意义1、学会常用的插值方法,求函数的近似表达式,以解决其它实际问题;2、明确插值多项式和分段插值多项式各自的优缺点;3、熟悉插值方法的程序编制;4、如果绘出插值函数的曲线,观察其光滑性。
四、实验步骤(1)0.40.550.650.800.951.050.410750.578150.696750.901.001.25382求五次Lagrange多项式,和分段三次插值多项式,计算,的值。
(提示:结果为,)第一步:先在matlab中定义lagran的M文件为拉格朗日函数代码为:function[c,l]=lagran(x,y)w=length(x);n=w-1;l=zeros(w,w);fork=1:n+1v=1;forj=1:n+1if(k~=j)v=conv(v,poly(x(j)))/(x(k)-x(j ));endendl(k,:)=v;endc=y*l;end第二步:然后在matlab命令窗口输入:x=[0.40.550.650.80,0.951.05];y=[0.410750.578150.696750.901. 001.25382];lagran(x,y)回车得到:ans=121.6264-422.7503572.5667-377.2549121.9718-15.0845由此得出所求拉格朗日多项式为p(x)=121.6264x5-422.7503x4+572.5667x3-377.2549x2+121.9718x-15.0 845第三步:在编辑窗口输入如下命令:x=[0.40.550.650.80,0.951.05];y=121.6264*x.^5-422.7503*x.^4+ 572.5667*x.^3-377.2549*x.^2+121.9718*x-15.0845;plot(x,y)命令执行后得到如下图所示图形,然后x=0.596;y=121.6264*x.^5-422.7503*x.^4+572.5667*x.^3-377.254 9*x.^2+121.9718*x-15.084y=0.6262得到f(0.596)=0.6262同理得到f(0.99)=1.0547(2)12345670.3680.1350.0500.0180.0070.0020.001试构造Lagrange多项式,和分段三次插值多项式,计算的,值。
数值分析大作业一一、算法设计方案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];}}}}三、程序结果。
数值分析上机作业(一)一、算法的设计方案1、幂法求解λ1、λ501幂法主要用于计算矩阵的按模最大的特征值和相应的特征向量,即对于|λ1|≥|λ2|≥.....≥|λn|可以采用幂法直接求出λ1,但在本题中λ1≤λ2≤……≤λ501,我们无法判断按模最大的特征值。
但是由矩阵A的特征值条件可知|λ1|和|λ501|之间必然有一个是最大的,通过对矩阵A使用幂法迭代一定次数后得到满足精度ε=10−12的特征值λ0,然后在对矩阵A做如下的平移:B=A-λ0I由线性代数(A-PI)x=(λ-p)x可得矩阵B的特征值为:λ1-λ0、λ2-λ0…….λ501-λ0。
对B矩阵采用幂法求出B矩阵按模最大的特征值为λ∗=λ501-λ0,所以λ501=λ∗+λ0,比较λ0与λ501的大小,若λ0>λ501则λ1=λ501,λ501=λ0;若λ0<λ501,则令t=λ501,λ1=λ0,λ501=t。
求矩阵M按模最大的特征值λ的具体算法如下:任取非零向量u0∈R nηk−1=u T(k−1)∗u k−1y k−1=u k−1ηk−1u k=Ay k−1βk=y Tk−1u k(k=1,2,3……)当|βk−βk−1||βk|≤ε=10−12时,迭终终止,并且令λ1=βk2、反幂法计算λs和λik由已知条件可知λs是矩阵A 按模最小的特征值,可以应用反幂法直接求解出λs。
使用带偏移量的反幂法求解λik,其中偏移量为μk=λ1+kλ501−λ140(k=1,2,3…39),构造矩阵C=A-μk I,矩阵C的特征值为λik−μk,对矩阵C使用反幂法求得按模最小特征值λ0,则有λik=1λ0+μk。
求解矩阵M按模最小特征值的具体算法如下:任取非零向量u 0∈R n ηk−1= u T (k−1)∗u k−1y k−1=u k−1ηk−1 Au k =y k−1βk =y T k−1u k (k=1,2,3……)在反幂法中每一次迭代都要求解线性方程组Au k =y k−1,当K 足够大时,取λn =1βk 。
序言数值分析是计算数学的范畴,有时也称它为计算数学、计算方法、数值方法等,其研究对象是各种数学问题的数值方法的设计、分析及其有关的数学理论和具体实现的一门学科,它是一个数学分支。
是科学与工程计算(科学计算)的理论支持。
许多科学与工程实际问题(核武器的研制、导弹的发射、气象预报)的解决都离不开科学计算。
目前,试验、理论、计算已成为人类进行科学活动的三大方法。
数值分析是计算数学的一个主要部分,计算数学是数学科学的一个分支,它研究用计算机求解各种数学问题的数值计算方法及其理论与软件实现。
现在面向数值分析问题的计算机软件有:C,C++,MATLAB,Python,Fortran等。
MATLAB是matrix laboratory的英文缩写,它是由美国Mathwork公司于1967年推出的适合用于不同规格计算机和各种操纵系统的数学软件包,现已发展成为一种功能强大的计算机语言,特别适合用于科学和工程计算。
目前,MATLAB应用非常广泛,主要用于算法开发、数据可视化、数值计算和数据分析等,除具备卓越的数值计算能力外,它还提供了专业水平的符号计算,文字处理,可视化建模仿真和实时控制等功能。
本实验报告使用了MATLAB软件。
对不动点迭代,函数逼近(lagrange插值,三次样条插值,最小二乘拟合),追赶法求解矩阵的解,4RungeKutta方法求解,欧拉法及改进欧拉法等算法做了简单的计算模拟实践。
并比较了各种算法的优劣性,得到了对数值分析这们学科良好的理解,对以后的科研数值分析能力有了极大的提高。
目录序言 (1)问题一非线性方程数值解法 (3)1.1 计算题目 (3)1.2 迭代法分析 (3)1.3计算结果分析及结论 (4)问题二追赶法解三对角矩阵 (5)2.1 问题 (5)2.2 问题分析(追赶法) (6)2.3 计算结果 (7)问题三函数拟合 (7)3.1 计算题目 (7)3.2 题目分析 (7)3.3 结果比较 (12)问题四欧拉法解微分方程 (14)4.1 计算题目 (14)4.2.1 方程的准确解 (14)4.2.2 Euler方法求解 (14)4.2.3改进欧拉方法 (16)问题五四阶龙格-库塔计算常微分方程初值问题 (17)5.1 计算题目 (17)5.2 四阶龙格-库塔方法分析 (18)5.3 程序流程图 (18)5.4 标准四阶Runge-Kutta法Matlab实现 (19)5.5 计算结果及比较 (20)问题六舍入误差观察 (22)6.1 计算题目 (22)6.2 计算结果 (22)6.3 结论 (23)7 总结 (24)附录问题一 非线性方程数值解法1.1 计算题目编写不动点迭代法求根程序:把方程010423=-+x x 写成至少四种x=g (x )的形式,取初值5.1x 0=,进行不动点迭代求根,并比较收敛性及收敛速度。
超松弛迭代法如何选取最佳松弛因子船建学院B1301095 wj一、课题背景逐次超松弛迭代法是Gauss-Seidel方法的一种加速方法,是解大型稀疏矩阵方程组的有效方法之一,它具有计算公式简单,程序设计容易,占用计算机内存较少等优点,但需要选择好的加速因子(即最佳松弛因子)。
最佳松弛因子ω的确定是数值代数中的一个理论难题,对于不同的矩阵,其最佳松弛因子往往相差很大,没有统一的计算公式来确定ω。
由于对称正定矩阵sor方法收敛的充分必要条件为w在0到2之间,故利用对称正定矩阵一定收敛的性质,本文提供一种针对于系数矩阵为对称正定矩阵时,如何选取合适的最佳松弛因子的方法。
二、课题研究流程图三、SOR迭代公式逐次超松弛(Successive Over Relaxation)迭代法,简称SOR迭代法,它是在GS法基础上为提高收敛速度,采用加权平均而得到的新算法,设解方程的GS法记为(1)再由与加权平均得这里ω>0称为松弛参数,将(1)式代入则得(2)称为SOR迭代法,[WTBX]ω>0称为松弛因子,当ω=1时(2)式即为GS法,将(2)式写成矩阵形式,则得即于是得SOR迭代的矩阵表示(3)四、Matlab程序%sor法确定对称正定矩阵的最佳松弛因子w%clc;clear;n=100;%矩阵的阶数%for num=1:100X=diag(rand(n,1));U=orth(rand(n,n)-0.5);a=U'*X*U;%以上是利用随机对角矩阵和随机正交矩阵,产生随机的对称正定矩阵,正交变化不改变特征值%L=zeros(n,n);U=zeros(n,n);%分配L和U的内存空间%step=0.02;%定义w的计算精度%for k=1:(2/step) %由于对称正定矩阵sor方法收敛的充分必要条件为w在0到2之间%w=(k-1)*step;for i=1:n %一个总的for循环给三个矩阵赋值D-L-U=A,%for j=1:i-1L(i,j)=-a(i,j);%L矩阵的赋值%endfor j=i+1:nU(i,j)=-a(i,j);%U矩阵的赋值%endD(i,i)=a(i,i);%D矩阵的赋值%endH=inv(D-w*L)*((1-w)*D+w*U);%sor方法的核心,H矩阵为迭代矩阵%p(k)=max(abs(eig(H)));%利用此函数求矩阵的谱半径%endk_min=find(p==min(p));%find函数寻找不同的w中谱半径的最小值,即寻找收敛最快的w%w_min(num)=(k_min-1)*step;%由最小值的序号得到最优的w%endhist(w_min,100)%对数量足够多的随机对称正定矩阵做频率统计,w划分100份,做出统计图%mean(w_min)%对不同矩阵的最小谱半径所对应的w对平均统计%五、结果对于不同阶数,计算得到的最佳收敛因子w不同,大致是随阶数增大而增大。
数值分析大作业二一、算法设计方案(一)算法流程1.将要求解的矩阵进行Householder变换,进行拟上三角化,并输出拟上三角化的结果;2.将拟上三角化后的矩阵进行带双步位移的QR分解(最大迭代次数1000次),逐个求出特征值,输出QR法结束后得到的Q、R、RQ阵,输出求出的特征值(用实部和虚部表示)3.对于求出来的实特征值,使用带原点平移的反幂法求出对应的特征向量,输出这些特征向量。
(二)程序设计流程1. 定义精度和最大迭代次数;2. 使用容器vector进行编程(方便增减元素),使用传引用调用(提高执行效率);3. 将各个步骤用到的数学算法封装成函数,方便调用。
具体需要的函数如下:double VectMod(vector< double > &p):求向量的模vector< double > NumbMultiVect(vector< double > &vect, double a):数乘向量double VectMultiVect(vector< double > &y, vector< double > &u):求两个向量的积vector< double > ConveArraMultiVect(vector< vector< double > > &B, vector<double > &u):矩阵的转置乘向量vector< double > ArraMultiVect(vector< vector< double > > &B, vector< double > &u):矩阵乘向量vector< vector< double > > VectMultiCovVect(vector< double > &a, vector< double >&b):向量乘向量转置得到矩阵void ArraSubs(vector< vector< double > > &C, vector< vector < double > > D) :两个矩阵相减Vector< double > VectSubs(vector< double > &a, vector< double > &b):两个向量相减vector<vector<double>> GetM(vector<vector<double>> &A):求解矩阵M (用于双部位移QR迭代用)double GetMode(vector < vector < double > > &B, const int r):求解矩阵B的r列向量的模double GetModeH(vector < vector < double > > &B, const int r):求解矩阵B的第r列向量的模,用于拟对角化vector< vector< double > > NumbMultiArra(vector< vector< double > > &D, double a):一个实数乘矩阵bool IsBirZeroH(vector< vector< double > > &B, const int r):判断B[i][r]对角线下是否为零void GausElim(vector< vector< double > > a):列主元高斯消元法求齐次方程解向量void Stop(vector< vector< double > > &Ar):停止,结束程序void SolutS1S2(complex< double > &s1, complex< double > &s2, vector< vector<double > > &A):求解二阶子阵的特征值s1,s2;void Save2(complex< double > &s1, complex< double > &s2):保存两个特征值void Save1(complex< double > &s):保存一个特征值void JudgemBelow2(vector< vector< double > > &A, vector< vector< double > > Abk):对于m == 1 及m == 0 的处理void Hessenberg(vector< vector< double > > &A):矩阵拟上三角化void QRMethod(vector< vector< double > > A):矩阵QR分解void CalculatAk(vector< vector < double > > &Ak):带双步位移QR迭代法二、源程序#include "stdafx.h"#include <vector>#include <iostream>#include <math.h>#include <complex>#include <fstream>using namespace std;const double epsion = 1e-12;const int L = 1000;int m,n;int k = 1;vector< vector< double > > I;vector< complex< double > > Lambda;///////////////////////////以下为自定义的算法流程中用到的函数double VectMod(vector< double > &p) //求向量的模{double value = 0.0;vector< double >::size_type i,j;j = p.size();for (i=1; i<j; i++){value += p[i] * p[i];}value = sqrt(value);return value;}vector< double > NumbMultiVect(vector< double > &vect, double a) //数乘向量{int j = vect.size();vector< double > b(j, 0);for (int i=1; i<j; i++){b[i] = a * vect[i];}return b;}double VectMultiVect(vector< double > &y, vector< double > &u)//两个向量相乘{vector< double >::size_type a = y.size();double value = 0;for (vector< double >::size_type i=1; i<a; i++){value += y[i] * u[i];}return value;}vector< double > ConveArraMultiVect(vector< vector< double > > &B, vector< double > &u)//矩阵的转置乘向量{int a = B.size();int b = u.size();vector< double > vec(a, 0);if (a != b){cerr << "Array and Vector not match in size!";}else{for (int i=1; i<a; i++){for (int j=1; j<a; j++){vec[i] += B[j][i] * u[j];}}return vec;}}vector< double > ArraMultiVect(vector< vector< double > > &B,vector< double > &u) //矩阵乘向量{int a = B.size();int b = u.size();vector< double > vec(a, 0);if (a != b){cerr << "Array and Vector not match in size!";}else{for (int i=1; i<a; i++){for (int j=1; j<a; j++){vec[i] += B[i][j] * u[j];}}return vec;}}vector< vector<double> > GetM(vector< vector <double> > &A){int a = A.size();double s = A[a-2][a-2] + A[a-1][a-1];double t = A[a-2][a-2] * A[a-1][a-1] - A[a-1][a-2] * A[a-2][a-1];vector<vector<double>> D(a, vector< double >(a, 0));for (int i=1; i<a; i++){{double sum = 0;for (int k=1; k<a; k++){sum += A[i][k] * A[k][j];}D[i][j] = sum - s * A[i][j] + t *(i==j ? 1.0 : 0);}}return D;}double GetMode(vector < vector < double > > &B, const int r){double value = 0;int a = B.size();for (int k=r; k<a; k++){value += B[k][r] * B[k][r];}value = sqrt(value);return value;}double GetModeH(vector < vector < double > > &B, const int r){double value = 0;int a = B.size();for (int k=r+1; k<a; k++){value += B[k][r] * B[k][r];}value = sqrt(value);return value;}vector< vector< double > > NumbMultiArra(vector< vector< double > > &D, double a)//数乘//向量{int b = D.size();vector< vector< double > > U(b, vector< double >(b, 0));for (int i=1; i<b; i++){{U[i][j] = a *D[i][j];}}return U;}bool IsBirZero(vector< vector< double > > &B, const int r){bool b = true;int a = B.size();for (int i=r+1; i<a; i++){if(abs(B[i][r]) > epsion){b = false;}}return b;}bool IsBirZeroH(vector< vector< double > > &B, const int r){bool b = true;int a = B.size();for (int i=r+2; i<a; i++){if(abs(B[i][r]) > epsion){b = false;}}return b;}vector< vector< double > > VectMultiCovVect(vector< double > &a,vector< double > &b)//向量乘向量的转置得到矩阵{int s1 = a.size();int s2 = b.size();if (s1 != s2){cerr << "Vectors not match in size ! ";}else{vector< vector< double > > U(s1, vector< double >(s1, 0));for (int i=1; i<s1; i++){for (int j=1; j<s1; j++){U[i][j] = a[i] * b[j];}}return U;}}void ArraSubs(vector< vector< double > > &C,vector< vector < double > > D){int a = C.size();int b = D.size();int c = C[0].size();int d = D[0].size();if (a!=b || c!=d){cerr << "Vectors not match in size !";}else{for (int i=1; i<a; i++){for (int j=1; j<a; j++){C[i][j] -= D[i][j];}}}}vector< double > VectSubs(vector< double > &a,vector< double > &b){int s1 = a.size();int s2 = b.size();if(s1 != s2){cerr << "Vectors not match in size !";}else{vector< double > value(s1,0);for (int i=1;i<s1;i++){value[i] = a[i] - b[i];}return value;}}void GausElim(vector< vector< double > > a) //高斯消元{int sz = a.size();vector< int > fx, ufx,ufxp, record;vector< double > x(sz, 0);vector< vector< double > > ret;//*****消元过程********for (int k = 1; k < sz-1; k++){double max = a[k][k];int p=0;for (int i=k+1; i<sz; i++){if (abs(a[i][k]) > abs(max)){p =i;max = a[i][k];}}//选出主元行if (abs(max) >= epsion){if (p != 0){for (int j=k; j<sz; j++){double temp = a[k][j];a[k][j] = a[p][j];a[p][j] = temp;}//交换主元行}for (int i=k+1; i<sz; i++){double tt = a[i][k] / a[k][k];for (int j=k+1; j<sz; j++){a[i][j] = a[i][j] - tt * a[k][j];}}}// end of if (abs(max) >= epsion)}// end of for (int k = 1; k < sz; k++)for (int i=1; i<sz; i++){int p=0;for (int j=1; j<=i;j++){if(abs(a[j][i]) >= 10*epsion)//不为零{p=j;}}record.push_back(p);}for (int i=1; i<sz; i++){int p=0;for (int j=sz-2; j>=0; j--){if (record[j] == i){p=j + 1;}}if (p != 0){ufxp.push_back(p);ufx.push_back(i);}}for (int i=1; i<sz; i++){int p = 0;for (int j=0; j < ufxp.size(); j++){if (ufxp[j] == i){p = 1;}}if (p == 0){fx.push_back(i);}}//end of for (int i=1; i<sz; i++)int c = fx.size();//***************************************************** for (int i=0; i<c; i++){for (int j=0; j<c; j++){if (i == j){x[fx.at(j)] = 1.0 + epsion;}else{x[fx.at(j)] = 0;}}int b = ufxp.size();for (int s=b-1; s>=0; s--){double temp=0;for(int t=ufxp.at(s)+1; t<sz; t++){temp += x[t] * a[ufx.at(s)][t];}x[ufxp.at(s)] = (0 - temp) / a[ufx.at(s)][ufxp.at(s)];}ret.push_back(x);}//end of for (int i=0; i<c; i++)//******************************************************* int sz1 = ret.size();int sz2 = ret[0].size();ofstream result2("CharactVector .txt", ios::app);result2.precision(12);for (int i=0; i<sz1; i++){for (int j=1;j<sz2; j++){result2 << scientific << ret[i][j] << endl;}result2 << endl << endl;}result2 << "下一个特征值的特征向量!" << endl;}void Stop(vector< vector< double > > &Ar){int a = Lambda.size();for (int i=0; i<a; i++){if (abs(Lambda[i].imag())<=epsion){vector< vector< double > > An=Ar;ArraSubs(An,NumbMultiArra(I,Lambda[i].real()));GausElim(An);}}ofstream result("result.txt");result.precision(12);vector<complex< double > >::iterator i,j;j = Lambda.end();for (i = Lambda.begin(); i<j; i++){result << scientific <<(*i) << endl;}exit(0);}void SolutS1S2(complex< double > &s1, complex< double > &s2,vector< vector< double > > &A){double s = A[m-1][m-1] + A[m][m];double t = A[m-1][m-1] * A[m][m] - A[m][m-1] * A[m-1][m];double det = s *s - 4.0 * t;if (det > 0){s1.imag(0);s1.real ((s + sqrt(det)) / 2);s2.imag (0);s2.real((s - sqrt(det)) / 2);}else{s1.imag(sqrt(0 - det) / 2);s1.real(s / 2);s2.imag(0 - sqrt(0 - det) / 2);s2.real(s / 2);}}void Save2(complex< double > &s1, complex< double > &s2)//存储特征值s1,s2 {Lambda.push_back(s1);Lambda.push_back(s2);}void Save1(complex< double > &s){Lambda.push_back(s);}void JudgemBelow2(vector< vector< double > > &A,vector< vector< double > > Abk){if (m == 1){complex< double > lbd;lbd.imag(0);lbd.real(A[1][1]);Save1(lbd);Stop(Abk);}else if (m == 0){Stop(Abk);}}//拟上三角化void Hessenberg(vector< vector< double > > &A){int a = A.size();vector< double > u(a,0);vector< double > p(a,0);vector< double > q(a,0);vector< double > w(a,0);double d, c, h, t;for (int r=1; r<a-2; r++){if (!IsBirZeroH(A, r)){d = GetModeH(A,r);c = (A[r+1][r] > 0) ?(0-d) : d;h = c * c - c * A[r+1][r];for (int j=1; j<a; j++){if (j < r+1){u[j] = 0;}else if (j == r+1){u[j] = A[j][r] - c;}else{u[j] = A[j][r];}}// end of for (int j=1; j<=m; j++)p = NumbMultiVect(ConveArraMultiVect(A, u), 1 / h);q = NumbMultiVect(ArraMultiVect(A, u), 1 / h);t = VectMultiVect(p, u) / h;w = VectSubs(q, NumbMultiVect(u, t));ArraSubs(A, VectMultiCovVect(w, u));ArraSubs(A, VectMultiCovVect(u, p));}// end of if (!IsBirZero(B, r))}// end of for (int r=1; r<m; r++)ofstream result("NISHANGDANJIAO.txt");result.precision(12);for (int i=1; i<a; i++){for (int j=1; j<a; j++){result << scientific << A[i][j] << " ";}result << endl;}}void QRMethod(vector< vector< double > > A){int a = A.size();vector< vector< double > > Q(a,vector < double > (a,0));for (int i=1; i<a; i++){Q[i][i] = 1.0;}vector< vector< double > > RQ(A);//vector< double > u(a,0);vector< double > v(a,0);vector< double > p(a,0);vector< double > q(a,0);vector< double > w(a,0);vector< double > l(a,0);double d, c, h, t;for (int r=1; r<a-1; r++){if (!IsBirZero(A, r)){d = GetMode(A,r);c = (A[r][r] > 0) ?(0-d) : d;h = c * c - c * A[r][r];for (int j=1; j<a; j++){if (j < r){u[j] = 0;}else if (j == r){u[j] = A[j][j] - c;}else{u[j] = A[j][r];}}// end of for (int j=1; j<=m; j++)l = ArraMultiVect(Q, u);ArraSubs(Q, VectMultiCovVect(l,NumbMultiVect(u, 1/h)));v = NumbMultiVect(ConveArraMultiVect(A, u), 1 / h);ArraSubs(A, VectMultiCovVect(u, v));p = NumbMultiVect(ConveArraMultiVect(RQ, u), 1 / h);q = NumbMultiVect(ArraMultiVect(RQ, u), 1 / h);t = VectMultiVect(p, u) / h;w = VectSubs(q, NumbMultiVect(u, t));ArraSubs(RQ, VectMultiCovVect(w, u));ArraSubs(RQ, VectMultiCovVect(u, p));}// end of if (!IsBirZero(B, r))}// end of for (int r=1; r<m; r++)ofstream result("QR.txt");result.precision(12);for (int i=1; i<a; i++){for (int j=1; j<a; j++){result << scientific << Q[i][j] << " ";}result << endl;}result << endl << endl;for (int i=1; i<a; i++){for (int j=1; j<a; j++){result << scientific << A[i][j] << " ";}result << endl;}result << endl << endl;for (int i=1; i<a; i++){for (int j=1; j<a; j++){result << scientific << RQ[i][j] << " ";}result << endl;}}void CalculatAk(vector< vector < double > > &Ak){int a = Ak.size();vector< vector < double > > B(a,vector < double > (a,0));vector< double > u(a,0);vector< double > v(a,0);vector< double > p(a,0);vector< double > q(a,0);vector< double > w(a,0);double d, c, h, t;B = GetM(Ak);for (int r=1; r<a-1; r++){if (!IsBirZero(B, r)){d = GetMode(B,r);c = (B[r][r] > 0) ?(0-d) : d;h = c * c - c * B[r][r];for (int j=1; j<a; j++){if (j < r){u[j] = 0;}else if (j == r){u[j] = B[j][j] - c;}else{u[j] = B[j][r];}}// end of for (int j=1; j<=m; j++)v = NumbMultiVect(ConveArraMultiVect(B, u), 1 / h);ArraSubs(B, VectMultiCovVect(u, v));p = NumbMultiVect(ConveArraMultiVect(Ak, u), 1 / h);q = NumbMultiVect(ArraMultiVect(Ak, u), 1 / h);t = VectMultiVect(p, u) / h;w = VectSubs(q, NumbMultiVect(u, t));ArraSubs(Ak, VectMultiCovVect(w, u));ArraSubs(Ak, VectMultiCovVect(u, p));}// end of if (!IsBirZero(B, r))}// end of for (int r=1; r<m; r++)}int _tmain(int argc, _TCHAR* argv[]){vector< vector< double > > A(11, vector< double >(11,0));vector< vector< double > > Abk;I=A;for (int i=1; i<11; i++){vector< double > temp;for (int j=1; j<11; j++){if(i != j){A[i][j] = sin(0.5 * i + 0.2 * j);I[i][j] = 0;}else{A[i][j] = 1.5 * cos(i + 1.2 *j);I[i][j] = 1.0;}}}Abk = A;n = A.size() - 1;m = n;//初始化问题Hessenberg(A);QRMethod(A);while (1){if (abs(A[m][m-1]) <= epsion){complex< double > lbdm;lbdm.imag(0);lbdm.real(A[m][m]);Save1(lbdm);m -= 1;//对A进行降维处理!!!!A.pop_back();int a = A.size();for (int i=0; i<a; i++){A[i].pop_back();}JudgemBelow2(A, Abk);}else{complex< double > va1, va2;SolutS1S2(va1, va2, A);if (m == 2){Save2(va1,va2);Stop(Abk);}//end of if (m == 2)if ( abs(A[m-1][m-2]) <= epsion){Save2(va1,va2);m = m - 2;//矩阵降维A.pop_back();A.pop_back();int a = A.size();for (int i=0; i<a; i++){A[i].pop_back();A[i].pop_back();}JudgemBelow2(A, Abk);}else{if (k == L){cerr << "Stop without solution";exit(-1);}else{CalculatAk(A);k += 1;}}}// end of if (abs(A[m][m-1]) >= epsion)}}三、实验结果(1)A经过拟上三角化后得到的矩阵-8.827516758830e-001 -9.933136491826e-002 -1.103349285994e+000-7.600443585637e-001 1.549101079914e-001 -1.946591862872e+000-8.782436382928e-002 -9.255889387184e-001 6.032599440534e-0011.518860956469e-001-2.347878362416e+000 2.372370104937e+000 1.819290822208e+0003.237804101546e-001 2.205798440320e-001 2.102692662546e+0001.816138086098e-001 1.278839089990e+000 -6.380578124405e-001-4.154075603804e-0011.0556********e-016 1.728274599968e+000 -1.171467642785e+000-1.243839262699e+000 -6.399758341743e-001 -2.002833079037e+0002.924947206124e-001 -6.412830068395e-001 9.783997621285e-0022.557763574160e-001-5.393383812774e-017 -3.165873865181e-017 -1.291669534130e+000-1.111603513396e+000 1.171346824096e+000 -1.307356030021e+0001.803699177750e-001 -4.246385358369e-001 7.988955239304e-0021.608819928069e-0011.533464996622e-017 5.963321406181e-017 0.000000000000e+0001.560126298527e+000 8.125049397515e-001 4.421756832923e-001-3.588616128137e-002 4.691742313671e-001 -2.736595050092e-001 -7.359334657750e-0021.300562737229e-016 -3.097060010889e-017 0.000000000000e+0000.000000000000e+000 -7.707773755194e-001 -1.583051425742e+000-3.042843176799e-001 2.528712446035e-001 -6.709925401449e-0012.544619929082e-0011.610216724767e-016 -2.211571837369e-016 0.000000000000e+0000.000000000000e+000 6.483933100712e-017 -7.463453456938e-001-2.708365157019e-002 -9.486521893682e-001 1.195871081495e-0011.929265617952e-0021.368550186199e-016 7.151513190805e-017 0.000000000000e+0000.000000000000e+000 -2.522454384246e-017 1.072074718358e-016-7.701801374364e-001 -4.697623990618e-001 4.988259468008e-0011.137691603776e-001-2.780851300718e-017 -6.708630788363e-017 0.000000000000e+0000.000000000000e+000 -3.282796821065e-017 4.879774287475e-0171.854829286220e-016 7.013167092107e-001 1.582180688475e-0013.862594614233e-001-2.124604440055e-017 -1.707979758930e-016 0.000000000000e+0000.000000000000e+000 1.013496750890e-016 -4.153758325241e-0171.222621691887e-016 -5.551115123126e-017 4.843807602783e-0013.992777995177e-001(2)Q-3.519262579534e-001 4.427591982245e-001 -6.955982513607e-0016.486200753651e-002 3.709718861896e-001 1.855847143605e-001-1.628942319628e-002 -1.181053169648e-001 -5.255375383724e-002 -5.486582943568e-002-9.360277287361e-001 -1.664679186545e-001 2.615299548560e-001 -2.438671728934e-002 -1.394774360893e-001 -6.977585391241e-0026.124472142963e-003 4.440505443139e-002 1.975907909728e-0022.062836970533e-002-4.208697095111e-017 -8.810520554692e-001 -3.989762796959e-0013.720308728479e-002 2.127794064090e-001 1.064463557221e-001-9.343171079758e-003 -6.774200464527e-002 -3.014340698675e-002 -3.146955080444e-002-2.150178169911e-017 4.009681353156e-017 -5.371806806439e-001 -1.234945854205e-001 -7.063151608719e-001 -3.533456368496e-0013.101438948264e-002 2.248676491598e-001 1.000601783527e-0011.044622748702e-0016.113458775639e-018 -3.721194648197e-0177.068175586628e-0189.892235468621e-001 -1.239411731211e-001 -6.200358589825e-0025.442272839461e-003 3.945881637235e-002 1.755813350011e-0021.833059462907e-0025.184948268593e-017 -4.198303559531e-017 3.255071298412e-017-1.527665297025e-017 5.323610690264e-001 -6.733900344896e-0015.910581205868e-002 4.285425323867e-001 1.906901343193e-0011.990794495295e-0016.419444583601e-017 4.121668945107e-017 3.096964582901e-017-5.050360323651e-017 -7.078737686239e-017 -6.0597********e-001 -9.165783032818e-002 -6.645586508974e-001 -2.957110877580e-001 -3.0872********e-0015.455993559780e-017 -9.724896332186e-017 3.956603694870e-0171.913857001710e-018 -4.316583456405e-0172.797376665557e-0179.933396625117e-001 -9.690440311939e-002 -4.311990584470e-002-4.501694411183e-002-1.108640877071e-017 4.655237056115e-017 -1.0722********e-017 -9.470236121745e-018 4.277993227986e-017 8.866601870176e-017 -2.516725033065e-016 5.410088006061e-001 -5.817540838226e-001 -6.0734********e-001-8.470152033092e-018 9.650816729410e-017 -1.429362211392e-017 -2.789222052040e-017 -3.690793770141e-017 -8.090765462521e-017 -1.964050295697e-016 -6.772274683437e-017 -7.221591336735e-0016.917269588876e-001(3)R2.508342744917e+000 -2.185646885493e+000 -1.314609070786e+000-3.558787493836e-002 -2.609857850388e-001 -1.283121847090e+000 -1.390878610606e-001 -8.712897972161e-001 3.849367902971e-0013.353802899665e-0012.100627753398e-016 -1.961603277854e+000 2.407523727633e-0017.054714572823e-001 5.957204318279e-001 5.526978774676e-001-3.268209924413e-001 -5.769498668364e-002 2.871129330189e-001 -8.895128754189e-002-3.300197935770e-016 -1.872873410421e-016 2.404534601993e+0001.706758096328e+000 -4.239566704091e-001 3.405332305815e+000-1.050017655852e-001 1.462257102734e+000 -6.684487469283e-001 -4.027*********e-0013.0773********e-017 1.746386351950e-017 0.000000000000e+0001.577122080722e+000 6.399535133956e-001 3.468127872427e-001-5.701786649768e-002 4.014788054433e-001 -2.222476176311e-001 -6.317059236442e-0021.760039865880e-016 9.988285339980e-017 0.000000000000e+0000.000000000000e+000 -1.447846997770e+000 -1.415724007744e+000-2.806139044665e-001 -2.817910521892e-001 -4.611434881851e-0021.996629079956e-0018.804885435596e-017 4.996802050991e-017 0.000000000000e+0000.000000000000e+000 8.831633340975e-017 1.231641451542e+0001.619701003419e-001 1.962638275504e-001 5.350035621760e-001-1.509273424767e-001-7.728357669400e-018 -4.385868928757e-018 0.000000000000e+0000.000000000000e+000 -7.751835246841e-018 -1.279231078565e-017-7.753441914209e-001 -3.464514508821e-001 4.312226803504e-0011.234643696237e-001-5.603391361152e-017 -3.179943413314e-017 0.000000000000e+0000.000000000000e+000 -5.620413613517e-017 -9.274974944455e-0170.000000000000e+000 1.296312940612e+000 -4.288053318338e-0012.737334158165e-001-2.493361499851e-017 -1.414991023727e-017 0.000000000000e+0000.000000000000e+000 -2.500935953597e-017 -4.127119443934e-0170.000000000000e+000 0.000000000000e+000 -6.707396440648e-001-4.842320121884e-001-2.603055667460e-017 -1.477242832192e-017 0.000000000000e+0000.000000000000e+000 -2.610963355436e-017 -4.308689959101e-0170.000000000000e+000 0.000000000000e+000 -1.110223024625e-0167.168323926323e-002(4)RQ1.163074414164e+0002.632670934508e+000 -1.772796003272e+000-8.668899138521e-002 3.300503471047e-001 1.455162371214e+000 -9.730650448593e-001 -4.873031174655e-001 -7.756411630489e-001 -3.249201979113e-0011.836115060851e+000 1.144286420080e-001 -9.880381403133e-0015.589725694767e-001 4.694190067101e-002 -2.978478237007e-0011.617130577649e-002 6.936977702522e-001 1.367670571405e-0011.419099231519e-0025.598200524418e-016 -2.118520153533e+000 -1.876189745783e+000-5.407071940597e-001 1.171538359721e+000 -2.550323020223e+0001.691577936540e+000 1.229951613262e+000 1.387947777212e+0008.667502917242e-001-3.179059303049e-017 -5.261714527977e-017 -8.471995127808e-0014.382910468318e-001 -1.008632199185e+000 -7.959374261495e-0014.769258865577e-001 4.072683083890e-001 4.096390493527e-0013.363378940862e-001-3.514195999269e-016 3.391949386044e-017 -2.160938214545e-016 -1.432244342447e+000 -5.742284908055e-001 1.213151477723e+000 -3.457508625575e-001 -4.749853573124e-001 -3.176158274191e-001 -4.294507015032e-002-3.704735750656e-017 -1.0998********e-016 -1.953241363386e-0178.269089741494e-017 6.556779598004e-001 -9.275250974463e-0012.529079844053e-001 6.905949216976e-001 -2.374430675823e-002-2.429781119781e-001-6.420051822287e-017 3.865817713597e-017 -3.806718328740e-0172.129734126613e-017 7.853*********e-017 4.698400884876e-001-2.730776009527e-001 7.821296259798e-001 -9.580964936399e-0027.846239841323e-0021.478496020372e-016 -8.383952267131e-017 9.577540382744e-017-7.120338911078e-017 -1.220876056602e-016 -1.854471832043e-0161.287679058937e+000 -3.576058900348e-001 -4.116725408807e-0033.914268216423e-0014.477158378610e-017 -6.204017427568e-017 3.360322998507e-017-1.133882337819e-017 -2.759056827456e-017 -9.217582575819e-0172.214639994444e-016 -3.628760503545e-001 7.398980975354e-0017.241608309576e-0023.408891482791e-017 2.353495494255e-017 1.932283926688e-017-3.456910153081e-017 -2.015177337156e-017 -8.084422691634e-017 -5.839476980893e-017 5.551115123126e-017 -5.176670596524e-0024.958522909877e-002(5)特征值(6.360627875745e-001,0.000000000000e+000)(5.650488993501e-002,0.000000000000e+000)(9.355889078188e-001,0.000000000000e+000)(-9.805309562902e-001,1.139489127430e-001)(-9.805309562902e-001,-1.139489127430e-001)(1.577548557113e+000,0.000000000000e+000)(-1.484039822259e+000,0.000000000000e+000)(-2.323496210212e+000,8.930405177200e-001)(-2.323496210212e+000,-8.930405177200e-001)(3.383039617436e+000,0.000000000000e+000)(6)实特征值的特征向量4.745031936539e+0003.157868541750e+0001.729946912420e+001-1.980049331455e+000-3.187521973524e+0017.794009603201e+000-1.004255685845e+0011.670757770480e+0011.310524273054e+0011.000000000001e+000下一个实特征值对应的特征向量:-5.105003830625e+000-4.886319842360e+0009.505161576151e+000-6.788331788214e-001-9.604334110499e+000-3.0457********e+0001.574873885602e+001-7.395037126277e+000-7.109654943661e+0001.000000000001e+000下一个实特征值对应的特征向量:2.792418944529e+0001.598236841512e+000-5.207507040911e-001-1.667886451702e+000-1.225708535859e+0017.241214790777e+000-5.398214501433e+0002.841008912974e+001-1.216518754416e+0011.000000000001e+000下一个实特征值对应的特征向量:6.217350824581e-001-1.115111815226e-001-2.483773580804e+000-1.306860840421e+000-3.815605442533e+0008.117305509395e+000-1.239170883675e+000-6.800309586197e-0012.691900144840e+0001.000000000001e+000下一个实特征值对应的特征向量:-1.730784582112e+0012.408192534967e+0014.133852365119e-001-8.572044074538e+0009.287334657928e-002-7.832726042776e-002-6.374274025716e-001-3.403204760832e-001。
迭代格式的比较1、自定义函数:function y=fun1(x)y=(3*x+1)/x^2;主程序:x0=input('Please input the initial value£ºx0=');k=input('Please input the number of iterations£ºk='); x(1)=x0;i=1;while i<=kx(i+1)=fun1(x(i));i=i+1;xk=x(i);endfprintf(' x=%f\n',x);运行结果:Please input the initial value:x0=1Please input the number of iterations:k=5x=1.000000x=4.000000x=0.812500x=5.207101x=0.613018x=7.554877结论:发散2、自定义函数:function y=fun2(x)y=(x^3-1)/3;主程序:x0=input('Please input the initial value£ºx0=');k=input('Please input the number of iterations£ºk='); x(1)=x0;i=1;while i<=kx(i+1)=fun2(x(i));i=i+1;xk=x(i);endfprintf(' x=%f\n',x);运行结果:Please input the initial value:x0=1Please input the number of iterations:k=8x=1.000000x=0.000000x=-0.333333x=-0.345679x=-0.347102x=-0.347273x=-0.347294x=-0.347296x=-0.347296结论:收敛3、自定义函数:function y=fun3(x)y=(3*x+1)^(1/3);主程序:x0=input('Please input the initial value£ºx0=');k=input('Please input the number of iterations£ºk='); x(1)=x0;i=1;while i<=kx(i+1)=fun3(x(i));i=i+1;xk=x(i);endfprintf(' x=%f\n',x);运行结果:Please input the initial value:x0=1Please input the number of iterations:k=11x=1.000000x=1.587401x=1.792790x=1.854542x=1.872325x=1.877384x=1.878819x=1.879225x=1.879340x=1.879372x=1.879382x=1.879384结论:收敛4、自定义函数:function y=fun4(x)y=1/(x^2-3);主程序:x0=input('Please input the initial value£ºx0=');k=input('Please input the number of iterations£ºk='); x(1)=x0;i=1;while i<=kx(i+1)=fun4(x(i));i=i+1;xk=x(i);endfprintf(' x=%f\n',x);运行结果:Please input the initial value:x0=1Please input the number of iterations:k=9x=1.000000x=-0.500000x=-0.363636x=-0.348703x=-0.347414x=-0.347306x=-0.347297x=-0.347296x=-0.347296x=-0.347296结论:收敛5、自定义函数:function y=fun5(x)y=sqrt(3+1/x);主程序:x0=input('Please input the initial value£ºx0=');k=input('Please input the number of iterations£ºk='); x(1)=x0;i=1;while i<=kx(i+1)=fun5(x(i));i=i+1;xk=x(i);endfprintf(' x=%f\n',x);运行结果:Please input the initial value:x0=1Please input the number of iterations:k=6x=1.000000x=2.000000x=1.870829x=1.880033x=1.879336x=1.879389x=1.879385结论:收敛6、自定义函数:function y=fun6(x)y=x-1/3*((x^3-3*x-1)/(x^2-1));主程序:x0=input('Please input the initial value£ºx0=');k=input('Please input the number of iterations£ºk='); x(1)=x0;i=1;while i<=kx(i+1)=fun6(x(i));i=i+1;xk=x(i);endfprintf(' x=%f\n',x);运行结果:Please input the initial value:x0=3Please input the number of iterations:k=6x=3.000000x=2.291667x=1.965507x=1.884402x=1.879404x=1.879385x=1.879385结论:收敛要求2,输出迭代次数:自定义函数:interation.m%x0为初始值,k为最大迭代次数,e为控制精度function interation(x0,k,e)x(1)=x0;i=1;while i<=kx(i+1)=fun6(x(i));if abs(x(i+1)-x(i))<efprintf(' the number of iterations: n=%f\n',i);breakendi=i+1;endx=x(i);fprintf(' a root of the original equation: x=%8.6f\n',x);取形式6为例,运行结果:>>interation(5,24,0.00001)the number of iterations: n=7.000000a root of the original equation: x=1.879385。
《数值分析》计算实习报告第一题院系:机械工程及自动化学院_学号: _____姓名: _ ______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=时,计算的结果如下:此结果即为上文中的正确计算结果。
一、问题提出设方程f(x)=x 3-3x-1=0有三个实根 x *1=1.8793 , x *2=-0.34727 ,x *3=-1.53209现采用下面六种不同计算格式,求 f(x)=0的根 x *1 或x *2 。
1、 x = 213xx + 2、x = 313-x3、 x = 313+x4、 x = 312-x 5、 x = x13+6、 x = x - ()1133123---x x x二、目的和意义1、通过实验进一步了解方程求根的算法;2、认识选择计算格式的重要性;3、掌握迭代算法和精度控制;4、明确迭代收敛性与初值选取的关系。
三、结构程序设计本程序实在matlab 软件上进行操作的。
首先建立一个空白的M-文件。
在编辑器中输入以下内容,并保存。
function [X1,m,n,q]=shizi1(p) x=zeros(100,1); x=double(x);x(1,1)=p;i=1;deltax=100;while (i<100 & deltax > 0.000001)x(i+1,1)=(3*x(i,1)+1)/x(i,1)^2deltax=abs(x(i+1,1)-x(i,1));i=i+1;endX1=x(1,1);m=i;n=x(i,1);q=deltax;以上是运行函数,下一步在建立一个执行M-文件,输入以下内容,并保存。
其中X1为初始值,m为迭代次数,n为最后得到的值,q为|x k+1-x k|。
clear all;clc;p=1.8;[X1,m,n,q]=shizi1(p)1、对第一个迭代公式,在执行文件中输入p=1.8;[X1,m,n,q]=shizi1(p)。
得到如下结果如下:初值为1.8,迭代100次,精度为10-6。
可见该迭代公式是发散的,将初值改为-1.5,其他均条件不变。
p=-1.5;[X1,m,n,q]=shizi1(p)改变初值后可以得到一个接近真值的结果x*3的结果ans=-1.5321。