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