版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
高斯肖元法C++上机实验报告学生姓名:学号:专业班级:实验类型:综合一实验工程名称全选主元高斯消去法解线性方程组二实验原理设有n元线性方程组(考虑便于C++程序数组表示,方程的下标从0开始),写为矩阵形式为Ax=b,其中A为线性方程组的系数矩阵,x为列向量,是方程组的解,b也是列向量.一般来讲,可以假定矩阵A是非奇异阵。〔n阶矩阵A的行列式不为零,即|A|≠0,那么称A为非奇异矩阵〕,,将系数矩阵A和向量b放在一起,形成增广矩阵B:全选主元消去就在矩阵B上进行,整个过程分为如下两个步骤:第一步:消去过程。对于k从0开始到n-2结束,进行以下三步。首先,从系数矩阵A的k行k列开始的子矩阵中选取绝对值最大的元素作为主元素。例如:然后交换B的第k行与第行,第k列与第列,这样,这个子矩阵中具有最大绝对值的元素被交换到k行k列的位置上.其次,进行归一化计算。计算方法为:最后进行消去计算:第二步,回带过程:三代码的实现LinearEqu的定义,LinearEqu.cpp文件中包括该类的成员函数实现文件;7-9.cpp文件包括程序的主函数,主函数中定义了一个类LinearEqu的对象,通过这个对象求解一个四元线性方程组。//Matrix.h文件一,定义一个CMatrix类#ifndef_MATRIX_H#define_MATRIX_HclassCMatrix//定义CMatrix基类{public://外部接口 CMatrix(intsize=2);//构造函数 ~CMatrix();//析构函数voidsetMatrix(constdouble*values);//矩阵赋初值voidprintMatrix()const;//显示矩阵intgetsize()const{returnsize;}//得到矩阵大小double&element(inti,intj){returnelements[i*size+j];}doubleelement(inti,intj)const{returnelements[i*size+j];}private://保护数据成员intsize;//定义矩阵的大小double*elements;//矩阵存放数组首地址};#endif//_MATRIX_H//LinearEqu.h文件二,CLinearEqu类定义#ifndef_LINEAR_EQU_H#define_LINEAR_EQU_H#include"Matrix.h"classCLinearEqu:publicCMatrix//公有派生类CLinearEqu定义{public://外部接口 CLinearEqu(intsize=2);//构造函数 ~CLinearEqu();//析构函数voidsetLinearEqu(constdouble*a,constdouble*b);//方程赋值boolsolve();//全选住院高斯消去法求解方程voidprintLinearEqu()const;//显示方程voidprintSolution()const;//显示方程的解private://私有数据double*sums;//方程右端项double*solution;//方程的解};#endif//_LINEAR_EQU_H经过公有派生,LinearEqu类获得了除构造函数、析构函数之外的Matrix类的全部成员。由于基类的成员是公有和保护类型,因此在派生类中的成员函数中,基类继承来的成员全部可以访问,而对于建立LinearEqu类对象的外部模块来讲,基类的保护成员是无法访问的。通过保护访问类型和公有的基方式,就实现了基类Matrix的数据的有效共享和可靠保护。在程序中,方程的系数矩阵、解以及右端项全部采用动态内存分配技术,这些工作都是在基类、派生类的构造函数中完成,它们的析构函数中完成。//Matrix.cpp文件三,CMatrix类实现#include"Matrix.h"//包含类的定义头文件#include<iostream>usingnamespacestd;voidCMatrix::setMatrix(constdouble*values)//设置矩阵{for(inti=0;i<size*size;i++) elements[i]=values[i];//矩阵成员赋初值}CMatrix::CMatrix(intsize/*=2*/):size(size)//矩阵CMatrix类的构造函数{ elements=newdouble[size*size];}CMatrix::~CMatrix()//矩阵Matrix类的析构函数{delete[]elements;//释放空间}voidCMatrix::printMatrix()const//显示矩阵的元素{ cout<<"TheMatrixis:"<<endl;for(inti=0;i<size;i++) {for(intj=0;j<size;j++) cout<<element(i,j)<<""; cout<<endl; }}//LinearEqu.cpp文件四,CLinearEqu类实现#include"LinearEqu.h"//包含类的定义头文件#include<iostream>#include<cmath>usingnamespacestd;CLinearEqu::CLinearEqu(intsize/*=2*/):CMatrix(size)//用size调用基类构造函数{ sums=newdouble[size];//动态内存分配 solution=newdouble[size];}CLinearEqu::~CLinearEqu()//派生类CLinearEqu的析构函数{delete[]sums;//释放内存delete[]solution;//会自动调用基类析构函数}voidCLinearEqu::setLinearEqu(constdouble*a,constdouble*b)//设置线性方程组{ setMatrix(a);//调用基类函数for(inti=0;i<getsize();i++) sums[i]=b[i];}voidCLinearEqu::printLinearEqu()const//显示线性方程组{ cout<<"TheLineequtionis:"<<endl;for(inti=0;i<getsize();i++) {for(intj=0;j<getsize();j++) cout<<element(i,j)<<""; cout<<""<<sums[i]<<endl; }}voidCLinearEqu::printSolution()const//输出方程组的解{ cout<<"TheResultis:"<<endl;for(inti=0;i<getsize();i++) cout<<"x["<<i<<"]="<<solution[i]<<endl;}inlinevoidswap(double&v1,double&v2)//交换两个实数{doubletemp=v1; v1=v2; v2=temp;}boolCLinearEqu::solve()//全选主元高斯消去法求解方程{int*js=newint[getsize()];//存储主元素所在列号的数组for(intk=0;k<getsize()-1;k++)//选主元素 {intis;//主元素所在行号doublemax=0;//所有元素的最大值for(inti=k;i<getsize();i++)for(intj=k;j<getsize();j++) {doublet=fabs(element(i,j));if(t>max) { max=t; js[k]=j; is=i; } }if(max==0) {delete[]js;returnfalse; }else//通过行列交换,把主元素交换到第K行第K列 {if(js[k]!=k)for(inti=0;i<getsize();i++) swap(element(i,k),element(i,js[k]));if(is!=k) {for(intj=k;j<getsize();j++) swap(element(k,j),element(is,j)); swap(sums[k],sums[is]); } }//消去过程doublemajor=element(k,k);for(intj=k+1;j<getsize();j++) element(k,j)/=major; sums[k]/=major;for(inti=k+1;i<getsize();i++) {for(intj=k+1;j<getsize();j++) element(i,j)-=element(i,k)*element(k,j); sums[i]-=element(i,k)*sums[k]; } }//判断剩下的一个元素是否等于零doubled=element(getsize()-1,getsize()-1);if(fabs(d)<1e-15) {delete[]js;returnfalse; }//回带过程 solution[getsize()-1]=sums[getsize()-1]/d;for(inti=getsize()-2;i>=0;i--) {doublet=0.0;for(intj=i+1;j<=getsize()-1;j++) t+=element(i,j)*solution[j]; solution[i]=sums[i]-t; } js[getsize()-1]=getsize()-1;for(intk=getsize()-1;k>=0;k--)if(js[k]!=k)swap(solution[k],solution[js[k]]);delete[]js;returntrue;}在类的成员函数实现过程中,派生类的构造函数使用参数调用了基类的构造函数,为矩阵动态分配了内存空间。而派生类的析构函数同样也调用了基类的析构函数,只是整个调用过程完全由系统内部完成。基类的保护数据成员的身份出现,派生类的成员函数可以自由的进行访问。全选主元高斯消去法求解函数返回值为整型,正常完成之后,返回值为1,非正常结束后,返回值为0,根据函数的返回值,就可以判断求解过程的完成情况//7-9.cpp文件五,主函数#include"LinearEqu.h"//类定义头文件#include<iostream>usingnamespacestd;intmain()//主函数{doublea[]=//方程系数矩阵 { 0.2368,0.2471,0.2568,1.2671, 0.1968,0.2071,1.2168,0.2271, 0.1581,1.1675,0.1768,0.1871, };doubleb[]={1.8471,1.7471,1.6471,1.5471};//方程右端项 CLinearEquequ(4);//定义一个四元方程组对象 equ.setLinearEqu(a,b);//设置方程组 equ.printLinearEqu();//通过调用输出方程组if(equ.solve())//求解方程组 equ.printSolution();//输出方程组的解else cout<<"fail"<<endl;return0;}在程序的主函数局部,选择了一个四元方程组来作为一个实际例子验证算法。方程组的系数及右端项数据都使用一维数组来存储。首先定义一个运行结果如下:四实际应用许多实际问题经常最后归结为求解线性方程组。例如:用最小二乘法处理测量结果时,和用网格法逼近微分方程的边值问题时,都会得到线性方程组。这些方程组中的未知量往往是几十个,甚至上百个,如果要解含n个未知量的线性方程时,就得计算出n+1个n阶行列式,而计算每一个n阶行列式就需做n!次乘法,一般来说,即使借助电子计算机,也需要数月乃至数年的时间,所以在解这些含有未知量的线性方程组时,不仅要借助于电子计算机,同时还必须寻求恰当的计算方法。而高斯全选主元消去法是一种效率很高、较为常用的线性方程组解法。以下以电阻网络为例加以说明。电阻网络实例简单电网中的电流可以利用线性方程组来描述。当电流经过电
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论