Guass列主元、平方根法、追赶法求解方程组的C++实现
一,要解决的问题
选用合适的算法,求解三种线性方程组:一般线性方程组,对称正定方程组,三对角线性方程组。
方程略。
二,数值方法
1,使用Guass列主元消去法求解一般线性方程组。
Guass列主元是为了防止Guass消去法中大数吃掉小数而引出的一种线性方程组求解方法,消元时选用一列中绝对值最大的元素作为列主元素。
算法伪代码:
消元过程
回代过程
2,使用平方根法求解对称正定方程组
平方根法。它把系数矩阵(对称正定矩阵)表示成一个下三角矩阵L和其转置的乘积的分解。这样的分解又称为Cholesky分解。
3,使用追赶法求解三对角线性方程组
三对角线性方程组是指这一类的线性方程组:系数矩阵是一个对角占优的三对角矩阵。追赶法是专门用来求解三对角线性方程组的,它将系数矩阵分解成alpha矩阵和beta矩阵的乘积,例如以下图所看到的:
三。算法
1。Guass列主元消去法
/*
CreateOn:2016/03/20
Author:linxiaobai
Function:linear equation solution
solution1:列主元Guass消去法求解一般线性方程组
*/
#include "stdafx.h"
# include<iostream>
# include<algorithm>
# include<fstream>
# include<iomanip>
# include<cmath>
using namespace std;
double a[15][15];
const int N=10;
double res[N+1];
void printArry(double a[][15])//打印增广矩阵
{
for(int i=1;i<=10;i++)
{
for(int j=1;j<=11;j++)
{
cout<<setw(3)<<a[i][j]<<" ";
}
cout<<endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
cout<<"【运用列主元Guass求解一般线性方程组】"<<endl;
//读入增广矩阵
ifstream in;
in.open("data.txt");
if(!in)
{
cerr<<"file open failed!"<<endl;
return 0;
}
double x;
int i=1,j=1;
while(!in.eof())
{
in>>a[i][j];
j++;
if(j>11)
{
i++;j=1;
}
}
cout<<"增广矩阵:"<<endl<<"++++++++++++++++++++++++++"<<endl;
printArry(a);
cout<<"++++++++++++++++++++++++++";
for(int k=1;k<=N-1;k++)
{
double tmp=abs(a[k][k]);
int ind=k;
for(int j=k;j<=N;j++)//找绝对值最大的行
{
if(abs(a[j][k])>tmp)
{tmp=abs(a[j][k]);ind=j;}
}
//若a[ind][k]=0,停止计算
if(a[ind][k]==0){cout<<"no unique solution"<<endl;return 0;}
//绝对值最大的行交换到第k行
if(ind!=k)
for(int j=1;j<=N+1;j++)
swap(a[ind][j],a[k][j]);
//消元计算
double p;
for(int i=k+1;i<=N;i++)
{
p=a[i][k]/a[k][k];
for(int j=k;j<=N+1;j++)
a[i][j]-=p*a[k][j];
}
}
if(a[N][N]==0)
{cout<<"no unique solution"<<endl;return 0;}
//回代求解
res[N]=a[N][N+1]/a[N][N];
double s;
for(int i=N-1;i>=1;i--)
{
s=0;
for(int j=i+1;j<=N;j++)
s+=a[i][j]*res[j];
res[i]=(a[i][N+1]-s)/a[i][i];
}
//输出解向量为
cout<<endl<<endl<<"解向量为:"<<endl;
for(int i=1;i<=N;i++)
if(abs(res[i])<10e-14)
cout<<"0"<<" ";
else
cout<<res[i]<<" ";
cout<<endl;
return 0;
}
2,使用平方根算法解对称正定方程组
/*
CreateOn:2016/03/20
Author:linxiaobai
Function:linear equation solution
solution1:使用平方根算法解对称正定方程组
*/
# include"stdafx.h"
# include<iostream>
# include<fstream>
# include<cmath>
# include<iomanip>
using namespace std;
double a[10][10];
const int N=8;
double b[N+1],xx[N+1],yy[N+1];
void printArry(double a[][10])//输出系数矩阵
{
for(int i=1;i<=8;i++)
{
for(int j=1;j<=8;j++)
{
cout<<setw(3)<<a[i][j]<<" ";
}
cout<<endl;
}
}int main()
{
cout<<"【运用平方根算法解对称正定方程组】"<<endl;
/*读入系数矩阵*/
ifstream in;
in.open("data2.txt");
if(!in)
{
cerr<<"file open failed!"<<endl;
return 0;
}
int i=1,j=1;
while(i<=N)
{
in>>a[i][j];
j++;
if(j>8)
{
i++;j=1;
}
}
/*读入b[]*/
for(int i=1;i<=N;i++)
in>>b[i];
cout<<"系数矩阵:"<<endl<<"++++++++++++++++++++++++++"<<endl;
printArry(a);
cout<<endl<<endl<<"b:"<<endl;
for(int i=1;i<=N;i++)
cout<<setw(3)<<b[i]<<" ";
cout<<endl<<"++++++++++++++++++++++++++";
//開始计算。A=GG',G存在A的下三角
for(int k=1;k<=N;k++)
{
double s1=0;
for(int m=1;m<=k-1;m++)
s1+=pow(a[k][m],2);
a[k][k]=sqrt(a[k][k]-s1);
for(int i=k+1;i<=N;i++)
{
double s2=0;
for(int m=1;m<=k-1;m++)
s2+=a[i][m]*a[k][m];
a[i][k]=(a[i][k]-s2)/a[k][k];
}
//计算y
double s3=0;
for(int m=1;m<=k-1;m++)
s3+=a[k][m]*yy[m];
yy[k]=(b[k]-s3)/a[k][k];
}
//计算x
xx[N]=yy[N]/a[N][N];
for(int k=N-1;k>=1;k--)
{
double s4=0;
for(int m=k+1;m<=N;m++)
s4+=a[m][k]*xx[m];
xx[k]=(yy[k]-s4)/a[k][k];
}
cout<<endl<<"解向量为:"<<endl;
for(int i=1;i<=N;i++)
cout<<setw(3)<<xx[i]<<" ";
cout<<endl;
return 0;
}
3,使用追赶法解三对角线性方程组
/*
CreateOn:2016/03/20
Author:linxiaobai
Function:linear equation solution
solution1:使用追赶法解三对角线性方程组
*/
# include"stdafx.h"
# include<iostream>
# include<fstream>
# include<iomanip>
# include<cmath>
using namespace std;
const int N=10;
double a[N+1],c[N+1],d[N+1],xx[N+1],yy[N+1];
int main()
{
cout<<"【运用追赶法解三对角线性方程组】"<<endl;
//a[N]:主对角线上的元素
for(int i=1;i<=N;i++)
a[i]=4;
//c[N]:上辅对角线上的元素
for(int i=1;i<=N-1;i++)
c[i]=-1;
//d[N]:下辅对角线上的元素
for(int i=2;i<=N;i++)
d[i]=-1;
double b[]={0,7,5,-13,2,6,-12,14,-4,5,-5};
cout<<"++++++++++++++++++++++++++"<<endl;
cout<<"主对角线上的元素a:"<<endl;
for(int i=1;i<=N;i++)
cout<<setw(3)<<a[i]<<" ";
cout<<endl<<endl<<"上辅对角线上的元素c:"<<endl;
for(int i=1;i<=N-1;i++)
cout<<setw(3)<<c[i]<<" ";
cout<<endl<<endl<<"下辅对角线上的元素d:"<<endl;
for(int i=2;i<=N;i++)
cout<<setw(3)<<d[i]<<" ";
cout<<endl<<endl<<"b:"<<endl;
for(int i=1;i<=N;i++)
cout<<setw(3)<<b[i]<<" ";
cout<<endl<<"++++++++++++++++++++++++++"<<endl;
/*開始计算*/
double alpha[N+1],beta[N+1];
alpha[1]=a[1];
for(int i=1;i<=N-1;i++)
{
beta[i]=c[i]/alpha[i];
alpha[i+1]=a[i+1]-d[i+1]*beta[i];
}
yy[1]=b[1]/alpha[1];
for(int i=2;i<=N;i++)
{
yy[i]=(b[i]-d[i]*yy[i-1])/alpha[i];
}
xx[N]=yy[N];
for(int i=N-1;i>=1;i--)
xx[i]=yy[i]-beta[i]*xx[i+1];
//解向量为:
cout<<endl<<"解向量为:"<<endl;
for(int i=1;i<=N;i++)
if(abs(xx[i])<10e-14)
cout<<"0"<<" ";
else
cout<<xx[i]<<" ";
cout<<endl;
return 0;
}
四,数值结果
1,Guass列主元消去法
2,使用平方根算法解对称正定方程组
3,使用追赶法解三对角线性方程组
五,结果分析与实验总结
浮点计算产生的误差
在Guass消元算法之前的代码中,我使用了近似的方法,将绝对值小于10的-14次方的值近似为0,如今去掉这个处理。来看一下结果:
for(int i=1;i<=N;i++)
//if(abs(res[i])<10e-14)
//cout<<"0"<<" ";
//else
cout<<res[i]<<" ";
能够看到x3的值是一个十分接近于0的数,假设将消元后的系数矩阵打印出来。能够看到消元后的系数矩阵并非一个真正的上三角矩阵,下三角部分有几处的值是一个绝对值极小的值。这是因为计算机的浮点计算造成的,浮点数在计算机中本身就不是一个精确的数,在消元的过程中。一些浮点运算有误差,于是最后得到的是近似值,而不是0。
同理,平方根法和追赶法也会产生由浮点数计算引起的误差,降低计算误差正是学习数值分析的目的。
Guass列主元、平方根法、追赶法求解方程组的C++实现的更多相关文章
- 用列主元消去法分别解方程组Ax=b,用MATLAB程序实现(最有效版)
数值分析里面经常会涉及到用MATLAB程序实现用列主元消去法分别解方程组Ax=b 具体的方法和代码以如下方程(3x3矩阵)为例进行说明: 用列主元消去法分别解方程组Ax=b,用MATLAB程序实现: ...
- 插值代码17个---MATLAB
函数名 功能Language 求已知数据点的拉格朗日插值多项式Atken 求已知数据点的艾特肯插值多项式Newton 求已知数据点的均差形式的牛顿插值多项式Newtonforward 求已知数据点的前 ...
- MATLAB求解方程与方程组
1. solve函数 ①求解单个一元方程的数值解 syms x; x0 = double(solve(x +2 - exp(x),x)); 求x+2 = exp(x)的解,结果用double ...
- fslove - Matlab求解多元多次方程组
fslove - Matlab求解多元多次方程组 简介: 之前看到网上的一些资料良莠不齐,各种转载之类的,根本无法解决实际问题,所以我打算把自己的学到的总结一下,以实例出发讲解fsolve. 示例如下 ...
- 高斯消去、追赶法 matlab
1. 分别用Gauss消去法.列主元Gauss消去法.三角分解方法求解方程组 程序: (1)Guess消去法: function x=GaussXQByOrder(A,b) %Gauss消去法 N = ...
- (原创)列主元Gauss消去法的通用程序
import numpy as np np.set_printoptions(precision=5) A = np.array([[31., -13., 0., 0., 0., -10., 0., ...
- MDP中值函数的求解
MDP概述 马尔科夫决策过程(Markov Decision Process)是强化学习(reinforcement learning)最基本的模型框架.它对序列化的决策过程做了很多限制.比如状态 ...
- 实现求解线性方程(矩阵、高斯消去法)------c++程序设计原理与实践(进阶篇)
步骤: 其中A是一个n*n的系数方阵 向量x和b分别是未知数和常量向量: 这个系统可能有0个.1个或者无穷多个解,这取决于系数矩阵A和向量b.求解线性系统的方法有很多,这里使用一种经典的方法——高斯消 ...
- python实现迭代法求方程组的根
有方程组如下: 迭代法求解x,python代码如下: import numpy as np import matplotlib.pyplot as plt A = np.array([[8, -3, ...
随机推荐
- iTOP-4418/6818开发板支持锂电池供电方案
iTOP-4418/6818开发板支持的是官方推荐的AXP228电池管理,动态调频,更稳定可靠,支持充放电电路与电量计(库化计), 广泛应用于各种电子产品中. 4418开发板中锂电池充放电接口,适用于 ...
- js编码处理(转)
1. 使用 JS 中的 encodeURIComponent 或 encodeURI 方法. 说明: encodeURIComponent(String) 对传递参数进行设置.不编码字符有 ...
- springboot Tomcat connector configured to listen on port 8081 failed to start.
启动报 Tomcat connector configured to listen on port 8081 failed to start. The port may already be in ...
- bin/hadoop checknative
bin/hadoop checknative #检查是否支持本地库 [root@node01 ~]# hadoop checknative19/05/28 23:12:46 INFO bzip2.Bz ...
- JAVA基础——数据流
DataInputStream 类和DataOutputStream 类 在前面的学习中,我们知道数据流处理的数据都是指字节或字节数组,但实际上很多时候不是这样的,它需要数据流能直接读.写各种各样的j ...
- WC2007 石头剪刀布 数学+最小费用最大流
题面: 有N个人参加一场比赛,赛程规定任意两个人之间都要进行一场比赛:这样总共有N*(N-1)/2场比赛.比赛已经进行了一部分,我们想知道在极端情况下,比赛结束后最多会发生多少剪刀石头布情况.即给出已 ...
- Linux基础学习一
swap:虚拟内存ctrl+a:跳到命令首部 ctrl+e:跳到命令尾部alias:指令别名cp -r:递归复制粘贴mv 源路径 目标路径:移动操作 (如果提示是否覆盖,在mv前加\即可不提示:\mv ...
- JavaScript在HTML中的应用
JavaScript在HTML中的应用 制作人:全心全意 在HTML文档中可以使用<script>...</script>标记将JavaScript脚本嵌入到其中,在HTML文 ...
- solr-5.3.1配置(win7 x64)
下载solr,下载地址http://www.eu.apache.org/dist/lucene/solr/5.3.1/solr-5.3.1.zip 解压到某个目录下,这里是解压到了d盘目录下,路径:D ...
- PHP:分页类(比较庞大不建议在项目中用)
文章来源:http://www.cnblogs.com/hello-tl/p/7685178.html <?php //地址 //page::$url=''; //每页的条数 默认10 //pa ...