介绍

程序SolveLinearEquations解决联立方程。该方案需要一个文本文件,其中包含输入和输出方程解决。这个项目是几年前我写在C#中http://www.codeproject.com/Articles/673076/Linear-Equation-Solver线性方程组求解。以外,这个程序没有图形用户界面和一个稍微修改公式格式,这个计划是非常类似于C#程序,该程序使用SparseArray模板类来实现向量和矩阵。矩阵使用DoubleIndex的类,这需要两个整数指数,实行单一的键使用SparseArray类。矩阵SparseArray的存储类型是双精度数。每个向量只是一个实例的的SparseArray类存储一个双精度值一个整数索引一键。代码使用原油的解析器来解析输入文件中的方程。这是原油,因为它需要有些僵硬的输入格式,不支持括号或数学函数。

输入文件是一个文本文件,其中包含方程。可以有不超过1024个字符的行上。方程以分号结束。如果没有分号结尾的行,然后在下一行上继续方程。

该方程具有以下格式,它允许使用加法和减法符号,以结合的形式:

[number][variable]

每个方程中必须有一个单等号。

无论是数字或变量是可选的,可以结合使用加号或减号所需的许多条款。这个数字可以包含小数点和指数。变量可以
只包含字母字符或下划线字符。

浮点指数前^字符,而不是通常的ê字符,以避免任何模糊变量名。下面的行显示一个浮点数,等于230万。

X = 2.3^6

公式必须包含一个等号。

方程组的一个例子是:

3 X + 4 Y = -5 Z

X + Z = 10 Y

X + Z = 42.5

注意空行分隔方程。

该程序产生的解决方案,这些方程:

X = 114.75
Y = 4.25
Z = -72.25

设置3个方程的另一个例子可能是:

MARYS_AGE=2BOBS_AGE ; BOBS_AGE = 3 CATHYS_AGE

CATHYS_AGE = 4;

或另外一个例子:

HEIGHT = 5 + 10

如果您忘记了公式的格式

运行下面的命令行程序,将给上述有关公式输 入文件中的要求的格式相同的信息。

SolveLinearEquations -h

背景

我在大学的时候,我写了一个电路分析程序在Fortran。我需要一种方法来解联立方程,我无意中发现了下面这本书和算法:

病态线性方程组 “,由JH威尔金森,”数字计算机的数学方法“第2卷,编辑安东尼·罗尔斯顿和赫伯特·S·维尔夫,1967年,约翰·威利父子,第65-93页的“ 解决方案。虐待空调的方程组是一组方程,是很困难或不可能解决使用给定的浮点精度。方程病态当两个或更多的方程定义几乎平行的线,或两个以上的尺寸,几乎平行的平面几乎平行的超平面的情况下。病态方程的一个例子将是:

3 10 -12 X + Y = 0.7

X + Y = 0.9,我很幸运,栽倒在这个特定的参考。虽然这本书给出了一个标准的执行 高斯消去部分旋转,教计算机科学线性代数课程,这种算法也确定是否可以找到一个准确的解决方案。这是通过使用两个矩阵的 规范和一个常数,它被设置的基础上的一个浮点数的尾数的比特数。

我已经重写了该算法几次。我写这在Fortran,C + +使用简单的数组,再在C + +使用的是稀疏的容器类,终于在C#中。

早在20世纪70年代末,我一个DEC-10计算机上运行这个算法,解决1000 1000在大约30秒的变量方程。今天,与原来的C代码,一个问题,就是在PC上运行,大小在
眨眼。这段代码是比较慢,因为它使用了一个的SparseArray,但它仍然是非常快的。

文件列表

  • SolveLinearEquations.cpp – 主程序。
  • LinearEquationParser.cpp – 解析输入文件包含方程。
  • LinearEquationParser.h – 分析器头文件。
  • CharString.cpp – 一个字符串处理类
  • CharString.h – 字符串类的头文件。
  • MatrixPackage.cpp – 包含线性方程组的求解器功能。
  • MatrixPackage.h – 线性方程组求解的头文件。
  • SparseArray.h – 的SparseArray模板文件。
  • DoubleIndex.cpp进入一个关键的两个指标 – A类。
  • DoubleIndex.h – 头文件DoubleIndex
  • SolveLinearEquations.vcproj – Visual Studio 2008项目文件。
  • SolveLinearEquations.sln – Visual Studio 2008的解决方案文件。

关于SolveLinearEquations功能

一组线性方程组的矩阵方程表示:

aMatrix xVector = bVector

该aMatrix bVector,并给出的xVector是解决。

上面给出的方程组的第一个例子中可改写为:

3 X + 4 Y + 5 Z = 0
1 X – 10 Y + 1 Z = 0
1 X + 0 Y + 1 Z = 42.5


这些方程的矩阵形式为:

| 3 4 5 | | X | | 0 || 1 10 1 | | Y | = | 0 || 1 0 1 | | Z | | 42.5 |

的aMatrix是在左边的方阵。在右边的bVector。

的xVector,其中包含的变量名,这是个未知数,是在中间。为了解决这些方程,调用SolveLinearEquations功能在MatrixPackage命名空间。此功能在文件MatrixPackage.h和定义实施文件MatrixPackage.cpp。

Status_T SolveLinearEquations(unsigned int number_of_equations,const SparseMatrix & a_matrix,const SparseVector & b_vector,SparseVector & x_vector);

一天的意图,实现更大的一组矩阵运算命名这些文件MatricPackage的意图。所有我需要的时候是一个方程求解,,和一些错误代码,现在是矩阵包。xVector,这将存储解决方案,是最后一个参数。方程的数量是一维的正方形矩阵的大小。

该计划还将表示,如果一组方程是’奇异’的工作精度。甲奇异的一组方程没有单一的解决方案,因为两个或更多的方程仅仅是其他公式的倍数,如:

X + Y = 72X + 2Y = 36

即使第二个方程,“2X + 2Y = 14”,所以这是与第一个方程相一致,没有单一的解决方案的两个方程,方程是奇异的加工精度,该方案将报告。

确定如果方程是病态的一个重要参数

文件MatrixPackage.cpp包含一个常数,它是一套基于数位双精度浮点数的尾数。

const double f_SMALL_FLOAT = 5.69E-14;

如果线性方程解算器移植到另一个平台上,那么一定要调整这个常数。该代码包含以下注释,关于这个常数。

/ / 原来实行浮动的电脑上
。对于该系统,下面的值
/ / 设置为2.92E-11,只是略大于
/ / 1 /(2 ^ 35),这是2.91E-11。对于我的英特尔系统,尾数
/ / 双精度浮点数是48位,所以
/ / 值设置为略大于1 /(2 ^ 44)。1 /(^ 44)
/ / 计算结果为5.68E-14,所以值5.69E-14是用在这里。

为什么稀疏的容器用于向量和矩阵。

在20世纪70年代后期,我实现了这个算法在Fortran的电路分析程序。该阵列是硬编码的大小。因此,要解决1000 1000系统的方程需要两个矩阵,有1000 项,或一百万个条目!多年以后,我重新编码,这在C语言中,再次与硬编码的大小。大多数现实世界的问题,要求矩阵大小远远小于1000 1000,或矩阵是稀疏的。电路分析程序通常需要大约5每个方程中,其中每个词对应的一列“组成的”矩阵。所以,一个1000 1000矩阵这样的问题会只有1000 5星,或5000的非零项。因此,稀疏容器将只有5000双精度值存储,1000 1000,而一个完整的矩阵将需要一百万双精度值,或尽可能多值的200倍!

对于非常大的问题,节省空间巨大,值得在运行时的性能退化。

另外,我意识到,这是很容易实现稀疏的容器和算法,将其转换为使用固定大小的数组,而做相反的是大量的工作。所以,有人可以转换使用了大量的空间,并有可能更快。随着现代处理器的高速缓存中,根据总线的速度和处理器体系结构,使得该算法使用了大量的内存,可以使算法的速度较慢,即使当执行的指令数是由更小。

使用代码

创建一个文件,该文件只包含方程早在这篇文章中提到的格式,或使用提供的文件equations.txt的。输入:

SolveLinearEquations equations.txt

该计划将输出变量名和值按字母顺序排序的列表。对于文件equations.txt,输出将是:

Linear Equation Solver – Version 2.01
Copyright (C) William Hallahan 2001-2013.
Ann = 2
Joe = 8
Mary = 12
Rita = 18
Tom = 70

总结

只有的ASCII构建支持Windows。字符串类型类不支持Unicode,但大部分其他的代码将被移植。最困难的代码端口将输入文件的代码,使用ofstream的。虽然这是可能的,但它需要更多的工作,使其跨平台移植。

我还没有测试在g+ +编译器中的代码SparseArray.h MatrixPackage.cpp(H)在Linux上使用。我预计,如果代码不编译和在Linux,使其工作所需的改变将是最小的和简单的。

C++线性方程求解的更多相关文章

  1. POJ 2142 TheBalance 模线性方程求解

    题目大意: 就是将两种砝码左右摆放,能够在物品放置在天平上时保持平衡 很容易得到 ax + by = t的模线性方程 按题目要求,希望首先满足 |x| + |y| 最小 , 如果有多种情况,再满足所有 ...

  2. POJ 2115 简单的模线性方程求解

    简单的扩展欧几里得题 这里 2^k 不能自作聪明的用 1<<k来写 , k >= 31时就爆int了 , 即使定义为long long 也不能直接这样写 后来老老实实 for(int ...

  3. MATLAB学习(四)线性方程求解,多项式运算,函数局部最优解

    >> A=[2 1 3;1 3 2];B=[5;10] B = 5 10 >> X=lsqnonneg(A,B) X = 0 2.8571 0.7143 >> A\ ...

  4. g2o求解BA 第10章

    1.g2o_bal_class.h1.1 projection.hg2o还是用图模型和边,顶点就是相机和路标,边就是观测,就是像素坐标.只不过这里的相机是由旋转(3个参数,轴角形式,就是theta*n ...

  5. poj 2891 模线性方程组求解

    Strange Way to Express Integers Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 8005   ...

  6. 深入理解图优化与g2o:g2o篇

    内容提要 讲完了优化的基本知识,我们来看一下g2o的结构.本篇将讨论g2o的代码结构,并带着大家一起写一个简单的双视图bundle adjustment:从两张图像中估计相机运动和特征点位置.你可以把 ...

  7. Cardinal样条曲线的Javascript实现(理论篇)

    首先,要对样条曲线进行插值的原因是:希望通过给定的关键帧点生成一条希望的直线或者曲线. 1.直线插值 生成一条直线,给定直线首尾的关键点P0,P1,就能确定这条直线的特性,比如y=kx+b中的斜率k和 ...

  8. 一般多项式曲线的最小二乘回归(Linear Regression)

    对于一般多项式: K为多项式最高项次,a为不确定的常数项,共k+1个; 有离散数据集对应,其方差: β为,方差函数S对β自变量第j个参数的梯度(偏导数): 当以上梯度为零时,S函数值最小,即: 中的每 ...

  9. ACRush 楼天成回忆录

    楼教主回忆录: 利用假期空闲之时,将这几年 GCJ , ACM , TopCoder 参加的一些重要比赛作个回顾.首先是 GCJ2006 的回忆. Google Code Jam 2006 一波三折: ...

随机推荐

  1. sql server 数据库还原

    1. 用sa身份或Windows Authentication登陆数据库 2.鼠标右击DataBases选New Database 3.填写DataBase name,选择Database files ...

  2. js实现图片向上播放(轮番滚动)

    js实现图片向上播放(轮番滚动) 实现方式,多种多样,这里我们来看javascript实现方式,重点是研究里面的源代码: 看看别人是如何写出“优雅的代码” <!DOCTYPE html PUBL ...

  3. MVC强类型和弱类型的区别

    1 强类型的处理 首先必须要有一个对象的实体类,UserINfo就是一个实体类,如下: public class UserInfo() { public  int Id{set;get;} publi ...

  4. channelartlist添加栏目链接

    {dede:channelartlist} <a href='{dede:field name='typeurl'/}'></a> {/dede:channelartlist}

  5. 在Windows上安装PyCUDA跟Theano

    http://www.myexception.cn/cuda/1904274.html

  6. Spring MVC中使用Interceptor拦截器

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...

  7. Speed-BI 图表功能:服装订货与销售匹配分析

    在作为一个买手我们根据对市场的预测,订了一批的货回来. 我们总会有一个疑问:我的订货与市场的需求是一致的吗?是否出现了较大偏差.这时我们通过分析两个指标:订货占比与销售占比的差异,进行订货与销售的匹配 ...

  8. 关于 0xCCCCCCCC

    http://xingyunbaijunwei.blog.163.com/blog/static/76538067201281793111474/ http://stackoverflow.com/q ...

  9. ios-XML文档解析之SAX解析

    首先SAX解析xml *xml文档的格式特点是节点,大体思路是把每个最小的子节点作为对象的属性,每个最小子节点的'父'节点作为对象,将节点转化为对象,输出. 每个节点都是成对存在的,有开始有结束.有始 ...

  10. python 归档tarfile,zipfile学习

    一.tarfile 用法: tarfile.open(cls, name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)  返回一个Tar ...