c语言编程求解线性方程组论文
线性方程组的数值算法C语言实现(附代码)

线性方程组AX=B 的数值计算方法实验一、 实验描述:随着科学技术的发展,线性代数作为高等数学的一个重要组成部分,在科学实践中得到广泛的应用。
本实验的通过C 语言的算法设计以及编程,来实现高斯消元法、三角分解法和解线性方程组的迭代法(雅可比迭代法和高斯-赛德尔迭代法),对指定方程组进行求解。
二、 实验原理:1、高斯消去法:运用高斯消去法解方程组,通常会用到初等变换,以此来得到与原系数矩阵等价的系数矩阵,达到消元的目的。
初等变换有三种:(a)、(交换变换)对调方程组两行;(b)、用非零常数乘以方程组的某一行;(c)、将方程组的某一行乘以一个非零常数,再加到另一行。
通常利用(c),即用一个方程乘以一个常数,再减去另一个方程来置换另一个方程。
在方程组的增广矩阵中用类似的变换,可以化简系数矩阵,求出其中一个解,然后利用回代法,就可以解出所有的解。
2、选主元:若在解方程组过程中,系数矩阵上的对角元素为零的话,会导致解出的结果不正确。
所以在解方程组过程中要避免此种情况的出现,这就需要选择行的判定条件。
经过行变换,使矩阵对角元素均不为零。
这个过程称为选主元。
选主元分平凡选主元和偏序选主元两种。
平凡选主元:如果()0p pp a ≠,不交换行;如果()0p pp a =,寻找第p 行下满足()0p pp a ≠的第一行,设行数为k ,然后交换第k 行和第p 行。
这样新主元就是非零主元。
偏序选主元:为了减小误差的传播,偏序选主元策略首先检查位于主对角线或主对角线下方第p 列的所有元素,确定行k ,它的元素绝对值最大。
然后如果k p >,则交换第k 行和第p 行。
通常用偏序选主元,可以减小计算误差。
3、三角分解法:由于求解上三角或下三角线性方程组很容易所以在解线性方程组时,可将系数矩阵分解为下三角矩阵和上三角矩阵。
其中下三角矩阵的主对角线为1,上三角矩阵的对角线元素非零。
有如下定理:如果非奇异矩阵A 可表示为下三角矩阵L 和上三角矩阵U 的乘积: A LU = (1) 则A 存在一个三角分解。
线性方程组的数值算法C语言实现(附代码)

线性方程组AX=B 的数值计算方法实验一、 实验描述:随着科学技术的发展,线性代数作为高等数学的一个重要组成部分,在科学实践中得到广泛的应用。
本实验的通过C 语言的算法设计以及编程,来实现高斯消元法、三角分解法和解线性方程组的迭代法(雅可比迭代法和高斯-赛德尔迭代法),对指定方程组进行求解。
二、 实验原理:1、高斯消去法:运用高斯消去法解方程组,通常会用到初等变换,以此来得到与原系数矩阵等价的系数矩阵,达到消元的目的。
初等变换有三种:(a)、(交换变换)对调方程组两行;(b)、用非零常数乘以方程组的某一行;(c)、将方程组的某一行乘以一个非零常数,再加到另一行。
通常利用(c),即用一个方程乘以一个常数,再减去另一个方程来置换另一个方程。
在方程组的增广矩阵中用类似的变换,可以化简系数矩阵,求出其中一个解,然后利用回代法,就可以解出所有的解。
2、选主元:若在解方程组过程中,系数矩阵上的对角元素为零的话,会导致解出的结果不正确。
所以在解方程组过程中要避免此种情况的出现,这就需要选择行的判定条件。
经过行变换,使矩阵对角元素均不为零。
这个过程称为选主元。
选主元分平凡选主元和偏序选主元两种。
平凡选主元:如果()0p pp a ≠,不交换行;如果()0p pp a =,寻找第p 行下满足()0p pp a ≠的第一行,设行数为k ,然后交换第k 行和第p 行。
这样新主元就是非零主元。
偏序选主元:为了减小误差的传播,偏序选主元策略首先检查位于主对角线或主对角线下方第p 列的所有元素,确定行k ,它的元素绝对值最大。
然后如果k p >,则交换第k 行和第p 行。
通常用偏序选主元,可以减小计算误差。
3、三角分解法:由于求解上三角或下三角线性方程组很容易所以在解线性方程组时,可将系数矩阵分解为下三角矩阵和上三角矩阵。
其中下三角矩阵的主对角线为1,上三角矩阵的对角线元素非零。
有如下定理:如果非奇异矩阵A 可表示为下三角矩阵L 和上三角矩阵U 的乘积: A LU = (1) 则A 存在一个三角分解。
C语言LU分解法实现解线性方程组

C语言LU分解法实现解线性方程组C语言LU分解法实现解线性方程组#include#include//LU分解法实现解线性方程组double sumU(double L[5][5] ,double U[5][5], int i, int j ){ double sU = 0.0;for (int k = 1; k <= i-1 ; k++){sU += L[i-1][k-1] * U[k-1][j-1];}return sU;}//计算求和1double sumL(double L[5][5] ,double U[5][5], int i, int j ){ double sL = 0.0;for (int k = 0; k <= j-1; k++){sL += L[i-1][k-1] * U[k-1][j-1];}return sL;}//计算求和2double sumY(double L[5][5] ,double y[5],int i){double sY=0.0;for (int k = 1; k <= i - 1; k++){sY += L[i-1][k-1] * y[k-1];}return sY;}//计算求和3double sumX(double U[5][5] ,double x[5],int i ,int m){double sX = 0.0;for (int k = i+1; k <= m; k++){sX += U[i-1][k-1] * x[k-1];}return sX;}//计算求和4int main(){double a[5][5] = {4,5.3,-5.6,-3,-3.4,5,-2.1,3.2,4,-8,2,-4,-7.2,-5,-2.4,5,-3,-8,2.3,3,4.2,-3,0,0,-2};//将系数存入二维数组double L[5][5] = {0};double U[5][5] = {0};//初始化部分double b[5] = {100.16,-75.72,98.2,57.1,3.72};int n = 5;//n阶//输出[Ab]printf("[A]:\n");for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){printf("%f\t", a[i-1][j-1]);}printf("\n");}//计算L,Ufor (int i = 1; i <= n; i++){L[i-1][i-1] = 1;//对角线元素为1for (int j = i; j <= n; j++)//由于数组下标从0开始所以i-1,j-1U[i-1][j-1] = a[i-1][j-1] - sumU(L,U,i,j);if(j+1 <= n) L[j][i-1] = (a[j][i-1] - sumL(L,U,j+1,i))/U[i-1][i-1];//i变j+1,j变i }}//输出Uprintf("U:\n");for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){printf("%f\t",U[i-1][j-1]);}printf("\n");}//输出Lprintf("L:\n");for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){printf("%f\t",L[i-1][j-1]);}printf("\n");}//由Ly=b 求ydouble y[5] = {0.0};y[0] = b[0];//y(1) = b(1);for (int i = 2; i <= n; i++)y[i-1] = b[i-1] - sumY(L,y,i);}//由Ux=y 求xdouble x[5] = {0.0};for (int i = n; i >= 1; i--){x[i-1] =( y[i-1] - sumX(U,x,i,n))/ U[i-1][i-1]; } //输出yprintf("y:\n");for (int i = 0; i < n; i++){printf("%f\n",y[i]);}printf("\n");//输出xprintf("x:\n");for (int i = 0; i < n; i++){printf("%f\n",x[i]);}printf("\n");system("pause");return 0;}。
线性方程组求解.cpp

#include <stdio.h>#include <math.h>#include <stdlib.h>#define MAX 20 //定义最大的方程组中方程个数double a[MAX+1][MAX+2] ; //方程组系数存放的增广矩阵存放数组double b[MAX+1][MAX+2] ;int n ; //方程的实际个数int xxx = 0; //是否初始化void init()//输入线性方程组{xxx= 1;printf("\n\t请输入方程组的方程个数: ");scanf ("%d",&n);if( n > MAX )//输入的数超过了定义的最大方程个数,退出{printf("sorry,can not deal !\n\n");printf("最大能处理的方程组为%d阶方程组\n\n,MAX");exit(0);}printf("\n请依次输入方程组的方程的系数(顺序从上到下,从左至右):\n"); for(int i = 1 ; i < n+1 ; i++ )//n行n+1列的增广矩阵for(int j = 1 ; j < n+2 ; j++ )scanf ("%lf",&a[i][j]);for(int i = 1 ; i < n+1 ; i++ ) //备份for(int j = 1 ; j < n+2 ; j++ )b[i][j]=a[i][j];}void reset()//将数组a还原成初始状态{for(int i = 1 ; i < n+1 ; i++ )for(int j = 1 ; j < n+2 ; j++ )a[i][j]=b[i][j];}void display()//输出增光矩阵{for(int i = 1 ; i < n+1 ; i++ ){for(int j = 1 ; j < n+2 ; j++ )printf("%.3f ",a[i][j]);printf("\n");}}void print()//输出线性方程组{int count=0;//记录某一行中系数为0的个数for(int i = 1 ; i < n+1 ; i++ )for(int j = 1 ; j < n+2 ; j++ ){if( a[i][j] == 0 && j != n+1)count ++ ;else{if( j == 1 || count == j-1)//系数为第一项或者该项之前的所有项的系数都是0printf ("%.3f X%d ",a[i][j],j);//小数后面保留三位elseif( j == n+1 ){printf(" = %.3f\n",a[i][n+1]);count =0;}elsea[i][j]>0 ? printf (" + %.3f X%d ",fabs(a[i][j]),j): printf (" - %.3f X%d ",fabs(a[i][j]),j);}}}void selectMainEle(int k)//选取第k列的主元{double mainEle = fabs(a[k][k]) ,temp=0;int j = k ;//用变量j记住主元初始位置for(int i = k+1 ; i < n+1 ; i++ )//选出绝对值最大的数if( mainEle < fabs(a[i][k])){mainEle = fabs(a[i][k]) ;j = i; //j记录主元(列中的最大数)的行数}if( k != j ) //初始值不是最大值,k,j换行for(int i = 1 ; i < n+2 ; i++ ){temp = a[k][i] ;a[k][i] = a[j][i] ;a[j][i] = temp ;}}void printit()//输出方程组的根{printf("\n\n求解的方程组的根为:\n");for(int i=1;i<n+1;i++){if(i%4==0) printf("\n");//每一行输出三个解 printf("X%d=%.3f ",i,a[i][n+1]);}printf("\n");}void gause()//高斯列主消元法核心{printf("线性方程组为:\n");print();//输出输入的方程组for( int k=1 ; k < n ; k ++)//消元过程{selectMainEle(k);for(int i = k+1 ; i < n+1 ; i++ )a[i][k] /= a[k][k];for(int i = k+1 ; i < n+1 ; i++ )for(int j = k+1 ; j < n+2 ; j++ )a[i][j] -= a[i][k] * a[k][j] ;printf("\n消元过程如下:\n");for(int i=1;i<n+1;i++){for(int j=1;j<n+1;j++)if(j<k+1&&i>j)printf("%.4f ",0.0);elseprintf("%.4f ",a[i][j]);printf("\n");}}a[n][n+1] /= a[n][n] ;//回代过程for(int i=n-1 ; i>0 ; i--){double sum=0.0;for(int j=i+1 ;j<n+1 ;j++)sum += a[i][j] * a[j][n+1];a[i][n+1] = (a[i][n+1] - sum)/a[i][i];}printit();}void gauseyuedang()//高斯-约当列主元消去法,高斯列主元消去法的改进{printf("线性方程组为:\n");print();//输出输入的方程组double temp;for( int k=1 ; k < n+1 ; k++)//消元,只保留主元{selectMainEle(k);temp = a[k][k];//用temp记住主元的值for(int i=k ; i < n+2 ; i++)//将主元变为1a[k][i] /= temp;//开始消元,出去主元第k列元素全部消去变为零for(int i = 1 ; i < n+1 ; i++ )//行控制if( i != k ) //行变换不包括当前主元所在行for(int j = k+1 ; j < n+2 ; j++ )//列控制a[i][j]=a[i][j]-a[k][j]*a[i][k];printf("\n消元过程如下:\n");for(int i=1;i<n+1;i++){for(int j=1;j<n+1;j++)if(j<k+1&&i!=j)printf("%.4f ",0.0);elseprintf("%.4f ",a[i][j]);printf("\n");}}printit();//输出方程组的解}void LU()//LU分解法{double sum ;printf("线性方程组为:\n");print();//输出输入的方程组for(int i=2;i<n+1;i++)a[i][1] /= a[1][1];for(int r=2 ; r<n+1 ; r++){for(int i=r ; i<n+1 ; i++)//U变换{sum = 0;for(int k=1;k<r;k++)sum += a[r][k]*a[k][i];a[r][i] -= sum;}for(int i=r+1 ; i<n+1 ; i++)//L变换{sum = 0;for(int k=1 ; k<r ; k++)sum += a[i][k]*a[k][r];a[i][r] = (a[i][r] - sum)/a[r][r];}}printf("\n\nLU分解中的L为:\n");for(int i=1 ; i < n+1 ; i++){for(int j=1 ;j < n+1 ; j++)if(i < j) //上部为0printf("%.3f ",0.0);elsei==j ? printf("%.3f ",1.0): printf("%.3f ",a[i][j]); //主对角线为1 printf("\n");}printf("\n\nLU分解中的U为:\n");for(int i=1 ; i < n+1 ; i++){for(int j=1 ;j < n+1 ; j++)if(i > j) //上部为0printf("%.3f ",0.0);elseprintf("%.3f ",a[i][j]);printf("\n");}for(int i=2;i<n+1;i++)//第一次回带求解{sum=0;for(int k=1;k<i;k++)sum+=a[i][k]*a[k][n+1];a[i][n+1] -= sum;}printf("\n\n第一次求解的方程组(LY=b)的根为:\n");for(int i=1;i<n+1;i++){if(i%4==0) printf("\n");//每一行输出三个解printf("Y%d=%.3f ",i,a[i][n+1]);}a[n][n+1]/=a[n][n];//Xn的值for(int i=n-1;i>0;i--){sum=0;for(int k=i+1;k<n+1;k++)sum+=a[i][k]*a[k][n+1];a[i][n+1] = (a[i][n+1] - sum)/a[i][i];}printf("\n\n第二次求解的方程组(UX=y)的根,即原方程组的解为:\n"); for(int i=1;i<n+1;i++){if(i%4==0) printf("\n");//每一行输出三个解printf("X%d=%.3f ",i,a[i][n+1]);}printf("\n");}void Jacobi()//雅可比迭代法{printf("线性方程组为:\n");print();//输出输入的方程组int count=0;///迭代次数double latest[n+1],old[n+1],temp[n+1],sum,precision,max,temp2;for(int i=1;i<n+1;i++)if(a[i][i] == 0){printf("sorry,主对角线中有数据为0,不能用Jacobi迭代法处理!\n请返回重新选择");return ;}printf("\n输入求解精度值: ");scanf("%lf",&precision);for(int i=1 ; i < n+1 ; i++) //初始状态解为0{latest[i] = 0.0;//新值,下一次迭代结果old[i] = 0.0;//旧值,上一次的迭代结果}printf("Jacobi迭代法迭代过程如下:\n");do{ max =0;printf("\n\n第%d次迭代的结果: ",count++);for(int i=1 ; i<n+1 ; i++){if(i%4==0) printf("\n");//每一行输出三个解printf("X%d=%.4f ",i,old[i]);}for(int i = 1 ; i < n+1 ; i++)//迭代过程,完成新的一组解{sum =0.0;for(int j = 1 ; j < n+1 ; j++)if(j != i) sum = sum + a[i][j] * old[j];latest[i]=(a[i][n+1] - sum)/a[i][i];temp[i] = latest[i];//Y用来记录本次迭代的值temp2 = fabs(latest[i] - old[i]); //新值减旧值if(max < temp2) max = temp2 ;}printf("最大的偏差为:%.4f\n",max);for(int i=1 ; i<n+1 ; i++)old[i] = temp[i]; //将新值保留到old数组} while( max > precision && count <= 100);//前后两次解的偏差满足精度要求或者迭代次数超过100次printf("\n\n第%d次(最后的)求解的方程组的根为:\n",count);for(int i=1;i<n+1;i++){if(i%4==0) printf("\n");//每一行输出三个解printf("X%d=%.4f ",i,old[i]);}printf("\n");}void GS()//高斯-赛德尔迭代法{printf("线性方程组为:\n");print();//输出输入的方程组double precision,sum,X[n+1],max,temp,old;int count=0;///迭代次数for(int i=1;i<n+1;i++)if(a[i][i] == 0){printf("sorry,主对角线中有数据为0,不能用高斯赛德尔迭代法处理!\n请返回重新选择");return ;}printf("\n输入求解精度值: ");scanf("%lf",&precision);for(int i = 1 ; i < n+1 ; i++)// 解初始化为0X[i] = 0.0 ;printf("高斯赛德尔迭代法迭代过程如下:\n");do{printf("\n\n第%d次迭代的结果: ",count++);for(int i=1 ; i<n+1 ; i++){if(i%4==0) printf("\n");//每一行输出三个解printf("X%d=%.5f ",i,X[i]);}for(int i = 1 ; i < n+1 ; i++)//迭代过程,完成新的一组解{sum = 0.0;max = 0.0;old =X[i];for(int j = 1 ; j < n+1 ; j++)if(j != i) sum += a[i][j] * X[j] ;X[i] = (a[i][n+1] - sum) /a[i][i];temp = fabs(X[i]-old);if(max < temp) max = temp;}printf("最大的偏差为:%.5f\n",max);} while(max > precision && count <= 100);//前后两次解的偏差满足精度要求或者迭代次数超过100次printf("\n\n第%d次(最后的)求解的方程组的根为:\n",count);for(int i=1;i<n+1;i++){if(i%4==0) printf("\n");//每一行输出三个解printf("X%d=%.5f ",i,X[i]);}printf("\n");}int main(){int xz;while(1){printf("\t\t\t*****************************************\n");printf("\t\t\t**** \t 0.更改线性方程组 ****\n");printf("\t\t\t**** \t 1.高斯列主消元法 ****\n");printf("\t\t\t**** \t 2.高斯-约当列主消去法 ****\n");printf("\t\t\t**** \t 3.LU分解法 ****\n");printf("\t\t\t**** \t 4.雅各比迭代法 ****\n");printf("\t\t\t**** \t 5.高斯-赛德尔迭代法 ****\n");printf("\t\t\t**** \t 6.退出 ****\n");printf("\t\t\t*****************************************\n");printf("\t请根据相应的代号,从上述方法中选择其一: ");scanf("%d",&xz);switch(xz){case 0: init(); break;case 1: if(xxx){reset();gause();}else{printf("sorry,还没有输入线性方程组!\n");init();}break;//高斯列主消元法case 2: if(xxx){reset();gauseyuedang();}else{printf("sorry,还没有输入线性方程组!\n");init();}break;//高斯-约当列主元消去法case 3: if(xxx){reset();LU();}else{printf("sorry,还没有输入线性方程组!\n");init();}break;case 4:if(xxx){reset();Jacobi();}else{printf("sorry,还没有输入线性方程组!\n");init();}break;case 5: if(xxx){reset();GS();}else{printf("sorry,还没有输入线性方程组!\n");init();}break;case 6: exit(0);default:printf("\n\t错误输入o(︶︿︶)o 唉!\n\n");break;}system("pause");system("cls");}}。
线性方程组求解 高质量C语言程序

课题:线性方程组求解目录课题描述及要求 (2)项目分析 (2)算法流程 (2)方法说明 (3)源代码 (3)程序说明 (6)运行结果 (7)总结 (7)参考文献 (8)线性方程组求解05111114 陈龙一.课题描述和功能要求1.描述:求解线性方程组Ax=b,写成函数。
其中,A为n乘n阶矩阵,x为n元未知向量,b为n个常数组成的矩阵。
2.要求:采用高斯先列主元消元法(也可采用其他方法)求解线性方程组AX=b。
二.项目分析数学上,高斯消去法或称高斯-约当消去法,由高斯和约当得名(很多人将高斯消去作为完整的高斯-约当消去的前半部分),它是线性代数中的一个算法,用于决定线性方程组的解,决定矩阵的秩,以及决定可逆方矩阵的逆。
当用于一个矩阵时,高斯消去产生“行消去梯形形式”。
例如:一个二元一次方程组,设法对每个等式进行变形,使两个等式中的同一个未知数的系数相等,这两个等式相减,得到一个新的等式,在这个新的等式中,细数相等的未知数就被除去了(系数为0)。
同样的也适合多元多次方程组。
我们知道m*n矩阵(用大写字母表示)是一个m行n列的数阵,n维向量(用加粗的小写字母表示)是n个数的数组,也就是一个n*1矩阵(列向量。
我们不考虑行向量)。
另外,大家也都知道矩阵乘法。
因此一个m*n线性方程组可以表示为Ax=b,其中A是由系数aij组成的m*n矩阵即系数矩阵,x是n维的未知数向量,b是m维的结果向量。
如果把向量b写到A的右边得到m*(n+1)的矩阵,得到的新矩阵称为这个方程组的增广矩阵。
每一个方程组均对应于一个增广矩阵。
三.算法流程图四.方法说明(1)第1步消元——在增广矩阵(A,b)第一列中找到绝对值最大的元素,将其所在行与第一行交换(2)第2步消元——在增广矩阵(A,b)中的第二列中(从第二行开始)找到绝对值最大的元素,将其所在行与第二行交换(3)第3步消元——在增广矩阵(A,b)中的第三列中(从第三行开始)找到绝对值最大的元素,将其所在行与第二行交换(4)按x4- x3- x2- x1的顺序回代求解出方程组的解。
C++课程设计高斯消元法求线性代数方程组的解

C++课程设计高斯消元法求线性代数方程组的解第一篇:C++课程设计高斯消元法求线性代数方程组的解河北工业大学计算机软件技术基础(VC)课程设计报告学院管理班级管理104班姓名杨立宝 __ 学号 101707____ 成绩 __ ____一、题目:求线性代数方程组的解(高斯消去法)(C13)二、设计思路1、总体设计1)分析程序的功能第一:编写输入程序,通过键盘先输入对应的已知量及函数的大小n和系数a[i]和得数b[i]。
第二:编写中间程序,通过函数的调用先定义线性代数方程,然后通过程序求出方程的梯形矩阵系数,并最终得出结果。
第三编写输出程序,输出最终结果。
2)系统总体结构:设计程序的组成模块,简述各模块功能。
模块一:各函数的具体内容A:三个输入函数,分别输入n,一维数组,二维数组。
即输入已知量。
B:中间运算函数,计算是使得方程系数所成的矩阵成梯形矩阵,未知数的结果。
即计算中间变量及结果。
C:最后输出函数,输出最后计算结果。
模块二:各函数原型的声明 a写头文件。
b变量声明:存放输入数据的数组的声明,存放中间变量的数组的声明,存放运算结果的数组的声明。
分别存放对应数据。
c输入有关操作的文字d函数调用,在运算中自动调用对应的函数解决对应问题。
模块三:主函数2、各功能模块的设计:说明各功能模块的实现方法模块一:各个函数的声明,直接声明。
模块二:各函数都通过for循环来实现各个数组之间的基本运算。
3、设计中的主要困难及解决方案在这部分论述设计中遇到的主要困难及解决方案。
1)困难1 函数调用是怎么用?解决方案:仔细阅读课本,以及同学之间的讨论,和老师的帮助。
4、你所设计的程序最终完成的功能1)说明你编制的程序能完成的功能输入线性代数的系数后,运行程序即可得到梯形矩阵和结果。
2)准备的测试数据及运行结果三、程序清单如果是使用一个文件完成的程序,只需列出程序代码。
如果是使用多文件完成的程序,首先说明程序中的代码存放在哪些文件中,说明文件名(例如:本程序包含first.cpp、second.cpp、third.cpp和all.h四个文件);然后依次给出每个文件名及该文件清单,例如:#include const N= 10;//设定矩阵大小范围 /* * 使用已经求出的x,向前计算x(供getx()调用)* double a[][] 系数矩阵 * double x[] 方程组解 * int i 解的序号 * int n 矩阵大小 * return 公式中需要的和 */ double getm(double a[N][N], double x[N], int i, int n){ double m = 0;int r;for(r=i+1;rresult = double(b[n-1]/a[n-1][n-1]);else //计算其他x值(对于公式中的求和部分,需要调用getm()函数)result = double((b[i]-getm(a,x,i,n))/a[i][i]);return result;} void main(){ //double a[N][N] = {{2},{1,3,2},{1,2,2}};//double b[N] = {4,6,5};double a[N][N];//系数矩阵 double b[N];//右端项 double x[N];//方程组解 int i,j,k;int n=N;//矩阵大小/*用户手工输入矩阵*/ cout<>n;cout<>a[i][j];} cout<>b[i];} /*显示原始矩阵*/ cout</*进行高斯消去*/ for(j=0;j/*显示处理后矩阵*/ cout</*回代方式解方程组*/ for(i=n-1;i>=0;i--){ x[i] = getx(a,b,x,i,n);} /*显示方程组解*/ cout<四、对该设计题目有何更完善的方案1、对自己完成程序进行自我评价。
关于线性方程组求解的论文

线性方程组的求解问题摘要:线性代数是代数学的一个重要组成部分,广泛应用于现代科学的许多分支。
其核心问题之一就是线性方程组的求解问题。
本文先简要介绍了线性方程组求解的历史,然后给出线性方程组解的结构。
重点介绍了解线性方程组的几种方法:消元法,克拉默法则和利用向量空间概念求解线性方程组的方法。
最后介绍了如何利用Matlab、Excel等常用电脑软件解线性方程。
关键词:线性方程组克拉默法则 Matlab1.线性方程组求解的历史线性方程组的解法,早在中国古代的数学著作《九章算术》方程章中已作了比较完整的论述。
其中所述方法实质上相当于现代的对方程组的增广矩阵施行初等行变换从而消去未知量的方法,即高斯消元法。
在西方,线性方程组的研究是在17世纪后期由莱布尼茨开创的。
他曾研究含两个未知量的三个线性方程组组成的方程组。
麦克劳林在18世纪上半叶研究了具有二、三、四个未知量的线性方程组,得到了现在称为克莱姆法则的结果。
克莱姆不久也发表了这个法则。
18世纪下半叶,法国数学家贝祖对线性方程组理论进行了一系列研究,证明了一元齐次线性方程组有非零解的条件是系数行列式等于零。
法国数学家范德蒙不仅对行列式理论本身进行了开创性研究,而且把行列式应用于解线性方程组。
英国数学家凯莱用矩阵表示线性方程组及线性方程组的解。
19世纪,英国数学家史密斯和道奇森继续研究线性方程组理论,前者引进了方程组的增广矩阵和非增广矩阵的概念,后者证明了n个未知数m个方程的方程组相容的充要条件是系数矩阵和增广矩阵的秩相同。
格拉斯曼则使用向量表示线性方程组的解。
2.线性方程组解的结构n元线性方程组的一个解(c1,c2,……c n)是一个,维向量,当方程组有无穷多个解时,需要研究这些解向量之间的关系,以便更透彻地把握住它们。
关于齐次线性方程组的解的结构有以下结论:1)定义1齐次线性方程组的一组解η1,η2……ηt称为该方程组的一个基础解系,如果a)该方程组的任一解都能表成η1,η2……ηt的线性组合。
c语言编程求解线性方程组论文

本科专业学年论文题目:线性方程组求解方法比较姓名郭凤专业计算机科学与技术专业班级08级本科(2)班指导教师刘晓娜完成日期:2010 年1月8日题目:线性方程组求解方法比较摘要目前在许多实际应用领域,诸如航空、造船以及其它结构工程中,常遇到求解大型线性代数方程组的问题。
本文根据线性代数方程组的雅可比迭代法、LU分解法及高斯列主元消去法三种解法进行了比较,用以方便在实际生活应用中更好的作出选择。
在第二章中本文详细的介绍了线性代数方程组的三种解法的理论知识与证明过程。
为了更加清晰的展现三种方法的不同点以及其各自的优越性,本文在第三章中给出了实例,通过实例的计算与程序的实现,再结合三种方法的优缺点进行了比较。
关键字:线性代数方程组、迭代法、LU分解法、高斯列主元消去法、不同点、比较目录第一章绪论 (4)第二章求解线性方程组的基本理论2.1 迭代法 (5)2.2 直接三角分解法 (6)2.3 高斯消去法 (7)第三章三种算法求解方程组实例3.1 迭代法 (8)3.2 直接三角分解法 (10)3.3 高斯列主元消去法 (14)3.4 三种方法的优缺点比较 (16)参考文献 (17)第一章绪论在自然科学、工程技术、经济和医学各领域中产生的许多实际问题都可以通过数学语言描述为数学问题,也就是说,由实际问题建立数学模型,然后应用各种数学方法和技巧来求解,最后把结果反馈到实际应用中去。
计算数学是数学学科的一大分支,它研究如何借助于计算机求解各类数值问题。
应用计算机求解各类数值问题需要经历以下几个主要过程:1、实际问题2、数学模型3、计算方法4、算法设计5、计算求解目前已有的数学软件可以帮助我们实现上机计算,基本上已经将数值分析的主要内容设计成简单的函数,只要调用这些函数进行运算便可得到数值结果。
数值分析的内通包括线性代数方程组求解、非线性代数方程(组)求解、矩阵的特征值与特征值向量的计算、函数插值、函数逼近、数值积分与数值微分以及微分方程数值解法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数值计算小报告题目:线性方程组求解方法比较姓名和丽专业软件工程班级11级软件(2)班完成日期:2013 年5月18日摘要目前在许多实际应用领域,诸如航空、造船以及其它结构工程中,常遇到求解大型线性代数方程组的问题。
本文根据线性代数方程组的雅可比迭代法、LU分解法及高斯列主元消去法三种解法进行了比较,用以方便在实际生活应用中更好的作出选择。
在第二章中本文详细的介绍了线性代数方程组的三种解法的理论知识与证明过程。
为了更加清晰的展现三种方法的不同点以及其各自的优越性,本文在第三章中给出了实例,通过实例的计算与程序的实现,再结合三种方法的优缺点进行了比较。
关键字:线性代数方程组、迭代法、LU分解法、高斯列主元消去法、不同点、比较目录第一章绪论 (4)第二章求解线性方程组的基本理论2.1 迭代法 (5)2.2 直接三角分解法 (6)2.3 高斯消去法 (7)第三章三种算法求解方程组实例3.1 迭代法 (8)3.2 直接三角分解法 (10)3.3 高斯列主元消去法 (14)3.4 三种方法的优缺点比较 (16)参考文献 (17)第一章绪论计算数学是数学学科的一大分支,它研究如何借助于计算机求解各类数值问题。
应用计算机求解各类数值问题需要经历以下几个主要过程:1、实际问题2、数学模型3、计算方法4、算法设计5、计算求解目前已有的数学软件可以帮助我们实现上机计算,基本上已经将数值分析的主要内容设计成简单的函数,只要调用这些函数进行运算便可得到数值结果。
数值分析的内通包括线性代数方程组求解、非线性代数方程(组)求解、矩阵的特征值与特征值向量的计算、函数插值、函数逼近、数值积分与数值微分以及微分方程数值解法。
线性方程组的求解从理论上可分为两类:直接法和迭代法。
直接法是不考虑计算过程中的舍入误差,经过有限次的运算得到方程组精确解的方法,常见的方法是高斯顺序消去法、高斯列主元消去法和矩阵的LU分解法。
迭代法是采用某种极限过程,用线性代数方程组的近似解逐步逼近精确解的方法。
迭代法中常见的方法有简单迭代法、J-迭代法、GS-迭代法和SOR-迭代法。
本文主要是分析高斯列主元消去法、矩阵的LU分解法和简单迭代法理论上的异同,并用C语言程序通过具体实例进行了分析比较。
本文将线性方程组的求解过程用计算机实现,本文的编写由以下几个特点:1、对于难点问题从具体模型引入,淡化抽象的概念与定理,通俗易通;2、对于具体模型本文给出了多种解题的思想及方法;3、对问题进行简洁易懂的理论证明,突出了线性代数的理论和基本思想,使数学方法更加利于理解掌握。
4、简要分析了算法的计算效果、稳定性、收敛效果、计算精度以及优劣性。
第1章 求解线性方程组的基本理论1.1 迭代法迭代法的基本思想:是将线性方程组转化为便于迭代的等价方程组,对任选一组初始值错误!未找到引用源。
(i=1,2…n ),按某种计算规则,不断地对所得到的值进行修正,最终获得满足精度要求的方程组的近似解。
对于线性方程组Ax=b 其中,A 为非奇异矩阵。
将A 分裂为A=M-N ,其中,M 为非奇异矩阵,且要求线性代数方程组Mx=d 容易求解,一般选择为A 的某一部分元素构成的矩阵,称M 为A 的分裂矩阵。
于是,求解Ax=b 转化为求解Mx=Nx+b,由此可构造一个迭代法:x(0)(初始向量) , x(k+1)=Bx(k)+f (k=0,1,2…)其中,f=b/M,B=I-A/M 为迭代法的迭代矩阵。
选取M 为A 的对角元素组成的矩阵,即选取M=D ,可得到解Ax=b 的迭代法:x(0)(初始向量),x(k+1)=Bx(k)+f (k=0,1,2…)B J 为求解Ax=b 的雅克比迭代法的迭代矩阵。
解迭代法的计算公式为:⎪⎩⎪⎨⎧--==∑∑+=-=+)(1),.......,,(1)(11)()1()0()0(2)0(1)0(n i j k j ij i j k j ij i ii k i T n x a x a b a x x x x X (k=0,1,2,……:i=1,2,3,……..n ) 迭代法方法是求对称矩阵的全部特征值以及相应的特征向量的一种方法,,它是基于以下两个结论:1)任何实对称矩阵A 可以通过正交相似变换成对角型,即存在正交矩阵Q ,使得 错误!未找到引用源。
AQ=diag(错误!未找到引用源。
) 其中错误!未找到引用源。
i (i=1,2,…,n )是A 的特征值,Q 中各列为相应的特征向量。
2)在正交相似变换下,矩阵元素的平方和不变。
即设错误!未找到引用源。
,Q 为交矩阵,记B=错误!未找到引用源。
AQ=错误!未找到引用源。
,则错误!未找到引用源。
基本思想:是通过一次正交变换,将A 中的一对非0的非对角线化成0,并且使得非对角元素的平方和减小。
反复进行上述过程,使变换后的矩阵的非对角元素的平方和趋于0,从而使该矩阵近似为对角矩阵,得到全部特征值和特征向量。
1.2 直接三角分解法矩阵直接三角分解法:是高斯消去法的变形方法。
高斯消去法有多种变形,有的是高斯消去法的改进,有的是用于某种特殊系数矩阵的化简。
高斯消去法解线性方程组先消元,然后再回代。
当用矩阵描述时,是对系数矩阵分解为一个上三角阵和一个下三角阵的乘积,即LU 分解。
因此,高斯消去法与矩阵的LU分解是一致的。
将高斯消去法改写为紧凑形式,可以直接从矩阵A的元素得到计算L,U元素的递推公式,而不需要任何中间步骤,这就是所谓的直接三角分解法,一旦实现了矩阵A的LU分解,那么求解Ax=b的问题就等价于求解两个三角形方程组:错误!未找到引用源。
的问题,而这两个线性代数方程组只要回代,就可以求出其解。
设A为非奇异矩阵,且有分解式A=LU,其中L为单位下三角矩阵,U为单位上三角矩阵,A=错误!未找到引用源。
错误!未找到引用源。
第一步,用L的第一行分别乘以U的第j(j=1,2,…,n)列,比较两边可得错误!未找到引用源。
(j=1,2,…,n) 分别用L的第i(i=1,2,…,n)行乘U的第一列,比较可得错误!未找到引用源。
(i=1,2,…,n) 即得错误!未找到引用源。
(i=1,2,…,n) 这样就求出了L的第一列和U的第一行的所有元素。
依次进行下去,一直到第k-1步,即已求出L的前k-1列和U的前k-1行的所有元素。
第k步,用L的第k行分别乘U的第j(j=k,k+1,…,n)列,比较两边可得:错误!未找到引用源。
=错误!未找到引用源。
+…+错误!未找到引用源。
+错误!未找到引用源。
(j=k,k+1,…,n)分别用L的第i(i=k+1,…,n)行乘U的第k列,比较两边可得:错误!未找到引用源。
=错误!未找到引用源。
+…+错误!未找到引用源。
+错误!未找到引用源。
(i=k+1,…,n)总结上述讨论,得到用直接三角分解法求解Ax=b的计算公式:…,n), 错误!未找到引用源。
(i=2,3,…,n) 错误!未找到引用源。
(j=1,2,错误!未找到引用源。
(j=k,k+1,…,n)错误!未找到引用源。
(i=k+1,k+2,…,n)及求解Ly=b,Ux=y的计算公式:错误!未找到引用源。
(k=2,3,…,n),错误!未找到引用源。
(k=n-1,n-2,…,2,1)1.3 高斯列主元消去法高斯顺序消去法的基本思想是:对线性代数方程组所对应的增广矩阵(A|b )进行一系列“把某一行的非零常数倍加到另一行上”的初等变换,使得(A|b )中A 的对角线一下的元素全变为0,从而使原方程组等价的转化为容易求解的上三角形线性代数方程组,再通过回代得到上三角形线性代数方程组的解,即可求得原方程组的解。
设线性方程组的增广矩阵为):():()1()1()1(b A b A A ===错误!未找到引用源。
首先,在第一列中选取绝对值最大的元素错误!未找到引用源。
作为第一列的主元,即 错误!未找到引用源。
然后交换第一行与第i 行,经一次消元计算得:错误!未找到引用源。
=(A 错误!未找到引用源。
B)错误!未找到引用源。
,此消去过程与高斯顺序消去法完全相同。
重复上述过程,设已完成第k-1步的选主元素,交换两行及消元过程后(A 错误!未找到引用源。
B)已约化为 错误!未找到引用源。
第k 步选主元素,在错误!未找到引用源。
右下角方阵的第一列内选取绝对值最大的元素错误!未找到引用源。
作为这一列的主元,即 错误!未找到引用源。
=错误!未找到引用源。
然后交换错误!未找到引用源。
的第i 行与第k 行,再进行消元计算。
如此重复,直到最后将原线性代数方程组化为 错误!未找到引用源。
错误!未找到引用源。
=错误!未找到引用源。
回代求解得到 错误!未找到引用源。
(k=n-1,…,2,1)列主元消去法除了每步需要按列选出主元,然后进行对换外,其消去过程与高斯顺序消去法是相同的。
第2章 三种方法求解方程组实例线性代数方程组的应用十分广泛,在实际生活中遇到的一些问题通常可以用求解方程组的方法来解决。
本章主要是通过实例介绍三种方法的应用以及其各种方法的优缺点比较。
例:用三种方法求解方程组 错误!未找到引用源。
的解。
2.1 迭代法解题步骤:将方程组记为Ax=b ,其中 A=错误!未找到引用源。
b=错误!未找到引用源。
将原方程组改写为错误!未找到引用源。
(1)也可写为 x=Bx+f 其中 B=错误!未找到引用源。
f=错误!未找到引用源。
任取初始值错误!未找到引用源。
=错误!未找到引用源。
,代入(1)式右边,得到新的值:错误!未找到引用源。
再将错误!未找到引用源。
代入(1)式右边得到错误!未找到引用源。
反复利用这个计算程序,得到一个向量序列和一般的计算公式:错误!未找到引用源。
=B错误!未找到引用源。
+f 其中k表示迭代次数(k=1,2,…)。
令错误!未找到引用源。
,由雅克比迭代公式错误!未找到引用源。
(k=0,1,2,…)有:D错误!未找到引用源。
于是,根据雅克比迭代法的计算公式可求出方程组的解。
迭代法代码:#include<math.h>#include<stdio.h>int gausdl(int n,double i[],double j[],double x[],double eps){ int u,v,w,r;double p,t,s,q;for(u=0;u<=n-1;u++){ w=u*n+u; p=0.0; x[u]=0.0;for (v=0; v<=n-1; v++)if(u!=v){ r=u*n+v; p=p+fabs(i[r]);}if(p>=fabs(i[w])){ printf("fail\n"); return(-1);}}p=eps+1.0;while (p>=eps){ p=0.0;for (u=0; u<=n-1; u++){ t=x[u]; s=0.0;for (v=0;v<=n-1;v++)if (v!=u) s=s+i[u*n+v]*x[v];x[u]=(j[u]-s)/i[u*n+u];q=fabs(x[u]-t)/(1.0+fabs(x[u]));if (q>p) p=q;}}return(1);}void main(){ int u;double eps;static double i[16]={2.0,0.0,0.0,1.0,2.0,3.0,2.0,4.0,-3.0,0.0,1.0,6.0,1.0,-6.0,-5.0};static double x[5],j[4]={0.0,-2.0,-7.0,6.0};eps=0.000001;if (gausdl(4,i,j,x,eps)>0)for (u=0;u<=3;u++)printf("x(%d)=%13.7e\n",u,x[u]);}}运行结果:x1=-3.500000e+000x2=0.000000e+000x3=-3.000000e+000x4=7.000000e+0002.2 直接三角分解法解题步骤:将方程组改写为错误!未找到引用源。