在前几篇关于math.net的博客中(见上面链接),主要是介绍了math.net中主要的数值功能,并进行了简单的矩阵向量计算例子,接着使用math.net的矩阵等对象,对3种常用的矩阵数据交换格式的读写。一方面可以了解math.net的使用,另一方面以后也可以直接读取和保存数据为这两种格式,给大家的科研或者工作带来便利。接下来的文章将继续对math.net的功能进行讲解和演示,并附带一些数学方面的基础知识。毕竟很多人没有精力去研究math.net,那我就把我的研究心得一一写出来,方便后来人。
数值分析(numerical analysis)是研究分析用计算机求解数学计算问题的数值计算方法及其理论的学科,是数学的一个分支,它以数字计算机求解数学问题的理论和方法为研究对象。为计算数学的主体部分。数值分析有如下特点: 1·面向计算机 2·有可靠的理论分析 3·要有好的计算复杂性 4·要有数值实验 5.要对算法进行误差分析 数值分析的主要内容:插值法,函数逼近,曲线拟和,数值积分,数值微分,解线性方程组的直接方法,解线性方程组的迭代法,非线性方程求根,常微分方程的数值解法。
所以我们今天要解决的就是数值分析的一个很小但又最常接触到的部分,方程(组)的求解。方程(组)的求解有2种方法,一种是直接求解,一种是迭代求解。直接方法比较好理解,相当与使用公式进行直接计算,结果也比较精确。而另外一种是迭代方法。从最初的猜测,迭代方法逐次近似形式收敛只在极限的精确解。
正如上面所说,方程(组)的形式很多,不同的形式以及实际要求的精度都可以使用不同的方法,而本文主要介绍最简单,也是最常见的线性方程的直接求解方法。
本文首先对math.net中求解线性方程的相关源码进行分析,这样大家碰到了问题,也可以更好的查找源码解决,或者进行扩展,实现自己的一些特殊需求。math.net中mathnet.numerics.linearalgebra.factorization命名空间下有一个泛型接口:isolver<t>,就是解ax = b类型的线性方程的接口类型。该接口功能很多,看看下面的接口源代码和注释(本人进行了简单的翻译),就很清楚了。
由于求解线性方程组主要用到了矩阵的分解,math.net实现了5种矩阵分解的算法:lu,qr,svd,evd,cholesky。而gramschmidt是继承qr的,每一个都是实现了isolver<t>接口,因此就可以直接使用矩阵的分解功能,直接进行线性方程组的求解。为了方便,我们举一个lu的源码例子,简单的看看源码的基本情况:
大家可能会注意到,上面是抽象类,这和math.net的实现是有关的。最终都是实现相应版本的matrix矩阵,然后实现对应版本的类型的分解方法。下面例子会介绍具体使用,大家有疑问,可以拿着源码和例子,调试一番,知道上面的2个实现过程,就比较简单了
假设下面是要求解的线性方程组(ax=b):
5*x + 2*y - 4*z = -7 3*x - 7*y + 6*z = 38 4*x + 1*y + 5*z = 43
测试代码,由于求解的方法很多,只列举了几种,其他的以此类推:
结果如下:
今天的用法就到此为止,请关注博客,后续还有更多的分析和使用文章。