• C++线性方程求解


    介绍

    程序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,使其工作所需的改变将是最小的和简单的。

  • 相关阅读:
    PhpPresentation ppt 导出PPT
    Springcloudalibaba学习实践(1) nacos环境搭建&Eureka Server搭建
    Springcloudalibaba学习实践(2) nacos&Eureka Server服务注册实践
    xna 3.1 to xna 4.0 conversion cheat sheet.(转)
    二分查找的越界以及边界值初始化问题
    决策树知识梳理
    论文分类及写作基础
    Cypher 入门笔记
    python字符串拼接
    Spring、Hibernate 事务流程分析Session生命周期
  • 原文地址:https://www.cnblogs.com/james1207/p/3400270.html
Copyright © 2020-2023  润新知