【原创】开源Math.NET基础数学类库使用(06)直接求解线性方程组
本博客所有文章分类的总目录:【总目录】本博客博文总目录-实时更新
开源Math.NET基础数学类库使用总目录:【目录】开源Math.NET基础数学类库使用总目录
前言
在前几篇关于Math.NET的博客中(见上面链接),主要是介绍了Math.NET中主要的数值功能,并进行了简单的矩阵向量计算例子,接着使用Math.NET的矩阵等对象,对3种常用的矩阵数据交换格式的读写。一方面可以了解Math.NET的使用,另一方面以后也可以直接读取和保存数据为这两种格式,给大家的科研或者工作带来便利。接下来的文章将继续对Math.NET的功能进行讲解和演示,并附带一些数学方面的基础知识。毕竟很多人没有精力去研究Math.NET,那我就把我的研究心得一一写出来,方便后来人。
1.数值分析与线性方程
数值分析的基本含义与特点:引用
数值分析(numerical analysis)是研究分析用计算机求解数学计算问题的数值计算方法及其理论的学科,是数学的一个分支,它以数字计算机求解数学问题的理论和方法为研究对象。为计算数学的主体部分。数值分析有如下特点:
1·面向计算机
2·有可靠的理论分析
3·要有好的计算复杂性
4·要有数值实验
5.要对算法进行误差分析数值分析的主要内容:插值法,函数逼近,曲线拟和,数值积分,数值微分,解线性方程组的直接方法,解线性方程组的迭代法,非线性方程求根,常微分方程的数值解法。
所以我们今天要解决的就是数值分析的一个很小但又最常接触到的部分,方程(组)的求解。方程(组)的求解有2种方法,一种是直接求解,一种是迭代求解。直接方法比较好理解,相当与使用公式进行直接计算,结果也比较精确。而另外一种是迭代方法。从最初的猜测,迭代方法逐次近似形式收敛只在极限的精确解。
正如上面所说,方程(组)的形式很多,不同的形式以及实际要求的精度都可以使用不同的方法,而本文主要介绍最简单,也是最常见的线性方程的直接求解方法。
2.Math.NET解线性方程源码分析
本文首先对Math.NET中求解线性方程的相关源码进行分析,这样大家碰到了问题,也可以更好的查找源码解决,或者进行扩展,实现自己的一些特殊需求。Math.NET中MathNet.Numerics.LinearAlgebra.Factorization命名空间下有一个泛型接口:ISolver<T>,就是解AX = B类型的线性方程的接口类型。该接口功能很多,看看下面的接口源代码和注释(本人进行了简单的翻译),就很清楚了。
using System; namespace MathNet.Numerics.LinearAlgebra.Factorization
{
/// <summary>形如AX = B的线性方程组求解的接口类型</summary>
/// <typeparam name="T">泛型参数,支持类型有:double, single, <see cref="Complex"/>,
/// 以及 <see cref="Complex32"/>.</typeparam>
public interface ISolver<T> where T : struct, IEquatable<T>, IFormattable
{
/// <summary>求解AX=B的线性方程组</summary>
/// <param name="input">右矩阵<c>B</c>.</param>
/// <returns>返回求解结果矩阵 <c>X</c>.</returns>
Matrix<T> Solve(Matrix<T> input); /// <summary>求解AX=B的线性方程组</summary>
/// <param name="input">右矩阵 <c>B</c>.</param>
/// <param name="result">求解结果矩阵, <c>X</c>.</param>
void Solve(Matrix<T> input, Matrix<T> result); /// <summary>求解AX=b的线性方程组</summary>
/// <param name="input">等式的右边向量 <c>b</c>.</param>
/// <returns>返回求解结果的左边向量 , <c>x</c>.</returns>
Vector<T> Solve(Vector<T> input); /// <summary>求解AX=b的线性方程组</summary>
/// <param name="input">等式的右边向量 <c>b</c>.</param>
/// <param name="result">求解结果矩阵, <c>x</c>.</param>
void Solve(Vector<T> input, Vector<T> result);
}
}
由于求解线性方程组主要用到了矩阵的分解,Math.NET实现了5种矩阵分解的算法:LU,QR,Svd,Evd,Cholesky。而GramSchmidt是继承QR的,每一个都是实现了ISolver<T>接口,因此就可以直接使用矩阵的分解功能,直接进行线性方程组的求解。为了方便,我们举一个LU的源码例子,简单的看看源码的基本情况:
public abstract class LU<T> : ISolver<T> where T : struct, IEquatable<T>, IFormattable
{
static readonly T One = BuilderInstance<T>.Matrix.One; readonly Lazy<Matrix<T>> _lazyL;
readonly Lazy<Matrix<T>> _lazyU;
readonly Lazy<Permutation> _lazyP; protected readonly Matrix<T> Factors;
protected readonly int[] Pivots; protected LU(Matrix<T> factors, int[] pivots)
{
Factors = factors;
Pivots = pivots; _lazyL = new Lazy<Matrix<T>>(ComputeL);
_lazyU = new Lazy<Matrix<T>>(Factors.UpperTriangle);
_lazyP = new Lazy<Permutation>(() => Permutation.FromInversions(Pivots));
} Matrix<T> ComputeL()
{
var result = Factors.LowerTriangle();
for (var i = ; i < result.RowCount; i++)
{
result.At(i, i, One);
}
return result;
} /// <summary>Gets the lower triangular factor.</summary>
public Matrix<T> L
{
get { return _lazyL.Value; }
}
/// <summary>Gets the upper triangular factor.</summary>
public Matrix<T> U
{
get { return _lazyU.Value; }
}
/// <summary>Gets the permutation applied to LU factorization.</summary>
public Permutation P
{
get { return _lazyP.Value; }
}
/// <summary>Gets the determinant of the matrix for which the LU factorization was computed.</summary>
public abstract T Determinant { get; }
public virtual Matrix<T> Solve(Matrix<T> input)
{
var x = Matrix<T>.Build.SameAs(input, input.RowCount, input.ColumnCount);
Solve(input, x);
return x;
}
public abstract void Solve(Matrix<T> input, Matrix<T> result); public virtual Vector<T> Solve(Vector<T> input)
{
var x = Vector<T>.Build.SameAs(input, input.Count);
Solve(input, x);
return x;
}
public abstract void Solve(Vector<T> input, Vector<T> result);
public abstract Matrix<T> Inverse();
}
大家可能会注意到,上面是抽象类,这和Math.NET的实现是有关的。最终都是实现相应版本的Matrix矩阵,然后实现对应版本的类型的分解方法。下面例子会介绍具体使用,大家有疑问,可以拿着源码和例子,调试一番,知道上面的2个实现过程,就比较简单了
3.Math.NET求解线性方程的实例
假设下面是要求解的线性方程组(Ax=b):
5*x + 2*y - 4*z = -7
3*x - 7*y + 6*z = 38
4*x + 1*y + 5*z = 43
测试代码,由于求解的方法很多,只列举了几种,其他的以此类推:
var formatProvider = (CultureInfo) CultureInfo.InvariantCulture.Clone();
formatProvider.TextInfo.ListSeparator = " "; //先创建系数矩阵A
var matrixA = DenseMatrix.OfArray(new[,] {{5.00, 2.00, -4.00}, {3.00, -7.00, 6.00}, {4.00, 1.00, 5.00}}); //创建向量b
var vectorB = new DenseVector(new[] {-7.0, 38.0, 43.0}); // 1.使用LU分解方法求解
var resultX = matrixA.LU().Solve(vectorB);
Console.WriteLine(@"1. Solution using LU decomposition");
Console.WriteLine(resultX.ToString("#0.00\t", formatProvider)); // 2.使用QR分解方法求解
resultX = matrixA.QR().Solve(vectorB);
Console.WriteLine(@"2. Solution using QR decomposition");
Console.WriteLine(resultX.ToString("#0.00\t", formatProvider)); // 3. 使用SVD分解方法求解
matrixA.Svd().Solve(vectorB, resultX);
Console.WriteLine(@"3. Solution using SVD decomposition");
Console.WriteLine(resultX.ToString("#0.00\t", formatProvider)); // 4.使用Gram-Shmidt分解方法求解
matrixA.GramSchmidt().Solve(vectorB, resultX);
Console.WriteLine(@"4. Solution using Gram-Shmidt decomposition");
Console.WriteLine(resultX.ToString("#0.00\t", formatProvider)); // 5.验证结果,就是把结果和A相乘,看看和b是否相等
var reconstructVecorB = matrixA*resultX;
Console.WriteLine(@"5. Multiply coefficient matrix 'A' by result vector 'x'");
Console.WriteLine(reconstructVecorB.ToString("#0.00\t", formatProvider));
结果如下:
. Solution using LU decomposition
DenseVector -Double
3.00
1.00
6.00 . Solution using QR decomposition
DenseVector -Double
3.00
1.00
6.00 . Solution using SVD decomposition
DenseVector -Double
3.00
1.00
6.00 . Solution using Gram-Shmidt decomposition
DenseVector -Double
3.00
1.00
6.00 . Multiply coefficient matrix 'A' by result vector 'x'
DenseVector -Double
-7.00
38.00
43.00
今天的用法就到此为止,请关注博客,后续还有更多的分析和使用文章。
4.资源
如果本文资源或者显示有问题,请参考 本文原文地址:http://www.cnblogs.com/asxinyu/p/4285245.html
【原创】开源Math.NET基础数学类库使用(06)直接求解线性方程组的更多相关文章
- 开源Math.NET基础数学类库使用(06)数值分析之线性方程组直接求解
原文:[原创]开源Math.NET基础数学类库使用(06)数值分析之线性方程组直接求解 开源Math.NET基础数学类库使用系列文章总目录: 1.开源.NET基础数学计算组件Math.NET(一) ...
- 【目录】开源Math.NET基础数学类库使用总目录
本博客所有文章分类的总目录链接:[总目录]本博客博文总目录-实时更新 1.开源Math.NET数学组件文章 1.开源Math.NET基础数学类库使用(01)综合介绍 2.开源Math.NET ...
- 【原创】开源Math.NET基础数学类库使用(01)综合介绍
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...
- 【原创】开源Math.NET基础数学类库使用(02)矩阵向量计算
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...
- 【原创】开源Math.NET基础数学类库使用(03)C#解析Matlab的mat格式
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...
- 【原创】开源Math.NET基础数学类库使用(04)C#解析Matrix Marke数据格式
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...
- 【原创】开源Math.NET基础数学类库使用(05)C#解析Delimited Formats数据格式
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...
- 【原创】开源Math.NET基础数学类库使用(07)常用的数学物理常数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 1.前 ...
- 【原创】开源Math.NET基础数学类库使用(08)C#进行数值积分
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...
随机推荐
- hdu1532网络流
(双倍经验题) 第二次写dinic模板,居然一遍写对了,而且短了不少O(∩_∩)O~ #include <cstdio> #define INF 2147483647 int n,m,an ...
- UTC时间和本地时间的区别
在用AS3的Date时,年月日都有两个api,带UTC和不带UTC的,比如fullYear,fullYearUTC 输出看一下: var date:Date = new Date; trace(dat ...
- Google Play Store —与google服务器通信时出现问题
机子:MX4 前几天刷完机后出现登录Google Play Store “与google服务器通信时出现问题”,今天试了好几种方法,来总结一下 1.修改最新Hosts文件 2.SmartHosts ...
- 【转】stopPropagation, preventDefault 和 return false 的区别
因为有父, 子节点同在, 因为有监听事件和浏览器默认动作之分. 使用 JavaScript 时为了达到预期效果经常需要阻止事件和动作执行. 一般我们会用到三种方法, 分别是 stopPropagat ...
- >hibernate初认识
一.什么是hibernate 1.hibernate是java领域的一款开源的ORM框架技术 2.hibernate对JDBC进行了非常轻量级的封装(使用了反射机制+配置或注解) 二.hibernat ...
- socket.io安装部署
需要node.js环境 创建package.json npm init 下载相关依赖 npm install --save express@4.10.2npm会在当前目录下载所需要的依赖到node_m ...
- 解决bootstrap模态框内输入框无法获取焦点
bootstrap 模态框中的input标签在某些情况下会无法获取焦点. 最终解决方法:去除模态框的 tabindex="-1" 属性即可
- SQL Server
1.通过触发器来级联删除: 具体的触发器代码如下: Create TRIGGER [dbo].[DeleteRelatedProducts] ON [dbo].[ProductCategory] A ...
- Apache服务器在80端口配置多域名虚拟主机的方法
我们在配置一台服务器的时候,如果只运行一个站点,往往过于浪费资源.Nginx和Apache都可以通过配置虚拟主机实现多站点.配置虚拟主机的方式主要有两种,一种是多个不同端口对应的多个虚拟主机站点,一种 ...
- SQL Server 2016 CTP2.2 安装手记
SQL Server 2016 CTP2.2 安装手记 下载一个iso文件,解压出来(大约2.8G左右),在该路径下双击Setup.exe即可开始安装. 安装之前请先安装.NET 3.5 SP1,在服 ...