大连理工大学 2015年矩阵上机编程作业

  • 格式:doc
  • 大小:841.04 KB
  • 文档页数:50

本答案说明:该1-10题所有结果均用C++完成,其中有些题目编写的代码比较长,为了使得看起来比较容易懂,程序的架构清晰,把main()函数提到了前面,如果想要调试的话,请把main()函数之后附的的各种实现函数提前,程序就能正常运行。

该11-15题需要作图,所以采用Matlab编程实现。

1.设, 其精确值为.(1)编制按从大到小的顺序, 计算的通用程序(2)编制按从小到大的顺序, 计算的通用程序(3)按两种顺序分别计算并指出有效位数(编制程序时用单精度)(4)通过本上机题,你明白了什么答案:通过分析我们发现利用编制从大到小得到的精度较高,一般先加小数再加大数,精度会发生缺失。

运行结果如下:代码如下:#include <iostream.h>//第1问void nFromMintoMax(float n){float sum;sum=0.0;for(float i=2;i<n;i++){sum=sum+ (float)1.0/(i*i-1);}cout<<"编制从大到小的计算结果"<<" "<<sum<<endl;}//第2问void nFromMaxtoMin(float n){float sum;sum=0.0;for(float i=n;i<1;i--){sum=sum+(float)1.0/(i*i-1);}cout<<"编制由小到大的计算结果"<<" "<<sum<<endl;}void main (){cout<<"S(100):"<<endl;nFromMintoMax(100); //调用第一问的函数nFromMaxtoMin(100); //调用第二问的函数cout<<"S(10000):"<<endl;nFromMintoMax(10000);nFromMaxtoMin(10000);cout<<"S(1000000):"<<endl;nFromMintoMax(1000000);nFromMaxtoMin(1000000);}2.秦九韶算法。

已知n次多项式,用秦九韶算法编写通用的程序计算函数在错误!未找到引用源。

点的值,并计算在错误!未找到引用源。

点的值.(提示:编写程序时,输入系数向量和点错误!未找到引用源。

,输出结果,多项式的次数可以通过向量的长度来判断)秦九韶算法公式为:秦九韶算法输出结果:秦九韶算法代码:#include <iostream.h>//秦九韶算法,a代表系数,n代表系数总数void QinJS(float a[],int n,float x){float sum=a[0];for(int i=0;i+1<n;i=i+1){sum=sum*x+a[i+1];}cout<<"秦九韶算法计算结果为"<<" "<<sum<<endl;}void main(){cout <<"请输入X"<<endl;float x;cin>>x;cout <<"请依次输入系数总数n和n个系数"<<endl;int n;cin>>n;float a[10];for(int i=0;i<n;i++){float j;cin>>j;a[i]=j;// cout<<a[i]<<endl;}//调用秦九韶算法QinJS(a,n,x);}3.分别用Gauss消元法和列主元消去法编程求解方程组Ax=b,其中,实验结果为:实验代码为:#include <iostream.h>#include <math.h>#include<iomanip.h>void main (){//Gauss 消元double a[9][10]={{31,-13,0,0,0,-10,0,0,0,-15},{-13,35,-9,0,-11,0,0,0,0,-27},{0,-9,31,-10,0,0,0,0,0,-23},{0,0,-10,79,-30,0,0,0,-9,0},{0,0,0,-30,57,-7,0,-5,0,-20},{0,0,0,0,-7,47,-30,0,0,12},{0,0,0,0,0,-30,41,0,0,-7},{0,0,0,0,-5,0,0,27,-2,7},{0,0,0,-9,0,0,0,-2,29,10}};Gauss(a,9,10); //高斯消元cout<<"Gauss消元的上三角矩阵为"<<endl;display(a,9,10); //显示矩阵SolveOne(a,9,10); //求解Ax=b,A为上三角矩阵//列主元消元double b[9][10]={{31,-13,0,0,0,-10,0,0,0,-15},{-13,35,-9,0,-11,0,0,0,0,-27},{0,-9,31,-10,0,0,0,0,0,-23},{0,0,-10,79,-30,0,0,0,-9,0},{0,0,0,-30,57,-7,0,-5,0,-20},{0,0,0,0,-7,47,-30,0,0,12},{0,0,0,0,0,-30,41,0,0,-7},{0,0,0,0,-5,0,0,27,-2,7},{0,0,0,-9,0,0,0,-2,29,10}};Lie(b,9,10); //列主元消元cout<<"列主元消元的上三角矩阵为"<<endl;display(b,9,10); //显示SolveOne(b,9,10); //求解Ax=b, A为上三角矩阵}//输出二维数组元素,这个函数是用来显示矩阵,用来调试void display(double a[9][10],int r_size1,int r_size2){for(int i=0; i<r_size1; i++){for(int j=0; j<r_size2; j++){cout<<setprecision(8)<<setw(12)<<a[i][j]<<"";if(j+1==r_size2){cout<<endl;}}}}//Ax=b的解答,A为上三角矩阵void SolveOne(double a[9][10],int m,int n){int j=n-2;double answer[9];for (int s=m-1;s>=0;s--){answer[j]=a[s][n-1]/a[s][j];for(int i=0;i<=s-1;i++){a[i][n-1]=a[i][n-1]-answer[j]*a[i][j];}j--;}cout<<"解答的结果为:"<<endl;for(int i=0;i<9;i++){cout<<setprecision(8)<<setw(12)<<answer[i]<<" ";}cout<<endl;}//Gauss 消元解法//先转化为上三角矩阵void Gauss(double a[9][10],int m,int n){double r[9]; //r为每次的倍数int k=0;for (int nowi=0,nowj=0;nowi<m-1 && nowj<n-1;nowi++,nowj++){ // 计算要乘的倍数for(int s=nowi;s<m;s++){r[s]=a[s+1][nowj]/a[nowi][nowj];}// 每次根据每行的倍数将所有数处理一遍,变成(1,0,0,0)Tfor (int i=nowi;i<m-1;i++){for(int j=nowj;j<n;j++){a[i+1][j]=a[i+1][j]-r[i]*a[nowi][j];}}}}// 发现绝对值最大的元素所在一行和当前的一行做交换void change(double a[9][10],int m,int n,int nowi,int nowj){int record=nowi;//记录该和哪一行做交换bool flag=true; //标志是否需要做交换double max=a[nowi][nowj];for(int i=nowi+1;i<m-1;i++){if(max<fabs(a[i][nowj])){max=a[i][nowj];record=i;flag=false;}}//行与行之间交换if(flag==false){for(int j=nowj;j<n;j++){double s;s=a[nowi][j];a[nowi][j]=a[record][j];a[record][j]=s;}}}//列主元消元解法,转化为上三角矩阵void Lie(double a[9][10],int m,int n){double r[9]; //r为每次的倍数int k=0;for (int nowi=0,nowj=0;nowi<m-1 && nowj<n-1;nowi++,nowj++){//与Guass不同的时,每次要检查是否需要交换行change(a,9,10,nowi,nowj);// 计算要乘的倍数for(int s=nowi;s<m;s++){r[s]=a[s+1][nowj]/a[nowi][nowj];}// 每次根据每行的倍数将所有数处理一遍,变成(1,0,0,0)Tfor (int i=nowi;i<m-1;i++){for(int j=nowj;j<n;j++){a[i+1][j]=a[i+1][j]-r[i]*a[nowi][j];}}}}4.编程求解题3中矩阵错误!未找到引用源。

的LU分解及列主元的LU分解(求出L,U和P),并用LU分解的方法求A的逆矩阵及A的行列式运行实验结果如下图:其代码如下所示:#include <iostream.h>#include<iomanip.h>void main(){float a[9][9]={{31,-13,0,0,0,-10,0,0,0},{-13,35,-9,0,-11,0,0,0,0},{0,-9,31,-10,0,0,0,0,0},{0,0,-10,79,-30,0,0,0,-9},{0,0,0,-30,57,-7,0,-5,0},{0,0,0,0,-7,47,-30,0,0},{0,0,0,0,0,-30,41,0,0},{0,0,0,0,-5,0,0,27,-2},{0,0,0,-9,0,0,0,-2,29}};float L[9][9];LU(a,L,9,9); //LU分解cout<<"LU分解的L矩阵为"<<endl;display(L,9,9);cout<<"LU分解的U矩阵为"<<endl;display(a,9,9);cout<<endl;}//定义矩阵相乘void XMatirx(float LL[9][9],float a[9][9],int m,int n){ float c[9][9];for (int i=0;i<m;i++){for(int j=0;j<n;j++){float sum=0;for(int s=0;s<n;s++){sum=sum+LL[i][s]*a[s][j];if(i==0 && j==0 && s==0){// cout<<LL[i][s]<<" "<<a[0][0]<<endl;// cout<<LL[i][s]*a[s][j]<<endl;}}c[i][j]=sum;}}//写回到B数组中,即为最终的Ufor (int i1=0;i1<m;i1++){for(int j=0;j<n;j++){a[i1][j]=c[i1][j];}}}//输出二维数组元素,这个函数是用来显示矩阵,用来调试void display(float a[9][9],int r_size1,int r_size2){for(int i=0; i<r_size1; i++){for(int j=0; j<r_size2; j++){cout<<setprecision(3)<<setw(12)<<a[i][j]<<"";if(j+1==r_size2){cout<<endl;}}}}//LU 分解void LU(float a[9][9],float L[9][9],int m,int n){float r[9]; //r为每次的倍数int k=0;float LL[9][9];//临时矩阵专门用来存储当前的L1,L2,L3 //初始化L矩阵for(int si=0;si<m;si++){for(int sj=0;sj<n;sj++){if(si==sj){L[si][sj]=1;} else{L[si][sj]=0;}}}for (int nowi=0,nowj=0;nowi<m-1 && nowj<n-1;nowi++,nowj++){ //初始化LL矩阵for(int si=0;si<m;si++){for(int sj=0;sj<n;sj++){if(si==sj){LL[si][sj]=1;} else{LL[si][sj]=0;}}}// display(LL,9,9);// 计算要乘的倍数for(int s=nowi;s<m-1;s++){r[s]=a[s+1][nowj]/a[nowi][nowj];//填充L矩阵L[s+1][nowj]=r[s];LL[s+1][nowj]=-r[s];}//调用矩阵相乘公式XMatirx(LL,a,9,9);}}5.编制程序求解矩阵A的cholesky分解,并用程序求解方程组Ax=b,其中解答:使用上述矩阵,所得到的结果如图:其代码为://主函数代码:#include <iostream.h>#include <math.h>#include<iomanip.h>void main(){double a[4][4]={{2,1,-1,1},{1,5,2,7},{-1,2,10,1},{1,7,1,11}};double answer[4]={13,-9,6,0};double L[4][4]; //L 矩阵double LT[4][4]; // LT矩阵InitL(L,4,4);//初始化L矩阵Choskey(a,L,4,4); //进行Choskey分解display(L,LT,4,4);//显示L 和LT//L*y=b, LT*x=ySolveOne(L,answer,4,4); // 先利用上三角矩阵求解ySolveTwo(LT,answer,4,4); // 利用下三角矩阵求解x}//Choskey分解,分解成L和LTvoid Choskey(double a[4][4],double L[4][4],int m,int n){for(int j=0;j<n;j++){for(int i=j;i<m;i++){if(i==j){double sum=0;for(int k=0;k<j;k++){sum=sum+L[j][k]*L[j][k];}L[i][j]=sqrt(a[i][j]-sum);}else{double sum=0;for(int k=0;k<j;k++){sum=sum+L[i][k]*L[j][k];}L[i][j]=(a[i][j]-sum)/L[j][j];}}}}// 初始化L矩阵void InitL(double L[4][4],int m,int n){for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(i<j){L[i][j]=0;}}}}//显示L和LT矩阵void display(double L[4][4],double LT[4][4],int m,int n){cout<<"Choskey分解的L矩阵为:"<<endl;for(int Li=0;Li<m;Li++){for(int j=0;j<n;j++){cout<<setprecision(8)<<setw(12)<<L[Li][j]<<"";}cout<<endl;}cout<<"Choskey分解的LT矩阵为:"<<endl;for(int i=0;i<m;i++){for(int j=0;j<n;j++){cout<<setprecision(8)<<setw(12)<<L[j][i]<<"";LT[i][j]=L[j][i];}cout<<endl;}}//Ax=b的解答,A为上三角矩阵void SolveTwo(double LT[4][4],double answer[4],int m,int n){ int j=n-1;for (int s=m-1;s>=0;s--){answer[j]=answer[j]/LT[s][j];for(int i=s-1;i>=0;i--){answer[i]=answer[i]-answer[j]*LT[i][j];}j--;}cout<<"解答的最终结果X为:"<<endl;for(int i=0;i<4;i++){cout<<setprecision(8)<<setw(12)<<answer[i]<<" ";}cout<<endl;}//Ax=b的解答,A为下三角矩阵void SolveOne(double L[4][4],double answer[4],int m,int n){int j=0;for (int s=j;s<m;s++){answer[j]=answer[j]/L[s][j];for(int i=j+1;i<m;i++){answer[i]=answer[i]-answer[j]*L[i][j];}j++;}cout<<"解答的中间结果Y为:"<<endl;for(int i=0;i<4;i++){cout<<setprecision(8)<<setw(12)<<answer[i]<<" ";}cout<<endl;}6.用追赶法编制程序求解方程组Ax=b,其中,追赶法的核心就是Ax=b,→LUx=b→Ly=bUx=y所以思路为:首先进行LU分解,然后利用上述所示公式进行求解,可以看到,该题只不过是结合了第三题和第五题:实验结果如图所示:实验的代码为:因为本题主要是把LU分解和第五题的分两步解答结合起来,所以只给出了主函数,里面的各种调用函数,都可以在第三题和第五题的代码中找到,只需要改变一下二维数组的大小即可,所以不再详述。