【原创】开源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基础数学类库使用总目录 前言 ...
随机推荐
- 如何使CEF支持Flash
方法一:复制Chrome浏览器下的pepperFlash,通过cef命令行参数设置路径. public Form1() { InitializeComponent(); InitializeChrom ...
- 设置label上文字大小、颜色不一样 NSMutableAttributedString的使用
- ajax+div 代替iframe 学习尝试
工作的时候遇到了所谓html内多tab展示的情况,主要是通过iframe来关联子页面: 不过也不知道从何时开始记得是说iframe不建议多用,所以想想,还是找找有没有其他方法(不应用于工作): 先说下 ...
- PHP的数组排序函数
<?php class order{ /** * * 数组排序 * @param array $arr 例如: * array ( array ( 'deskId' => '460646' ...
- java-JDBC登录注册代码
登录: public static void main(String[] args) throws Exception{ Scanner sc = new Scanner(System.in); Sy ...
- Python之路Day13--堡垒机
一.前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机在IT管理中的重要作用的,很多人觉得,堡垒机就是跳板机,其实这个认识是不全面的,跳板功能只是堡垒机所具备的功能属性中的 ...
- css技巧
1.实现position为fixed与absolute值时居中定位: 给需要定位的元素块外加一层div盒子,外层div盒子存在于文档流中,让外层div盒子居中定位并设置position属性为relat ...
- *CF2.D(哥德巴赫猜想)
D. Taxes time limit per test 2 seconds memory limit per test 256 megabytes input standard input outp ...
- 工作总结_JS_1
获取点击下的相对应的div: $('> div', this).show(); 本身同级下的相对应的div: $('>div[name=vv]', $(this).siblings(& ...
- 【安装mysql】windows安装压缩版mysql5.7.15
160915.1459 综述 中午安装成功,但是启动失败,很可能是压缩包有问题(从别人拷的),解决了近一个小时,没搞定,于是换条方案,重新去官网下载压缩包,这次看准了windows架构,且64-b ...