zoukankan      html  css  js  c++  java
  • [转]开源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

  • 相关阅读:
    linux软件安装方式
    docker 安装 jenkins touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?
    [ERR] Node goodsleep.vip:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
    Linux 常用命令 服务器间scp 用户 export 创建文件、软连接
    redis 安装 集群 主从 哨兵 docker
    WPF密码框中禁止复制、粘贴
    Application 统计在线人数
    【转义字符】HTML 字符实体&lt; &gt: &amp;等
    SQL语句统计每天的数据
    正则表达式计算代码数
  • 原文地址:https://www.cnblogs.com/gxlinhai/p/4424141.html
Copyright © 2011-2022 走看看