Math.Net学习(一)矩阵&向量


矩阵和向量

Math.Net Numberics程序集中包含了矩阵和向量的丰富类型。他们都支持单精度和双精度类型。 像在dotnet中所有的数据类型一样,他们都是基于0索引的,例如,左上位置的索引值是(0,0),在矩阵中第一个索引值指的是行,第二个索引值指的是列,空矩阵和向量不支持,例如,每个维数的长度至少是一。

存储布局

1.向量

  • 密集向量 使用一个与向量相同长度数组。
  • 稀疏向量 用两个通常比向量小的数组,一个数组存储非零值,另一个数组存储他们的索引值,向上排序.

2.矩阵

  • 密集矩阵 用一个数组存储
  • 对角矩阵 只存储对角值,在一个数组存储。
  • 稀疏矩阵 用了三个数组存储,第一个数组存储非零值,第二个数组存储非零值对应列号,第三个数组存储行偏移值,并且最后一个元素存储矩阵中非零值的个数。

第一个数组values存储非零值,顺序是每行从左往右扫,扫完依次扫下一行,即1,7,2,8,5,3,9,6,4

第二个数组column indices存储非零值的对应列号,即0,1,1,2,0,2,3,1,3。

第三个数组row offsets存储行偏移值,首先数组大小为行数+1(该例为4+1),第i个元素值存储第i行首个非零值前面非零值的个数(第0个数肯定为0),例如该数组第1(基于0索引)个值存储的是第1行第一个非零值(该例为2)前面非零值的个数(该例为2,非零值为1,7)。在例如该数组第3个值存储的是第3行第一个非零值(6)前面非零值的个数(该例为7,非零值为1,7,2,8,5,3,9)。第三个数组最后一个值存储矩阵中所有非零值的个数(该例为9)。

 

创建矩阵和向量

Matrix<T>Vector<T>类型定义在MathNet.Numerics.LinearAlgebra 命名空间中。从技术和性能上考虑,可以对每种数据类型进行明确的实现,例如,双精度类型可以使用DenseMatrix 类,这个类在MathNet.Numerics.LinearAlgebra.Double命名空间中。你一般不需要考虑这个,而是使用通常意义的Matrix<T> 的抽象类型,我们需要其他的方法来创建矩阵和向量实例。

Matrix<double> m = Matrix<double>.Build.Random(2, 2);
Vector<double> v = Vector<double>.Build.Random(4);
Console.WriteLine(m.ToString());
Console.WriteLine(m.ToString());

由于在一个应用程序中,你通常指需要用到一个特定的数据类型,通常用来来减少代码的小技巧是定义这个组建器的快捷方式。

            var M = Matrix<double>.Build;
            var V = Vector<double>.Build;

            Matrix<double> m1 = M.Dense(2, 2);
            Matrix<double> m2 = M.Dense(2, 2,(i,j)=>i+j);

            Vector<double> v1 = V.Dense(4);
            Vector<double> v2 = V.Dense(4, (i) => i % 2);

            Console.WriteLine("{0}\n{1}\n{2}\n{3}",
                m1.ToString(), m2.ToString(), v1.ToString(), v2.ToString());

这个组建器通常确定数据的存储方式,因此如果你想构建一个稀疏矩阵,intelligense将会列出所有的选项,一旦你敲入M.Sparse.

[lang=csharp]
// 3x4 dense matrix filled with zeros
M.Dense(3, 4);

// 3x4 dense matrix filled with 1.0.
M.Dense(3, 4, 1.0);

// 3x4 dense matrix where each field is initialized using a function
M.Dense(3, 4, (i,j) => 100*i + j);

// 3x4 square dense matrix with each diagonal value set to 2.0
M.DenseDiagonal(3, 4, 2.0);

// 3x3 dense identity matrix
M.DenseIdentity(3);

// 3x4 dense random matrix sampled from a Gamma distribution
M.Random(3, 4, new Gamma(1.0, 5.0));

但是大多数情况下,我们已经其他格式的数据,需要转换到矩阵形式,当函数中有一个of的函数他是用来创建原始数据副本的。

[lang=csharp]
// Copy of an existing matrix (can also be sparse or diagonal)
Matrix<double> x = ...
M.DenseOfMatrix(x);

// Directly bind to an existing column-major array without copying (note: no "Of")
double[] x = existing...
M.Dense(3, 4, x);

// From a 2D-array
double[,] x = {{ 1.0, 2.0 },
               { 3.0, 4.0 }};
M.DenseOfArray(x);

// From an enumerable of values and their coordinates
Tuple<int,int,double>[] x = {Tuple.Create(0,0,2.0), Tuple.Create(0,1,-3.0)};
M.DenseOfIndexed(3,4,x);

// From an enumerable in column major order (column by column)
double[] x = {1.0, 2.0, 3.0, 4.0};
M.DenseOfColumnMajor(2, 2, x);

// From an enumerable of enumerable-columns (optional with explicit size)
IEnumerable<IEnumerable<double>> x = ...
M.DenseOfColumns(x);

// From a params-array of array-columns (or an enumerable of them)
M.DenseOfColumnArrays(new[] {2.0, 3.0}, new[] {4.0, 5.0});

// From a params-array of column vectors (or an enumerable of them)
M.DenseOfColumnVectors(V.Random(3), V.Random(3));

// Equivalent variants also for rows or diagonals:
M.DenseOfRowArrays(new[] {2.0, 3.0}, new[] {4.0, 5.0});
M.DenseOfDiagonalArray(new[] {2.0, 3.0, 4.0});

// if you already have existing matrices and want to concatenate them
Matrix<double>[,] x = ...
M.DenseOfMatrixArray(x);

矩阵运算


可以直接加减乘除操作,也可以使用方法进行运算。

            var M = Matrix<double>.Build;
            var V = Vector<double>.Build;

            Matrix<double> m1 = M.Dense(2, 2, 1);
            Matrix<double> m2 = M.Dense(2, 2, (i, j) => i + j);
            Matrix<double> m3 = m1 * m2;
            //or
            //Matrix<double> m3 = m1.Multiply(m2);//m1 * m2 note that order
            Matrix<double> m4 = m3.Transpose();

            Console.WriteLine("{0}\n{1}\nmultiply:\n{2}\ntranpose\n{3}",
                m1.ToString(), m2.ToString(), m3.ToString(), m4.ToString());

这些方法也重载一个方法,它赋值给第三个参数,允许避免为每单个操作分配新的变量,提供了维数匹配。

            Matrix<double> m1 = M.Diagonal(3, 2, 1);
            Matrix<double> m2 = M.Dense(2, 2, (i, j) => i + j);
            Matrix<double> m3 = M.Random(3,2);          
            m1.Multiply(m2, m3);// m3 <= m1 * m2

 

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM