• [转]开源Math.NET基础数学类库使用(02)矩阵向量计算


    前言

      本文开始一一介绍Math.NET的几个主要子项目的相关功能的使用。今天先要介绍的是最基本Math.NET Numerics的最基本矩阵与向量计算。

      如果本文章资源下载不了,或者文章显示有问题,请参考 本文原文地址http://www.cnblogs.com/asxinyu/p/4265406.html 

    1.创建Numerics矩阵与向量

      矩阵与向量计算是数学计算的核心,因此也是Math.NET Numerics的核心和基础。

      Math.NET包括对向量(Vector)和矩阵(Matrix)的支持,类型也很多。其主要注意点有:索引是从0开始,不支持空的向量和矩阵,也就是说维数或者长度最少为1。它也支持稀疏矩阵和非稀疏矩阵的向量类型。其矩阵有3种类型:稀疏,非稀疏,对角。这2个类在MathNet.Numerics.LinearAlgebra命名空间。由于一些技术和表示的原因,每一种数据类型都有一个实现,例如MathNet.Numerics.LinearAlgebra.Double有一个DenseMatrix类型,Matrix<T> 是抽象类型, 要通过其他方法去初始化。可以看看源码中的定义:

    1 public abstract partial class Vector<T> :IFormattable, IEquatable<Vector<T>>, IList, IList<T>
    2                                 where T : struct, IEquatable<T>, IFormattable
    3 public abstract partial class Matrix<T> :IFormattable, IEquatable<Matrix<T>> 
    4                                 where T : struct, IEquatable<T>, IFormattable

     创建也很简单,可以大概看看下面这段代码,构造函数还有更多的用法,不一一演示,要自己研究下源代码,记得要引用MathNet.Numerics.LinearAlgebra命名空间:

    复制代码
     1 //初始化一个矩阵和向量的构建对象
     2 var mb = Matrix<double>.Build;
     3 var vb = Vector<double>.Build;
     4 
     5 //获取随机矩阵,也可以设置随机数所属的分布
     6 var randomMatrix = mb.Random(2,3);
     7 //向量相当于是一个一维数组,只有长度
     8 var vector0 = vb.Random(3);//也可以选择分布
     9 
    10 //矩阵还可以这样初始化
    11 var matrix1 = mb.Dense(2,2,0.55);
    12 //使用函数初始化
    13 var matrix2 = mb.Dense(2,3,(i,j)=>3*i + j );
    14 
    15 //对角矩阵
    16 var diagMaxtrix = mb.DenseDiagonal(3,3,5);
    17 
    18 Console.WriteLine("randomMatrix: "+randomMatrix.ToString());
    19 Console.WriteLine("vector0: "+vector0.ToString());
    20 Console.WriteLine("matrix1: "+matrix1.ToString());
    21 Console.WriteLine("matrix2: "+matrix2.ToString());
    22 Console.WriteLine("diagMaxtrix: "+diagMaxtrix.ToString());
    23 
    24 //当然也可以直接从数组中创建
    25 double[,] x = {{ 1.0, 2.0 },{ 3.0, 4.0 }};
    26 var fromArray = mb.DenseOfArray(x);
    27 
    28 Console.WriteLine("fromArray: "+fromArray.ToString());
    复制代码

    结果如下,顺便说一下,Matrix和Vector对象已经对ToString进行了重载,以比较标准化的格式化字符串输出,很方便显示和观察:

    复制代码
     1 randomMatrix: DenseMatrix 2x3-Double
     2 0.785955   0.168426  -0.752291
     3 0.878987  -0.220992  0.0911499
     4 
     5 vector0: DenseVector 3-Double
     6  -0.47651
     7  -0.42378
     8 -0.182919
     9 
    10 matrix1: DenseMatrix 2x2-Double
    11 0.55  0.55
    12 0.55  0.55
    13 
    14 matrix2: DenseMatrix 2x3-Double
    15 0  1  2
    16 3  4  5
    17 
    18 diagMaxtrix: DenseMatrix 3x3-Double
    19 5  0  0
    20 0  5  0
    21 0  0  5
    22 
    23 fromArray: DenseMatrix 2x2-Double
    24 1  2
    25 3  4
    复制代码

    2.矩阵与向量的算术运算

      Matrix和Vector都支持常见的操作运算符号:+ ,- , * ,/ ,%等。我们可以从源码中看到部分这样的结构,限于篇幅,只简单列举几个重载操作符的方法,详细的源码在Matrix.Operators.cs文件:

    复制代码
     1 public static Matrix<T> operator +(Matrix<T> rightSide)
     2 {
     3     return rightSide.Clone();
     4 }
     5 public static Matrix<T> operator -(Matrix<T> rightSide)
     6 {
     7     return rightSide.Negate();
     8 }
     9 public static Matrix<T> operator *(Matrix<T> leftSide, T rightSide)
    10 {
    11     return leftSide.Multiply(rightSide);
    12 }
    13 public static Matrix<T> operator /(T dividend, Matrix<T> divisor)
    14 {
    15     return divisor.DivideByThis(dividend);
    16 }
    复制代码

     矩阵的相关操作是线性代数的核心和基础,而Matrix的基础功能也是非常强大的,我们看看Matrix的关于矩阵操作的相关代码,不仅包括常见矩阵分解算法,如LU,QR,Cholesky等,而且还包括一些线性方程的求解,都是可以直接通过实例方法进行的,看看抽象类的方法原型,具体的代码在Matrix.Solve.cs文件中:

    复制代码
     1 public abstract Cholesky<T> Cholesky();
     2 public abstract LU<T> LU();
     3 public abstract QR<T> QR(QRMethod method = QRMethod.Thin);
     4 public abstract GramSchmidt<T> GramSchmidt();
     5 public abstract Svd<T> Svd(bool computeVectors = true);
     6 public abstract Evd<T> Evd(Symmetricity symmetricity = Symmetricity.Unknown);
     7 public void Solve(Vector<T> input, Vector<T> result)
     8 {
     9     if (ColumnCount == RowCount)
    10     {
    11         LU().Solve(input, result);
    12         return;
    13     }
    14     QR().Solve(input, result);
    15 }
    16 public void Solve(Matrix<T> input, Matrix<T> result)
    17 {
    18     if (ColumnCount == RowCount)
    19     {
    20         LU().Solve(input, result);
    21         return;
    22     }
    23     QR().Solve(input, result);
    24 }
    25 
    26 public Matrix<T> Solve(Matrix<T> input)
    27 {
    28     var x = Build.SameAs(this, ColumnCount, input.ColumnCount);
    29     Solve(input, x);
    30     return x;
    31 }
    32 public Vector<T> Solve(Vector<T> input)
    33 {
    34     var x = Vector<T>.Build.SameAs(this, ColumnCount);
    35     Solve(input, x);
    36     return x;
    37 }
    复制代码

     3.矩阵计算综合例子

      上面的一些说明可以看到一些基本的方法情况,下面有一个实际的例子,说明基本的矩阵运算情况,当然更多高级的功能不能在一篇里面一一讲到,后续还会逐步挖掘其他使用。上代码:

    复制代码
     1 // 格式 
     2 var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();
     3 formatProvider.TextInfo.ListSeparator = " ";
     4 
     5 //创建A,B矩阵
     6 var matrixA = DenseMatrix.OfArray(new[,] { { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0 }, { 7.0, 8.0, 9.0 } });
     7 var matrixB = DenseMatrix.OfArray(new[,] { { 1.0, 3.0, 5.0 }, { 2.0, 4.0, 6.0 }, { 3.0, 5.0, 7.0 } });
     8 
     9 //矩阵与标量相乘  ,使用运算符  *            
    10 var resultM = 3.0 * matrixA;
    11 Console.WriteLine(@"Multiply matrix by scalar using operator *. (result = 3.0 * A)");
    12 Console.WriteLine(resultM.ToString("#0.00	", formatProvider));
    13 Console.WriteLine();
    14 
    15 //使用Multiply相乘,结果和上面一样
    16 resultM = (DenseMatrix)matrixA.Multiply(3.0);
    17 
    18 //矩阵与向量相乘 右乘
    19 var vector = new DenseVector(new[] { 1.0, 2.0, 3.0 });            
    20 var resultV = matrixA * vector;
    21 22 
    23 //矩阵与向量相乘 左乘 也可以使用LeftMultiply
    24 resultV = vector * matrixA;        
    25 
    26 //2个矩阵相乘,要注意矩阵乘法的维数要求
    27 resultM = matrixA * matrixB;//也可以使用Multiply方法
    28 Console.WriteLine(@"Multiply matrix by matrix using operator *. (result = A * B)");
    29 Console.WriteLine(resultM.ToString("#0.00	", formatProvider));
    30 Console.WriteLine();
    31 
    32 //矩阵加法 使用 + ,或者Add方法
    33 resultM = matrixA + matrixB;          
    34 resultM = (DenseMatrix)matrixA.Add(matrixB);
    35 
    36 //矩阵减法 使用 - ,或者Subtract方法       
    37 resultM = matrixA - matrixB;          
    38 resultM = (DenseMatrix)matrixA.Subtract(matrixB);        
    39 
    40 //矩阵除法,使用 Divide          
    41 resultM = (DenseMatrix)matrixA.Divide(3.0);  
    复制代码

    过程比较简单,结果这里只列出部分:

    复制代码
     1 Multiply matrix by scalar using operator *. (result = 3.0 * A)
     2 DenseMatrix 3x3-Double
     3  3.00      6.00    9.00
     4 12.00     15.00   18.00
     5 21.00     24.00   27.00
     6 
     7 
     8 Multiply matrix by matrix using operator *. (result = A * B)
     9 DenseMatrix 3x3-Double
    10 14.00     26.00    38.00
    11 32.00     62.00    92.00
    12 50.00     98.00   146.00
    复制代码

    4.资源

      资源大家可以去本系列文章的首页进行下载:

      如果本文章资源或者显示有问题,请参考本文原文地址http://www.cnblogs.com/asxinyu/p/4265406.html

  • 相关阅读:
    Mysql如何进行分组,并且让每一组的结果按照某个字段排序,并且获取每一组的第一个字段
    Mysql报错:Packet for query is too large (1121604 > 1048576).You can change this value on the server by setting the max_allowed_packet variable
    JavaScript判断对象有没有定义
    本地设置VirtualBox虚拟机
    Mysql关于时间排序的问题
    PHP实现页面静态化
    301重定向的两种实现方法
    判断浏览器类型
    javascript DOM事件总结
    装饰器模式
  • 原文地址:https://www.cnblogs.com/gxlinhai/p/4424141.html
Copyright © 2020-2023  润新知