计算方法实验报告_列主元高斯消去法

计 算 方 法 实 验 报 告

动力与机械学院 08级自动化3班

唐禹

[1**********]78

2010.11.08

实验一 :使用列主元消去法求解线性方程组

列主元消去法是在Gauss消去法的基础上改进而得的一种比较快速和合理的求解线性方程组的方法。它的主要思路是通过对每次消元过程中主元的多次选取以达到减小误差和加快求解速度的一种消去法。使用列主元消去法相比于Gauss消去法基本上能控制舍入误差的影响,并且选主元素较全主元消去法更为方便。

其算法的设计思路如下:

该算法的具体流程图也如下图所示:

对应的C++程序源代码如下:

/*

编译环境 windows7 系统下 使用visual studio 2010 使用VC++6.0可能会用少许不兼容,修改一下即可 Copyright of 唐禹

Edited in 2010/11/01 Builed in 2010/11/01 Version 1.1 */

#include #include #include

using namespace std; int N; //方程的阶数,改用变量,可以由使用者决定方程阶数,程序更加灵活

double Main_Element; //记录每次选择的主元

double **A; double **B; double **A_B;

double **X;

/*用于试验的方程组 {3,1,6}; A= {2,1,3}; {1,1,1}; B= {2,7,4};

求的根为:X={19,-7,-8}; */ /*

为变量分配存储空间,初始化系数矩阵 */

void Init_Data(); /*

销毁变量空间 */

void Destroy_Data();

/*

求方程组Ax=B的增广矩阵A_B */

double** AUB(int N,double **A,double **B,double **A_B); /*

用于显示矩阵的详细参数,row x col型 */

void Show_Matrix(double **A,int row,int col); /*

用于横向显示向量,N x 1型 */

void Show_Result(int x/*表征解的个数/,int N);

int Gauss_Colum_Main_Element( int n, //方程阶数 double **A, //系数矩阵

double **B, //

double e);

//精度控制

/*

确定列主元素所在行,并返回行号 */

int Choose_Colum_Main_Element( int n, //方程阶数 double**A, //系数矩阵

int start);

/*

交换矩阵L1,L2两行 */

void Exchange(double **A,int num_of_colum,int L1,int L2); /*

单位化系数矩阵,更准确地说是将矩阵A的左上角nxn个分块矩阵单位化 */

double **Unitization(int n/*方程阶数*/,double**A /*系数矩阵*/);

/*

对确定好列主元素的矩阵进行消元处理 */

void Elimination(int n,double**A,int start);

/*主函数*/ int main() {

bool willgo; do {

Init_Data();

Show_Result(Gauss_Colum_Main_Element(N,A,B,0),N); cout

cin>>willgo; }while(willgo);

return 0;

}

//以下部分是对前面声明的函数的具体实现,相应的功能参看前面声明部分

//初始化数据

void Init_Data() { cout

while(N

cout

A=new double*[sizeof(double*)*N]; B=new double*[sizeof(double*)*1];

A_B=new double*[sizeof(double*)*(N+1)]; X=new double*[sizeof(double*)*1];

for(int i=0;i

A[i]=new double[N]; B[i]=new double[1];

A_B[i]=new double[N+1]; X[i]=new double[1]; }

cout

{

for(int j=0;j

cin>>A[i][j]; }

}

cout

cin>>B[i][0]; }

AUB(N,A,B,A_B);

}

//销毁数据

void Destroy_Data() {

for(int i=0;i

delete A[i]; delete B[i]; delete A_B[i]; delete X[i]; }

delete A; delete B; delete A_B; delete X; }

//求增广矩阵

double** AUB(int N,double **A,double **B,double **A_B) {

for(int i=0;i

for(int j=0;j

A_B[i][j]=A[i][j]; }

A_B[i][N]=B[i][0]; }

return A_B; }

//输出矩阵A的row x col 个元素

void Show_Matrix(double **A,int row,int col) {

cout

for(int i=0;i

cout

for(int j=0;j

cout

cout

cout

//输出最终结果

void Show_Result(double**X,int N) { if(x==0) // Gauss_Colum_Main_Element返回0,无解

{

cout

if(x==-1) // Gauss_Colum_Main_Element返回-1,为任意解

{

cout

cout

cout

cout

}

//高斯列主元消去法的主调函数

int Gauss_Colum_Main_Element( int N, //方程阶数 double **A, //系数矩阵

double**B, //

double e) //精度控制

{ cout

cout

int row=Choose_Colum_Main_Element(N,A_B,i); if(Main_Element

cout

Unitization(N,A_B);

cout

X[i][0]=A_B[i][N]; }

return 1;

A_0: //如果出现增广矩阵中|A|~0的情况处理如下 for(int i=0;i

if(abs(A_B[i][N])>e) return 0; }

//增广矩阵中|B|~0,即方程解为任意解的情况 return -1; }

//选取主元素,并返回主元所在的行

int Choose_Colum_Main_Element(int n,double**A,int start) {

int row=start;

double max=abs(A[start][start]); for(int i=start;i

if(max

{

row=i; max=A[i][start]; } }

Main_Element=max; return row;

}

//交换L1,L2行

void Exchange(double **A,int num_of_colum,int L1,int L2) {

double temp;

for(int i=0;i

temp=A[L1][i];

A[L1][i]=A[L2][i]; A[L2][i]=temp; } }

//消元过程函数(消元其实点为start,start)

void Elimination(int n,double**A,int start) {

double factor;

for(int i=start+1;i

factor=A[i][start]/A[start][start]; for(int j=start;j

A[i][j]=A[i][j]-factor*A[start][j]; } } }

//回带求解,即“单位化”增广矩阵

double **Unitization(int n,double**A) { double row_first; //行首元素 //主对角元素单位化

for(int i=0;i

row_first=A[i][i];

for(int j=0;j

{

A[i][j]=A[i][j]/row_first; } }

for(int k=n-1;k>0;k--) {

for(int i=0;i

double factor=A[i][k]; for(int j=0;j

A[i][j]=A[i][j]-factor*A[k][j]; } } }

return A;

}

关于本段程序的说明:

(1) 本程序对于方程组想系数矩阵不是采用默认的数组实现的,因为若采用数组实现则不能由使用者决定求解

方程的阶数,需要更改程序。故而此处采用二维指针的方式实现,这样程序很灵活,可以实现动态指定求解方程的阶数,但是同时也在一定程度上增加了程序的复杂程度。 (2) 关于“单位化”增广矩阵:其实这里A_B=[A B],并非NxN的矩阵,本没有单位化一说,这里为了便于

表述特将A_B经过转换所得形如[E B’]的过程,成为矩阵[A B]的单位化,其他的类推。 (3) 本程序最后的求解并不是采用书上面回带的方式求的最后的根的,而是采用“单位化”增广矩阵的方式来

实现的,其本质和回带是一样的,只是为了便于程序最后结果的输出。 (4) 另外,本程序版权归本人所有。

《程序的执行结果见下页》

下面是程序执行的结果记录:

请输入方程的阶数: 3

您选择了3阶方程组计算.

请输入系数矩阵A(按行输入): 注:为便于排版,执行的时候输入在一行中,并不影响程序结果

请输入系数矩阵A(按行输入): 1 0 0 1 0 0 0 0 1 请输入矩阵B: 0 0 0

Ax=B的增广矩阵为: 3 1 6 2 1 3 1 1 1 请输入矩阵B: 2 7 4

Ax=B的增广矩阵为:

| 3 1 6 2 | | 2 1 3 7 | | 1 1 1 4 |

解方程Ax=B的过程如下: 选取列主元后第1次消元:

| 3 1 6 2 | | 0 0.333333 -1 5.66667 || 0 0.666667 -1 3.33333 |

选取列主元后第2次消元:

| 3 1 6 2 | | 0 0.666667 -1 3.33333 || 0 0 -0.5 4 |

选取列主元后第3次消元:

| 3 1 6 2 | | 0 0.666667 -1 3.33333 | | 0 0 -0.5 4 |

单位化之后的结果:

| 1 0 0 19 | | 0 1 0 -7 | | -0 -0 1 -8 |

所求方程组的根为:(x1,x2,x3)=( 19 ,-7 ,-8 ). 退出(0)还是继续求解其他方程组(1)? 1

请输入方程的阶数: 3

您选择了3阶方程组计算.

| 1 0 0 0 | | 1 0 0 0 | | 0 0 1 0 |

解方程Ax=B的过程如下: 选取列主元后第1次消元:

| 1 0 0 0 | | 0 0 0 0 | | 0 0 1 0 |

方程组为任意解

退出(0)还是继续求解其他方程组(1)? 1

请输入方程的阶数: 3

您选择了3阶方程组计算.

请输入系数矩阵A(按行输入): 1 0 0 1 0 0 0 0 0 请输入矩阵B: 2 3 4

Ax=B的增广矩阵为:

| 1 0 0 2 | | 1 0 0 3 | | 0 0 0 4 |

解方程Ax=B的过程如下: 选取列主元后第1次消元:

| 1 0 0 2 | | 0 0 0 1 | | 0 0 0 4 |

由于消元过程中出现主元小于所设定的精度,且此时增广矩阵中B!~0 所以:方程无解

退出(0)还是继续求解其他方程组(1)? 0

计 算 方 法 实 验 报 告

动力与机械学院 08级自动化3班

唐禹

[1**********]78

2010.11.08

实验一 :使用列主元消去法求解线性方程组

列主元消去法是在Gauss消去法的基础上改进而得的一种比较快速和合理的求解线性方程组的方法。它的主要思路是通过对每次消元过程中主元的多次选取以达到减小误差和加快求解速度的一种消去法。使用列主元消去法相比于Gauss消去法基本上能控制舍入误差的影响,并且选主元素较全主元消去法更为方便。

其算法的设计思路如下:

该算法的具体流程图也如下图所示:

对应的C++程序源代码如下:

/*

编译环境 windows7 系统下 使用visual studio 2010 使用VC++6.0可能会用少许不兼容,修改一下即可 Copyright of 唐禹

Edited in 2010/11/01 Builed in 2010/11/01 Version 1.1 */

#include #include #include

using namespace std; int N; //方程的阶数,改用变量,可以由使用者决定方程阶数,程序更加灵活

double Main_Element; //记录每次选择的主元

double **A; double **B; double **A_B;

double **X;

/*用于试验的方程组 {3,1,6}; A= {2,1,3}; {1,1,1}; B= {2,7,4};

求的根为:X={19,-7,-8}; */ /*

为变量分配存储空间,初始化系数矩阵 */

void Init_Data(); /*

销毁变量空间 */

void Destroy_Data();

/*

求方程组Ax=B的增广矩阵A_B */

double** AUB(int N,double **A,double **B,double **A_B); /*

用于显示矩阵的详细参数,row x col型 */

void Show_Matrix(double **A,int row,int col); /*

用于横向显示向量,N x 1型 */

void Show_Result(int x/*表征解的个数/,int N);

int Gauss_Colum_Main_Element( int n, //方程阶数 double **A, //系数矩阵

double **B, //

double e);

//精度控制

/*

确定列主元素所在行,并返回行号 */

int Choose_Colum_Main_Element( int n, //方程阶数 double**A, //系数矩阵

int start);

/*

交换矩阵L1,L2两行 */

void Exchange(double **A,int num_of_colum,int L1,int L2); /*

单位化系数矩阵,更准确地说是将矩阵A的左上角nxn个分块矩阵单位化 */

double **Unitization(int n/*方程阶数*/,double**A /*系数矩阵*/);

/*

对确定好列主元素的矩阵进行消元处理 */

void Elimination(int n,double**A,int start);

/*主函数*/ int main() {

bool willgo; do {

Init_Data();

Show_Result(Gauss_Colum_Main_Element(N,A,B,0),N); cout

cin>>willgo; }while(willgo);

return 0;

}

//以下部分是对前面声明的函数的具体实现,相应的功能参看前面声明部分

//初始化数据

void Init_Data() { cout

while(N

cout

A=new double*[sizeof(double*)*N]; B=new double*[sizeof(double*)*1];

A_B=new double*[sizeof(double*)*(N+1)]; X=new double*[sizeof(double*)*1];

for(int i=0;i

A[i]=new double[N]; B[i]=new double[1];

A_B[i]=new double[N+1]; X[i]=new double[1]; }

cout

{

for(int j=0;j

cin>>A[i][j]; }

}

cout

cin>>B[i][0]; }

AUB(N,A,B,A_B);

}

//销毁数据

void Destroy_Data() {

for(int i=0;i

delete A[i]; delete B[i]; delete A_B[i]; delete X[i]; }

delete A; delete B; delete A_B; delete X; }

//求增广矩阵

double** AUB(int N,double **A,double **B,double **A_B) {

for(int i=0;i

for(int j=0;j

A_B[i][j]=A[i][j]; }

A_B[i][N]=B[i][0]; }

return A_B; }

//输出矩阵A的row x col 个元素

void Show_Matrix(double **A,int row,int col) {

cout

for(int i=0;i

cout

for(int j=0;j

cout

cout

cout

//输出最终结果

void Show_Result(double**X,int N) { if(x==0) // Gauss_Colum_Main_Element返回0,无解

{

cout

if(x==-1) // Gauss_Colum_Main_Element返回-1,为任意解

{

cout

cout

cout

cout

}

//高斯列主元消去法的主调函数

int Gauss_Colum_Main_Element( int N, //方程阶数 double **A, //系数矩阵

double**B, //

double e) //精度控制

{ cout

cout

int row=Choose_Colum_Main_Element(N,A_B,i); if(Main_Element

cout

Unitization(N,A_B);

cout

X[i][0]=A_B[i][N]; }

return 1;

A_0: //如果出现增广矩阵中|A|~0的情况处理如下 for(int i=0;i

if(abs(A_B[i][N])>e) return 0; }

//增广矩阵中|B|~0,即方程解为任意解的情况 return -1; }

//选取主元素,并返回主元所在的行

int Choose_Colum_Main_Element(int n,double**A,int start) {

int row=start;

double max=abs(A[start][start]); for(int i=start;i

if(max

{

row=i; max=A[i][start]; } }

Main_Element=max; return row;

}

//交换L1,L2行

void Exchange(double **A,int num_of_colum,int L1,int L2) {

double temp;

for(int i=0;i

temp=A[L1][i];

A[L1][i]=A[L2][i]; A[L2][i]=temp; } }

//消元过程函数(消元其实点为start,start)

void Elimination(int n,double**A,int start) {

double factor;

for(int i=start+1;i

factor=A[i][start]/A[start][start]; for(int j=start;j

A[i][j]=A[i][j]-factor*A[start][j]; } } }

//回带求解,即“单位化”增广矩阵

double **Unitization(int n,double**A) { double row_first; //行首元素 //主对角元素单位化

for(int i=0;i

row_first=A[i][i];

for(int j=0;j

{

A[i][j]=A[i][j]/row_first; } }

for(int k=n-1;k>0;k--) {

for(int i=0;i

double factor=A[i][k]; for(int j=0;j

A[i][j]=A[i][j]-factor*A[k][j]; } } }

return A;

}

关于本段程序的说明:

(1) 本程序对于方程组想系数矩阵不是采用默认的数组实现的,因为若采用数组实现则不能由使用者决定求解

方程的阶数,需要更改程序。故而此处采用二维指针的方式实现,这样程序很灵活,可以实现动态指定求解方程的阶数,但是同时也在一定程度上增加了程序的复杂程度。 (2) 关于“单位化”增广矩阵:其实这里A_B=[A B],并非NxN的矩阵,本没有单位化一说,这里为了便于

表述特将A_B经过转换所得形如[E B’]的过程,成为矩阵[A B]的单位化,其他的类推。 (3) 本程序最后的求解并不是采用书上面回带的方式求的最后的根的,而是采用“单位化”增广矩阵的方式来

实现的,其本质和回带是一样的,只是为了便于程序最后结果的输出。 (4) 另外,本程序版权归本人所有。

《程序的执行结果见下页》

下面是程序执行的结果记录:

请输入方程的阶数: 3

您选择了3阶方程组计算.

请输入系数矩阵A(按行输入): 注:为便于排版,执行的时候输入在一行中,并不影响程序结果

请输入系数矩阵A(按行输入): 1 0 0 1 0 0 0 0 1 请输入矩阵B: 0 0 0

Ax=B的增广矩阵为: 3 1 6 2 1 3 1 1 1 请输入矩阵B: 2 7 4

Ax=B的增广矩阵为:

| 3 1 6 2 | | 2 1 3 7 | | 1 1 1 4 |

解方程Ax=B的过程如下: 选取列主元后第1次消元:

| 3 1 6 2 | | 0 0.333333 -1 5.66667 || 0 0.666667 -1 3.33333 |

选取列主元后第2次消元:

| 3 1 6 2 | | 0 0.666667 -1 3.33333 || 0 0 -0.5 4 |

选取列主元后第3次消元:

| 3 1 6 2 | | 0 0.666667 -1 3.33333 | | 0 0 -0.5 4 |

单位化之后的结果:

| 1 0 0 19 | | 0 1 0 -7 | | -0 -0 1 -8 |

所求方程组的根为:(x1,x2,x3)=( 19 ,-7 ,-8 ). 退出(0)还是继续求解其他方程组(1)? 1

请输入方程的阶数: 3

您选择了3阶方程组计算.

| 1 0 0 0 | | 1 0 0 0 | | 0 0 1 0 |

解方程Ax=B的过程如下: 选取列主元后第1次消元:

| 1 0 0 0 | | 0 0 0 0 | | 0 0 1 0 |

方程组为任意解

退出(0)还是继续求解其他方程组(1)? 1

请输入方程的阶数: 3

您选择了3阶方程组计算.

请输入系数矩阵A(按行输入): 1 0 0 1 0 0 0 0 0 请输入矩阵B: 2 3 4

Ax=B的增广矩阵为:

| 1 0 0 2 | | 1 0 0 3 | | 0 0 0 4 |

解方程Ax=B的过程如下: 选取列主元后第1次消元:

| 1 0 0 2 | | 0 0 0 1 | | 0 0 0 4 |

由于消元过程中出现主元小于所设定的精度,且此时增广矩阵中B!~0 所以:方程无解

退出(0)还是继续求解其他方程组(1)? 0


相关内容

  • 列主元消去法解方程组实验报告
  • 实验名称: 列主元消去法解方程组 1 引言 我们知道,高斯消去法是一个古老的解线性方程组的方法.而在用高斯消去法解Ax=b k) 时,其中设A为非奇异矩阵,可能出现a(0的情况,这时必须进行带行交换的高斯消去kkk)k)法.但在实际计算中即使a(用a(作除数,会导致中间结果矩阵A(k)0但其绝对 ...

  • 数值计算基础
  • 数值计算基础 实验指导书 2010年 目录 实验一 直接法解线性方程组的 ................................ 1 实验二 插值方法 ........................................... 10 实验三 数值积分 ............. ...

  • Gauss顺序消去法解线性方程组报告
  • Gauss 顺序消去法解线性方程组 制作人:陈静 Gauss 消去法是解线性方程组的一种直接方法,有时也称为精确法,这种算法只包含有限四次运算,并且在每一步运算过程都不会发生舍入误差的假设下,计算的结果就是方程组的精确解.但实际计算中不可避免舍入误差的存在和影响,所以这种方法只能求得线性方程组的近似 ...

  • 高斯消元实验报告
  • 实验报告一 Gauss消去法求解线性方程组实验 一.实验内容 分别用顺序Gauss消去法和列选主元gauss消去法求解方程组 = 二.算法原理 对一般的形如的线性方程组,记增广矩阵.Guass消去法包括消元过程和回代过程,消去过程实际上是把通过有限步的初等变换(即把的某行的一个倍数加到另一行或变换的 ...

  • 最优化计算方法大纲
  • <最优化计算方法>课程教学大纲 课程名称:最优化计算方法/ Optimization Method 课程编码:0705004003 课程类型:学科专业课 总学时数/学分数:48/3 上机学时:8 适用专业:信息与计算科学 数学与应用数学 先修课程:数学分析 高等代数 修订日期:2011年 ...

  • 教学改革研究工作总结
  • 计算物理与MATLAB相结合的教学改革总结 李晓莉(物理科学与技术学院) 计算物理学是运用许多基础数学理论(如偏微分方程理论.线性代数.非线性规划等)和先进的计算技术(如性能优良的计算机和优秀的数值计算软件)对物理学研究前沿的挑战性问题进行大规模数值模拟和分析的学科.计算物理学的发展对统计物理.核物 ...

  • 高斯消去法高斯塞德尔迭代法
  • 数值计算 高斯消去法和高斯-塞德尔迭代法 摘要 虽然已学过加减消元法.代入消元法.矩阵变换法和Cramer 法则等,但是无法满足实际计算需要,故在此讨论在计算机上实现的有效而实用的解法.线性方程组的解法大致分2类:直接法(高斯消去法)和迭代法(高斯-赛德尔迭代法),在此对着此类算法进行比较分析. 一 ...

  • 迭代法实验
  • 实验五 线性方程组的迭代法实验 一. 实验目的 (1)深入理解线性方程组的迭代法的设计思想,学会利用系数矩阵的性质以保证迭 代过程的收敛性,以及解决某些实际的线性方程组求解问题. (2)熟悉Matlab编程环境,利用Matlab解决具体的方程求根问题. 二. 实验要求 建立Jacobi迭代公式.Ga ...

  • 滑差速器非圆锥齿轮线切割加工技术
  • 第10卷第4期 2008年7月 军事交通学院学报 JounrnalofAcademyofMilitaryTransportation V01.10No.4 July2008 ●基础理论与应用BasicTheoryandItsApplication 自适应变速比防滑差速器非圆锥齿轮线切割加工技术 贾巨 ...