MathNet.Numerics中的矩阵及其运算的简单整理

1.不支持空矩阵和空向量,不支持int型矩阵。

2.推荐将多个向量用集合存放,而不是组成矩阵(除非有组成矩阵的必要)

3…NET3.0之后支持lambda表达式,可以用于Dense函数的入参中,dense及稠密矩阵创建。

// 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
//用lambda表达式来对每个元素进行初始化
M.Dense(3, 4, (i,j) => 100*i + j);

// 3x4 square dense matrix with each diagonal value set to 2.0
//设置主对角线元素,其余为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));

4.当我们已经有用某种格式表征的矩阵的时候,就用以of开头的函数和方法来生成一个矩阵。

// Copy of an existing matrix (can also be sparse or diagonal)
//已有Matrix类的矩阵,直接复制生成新矩阵
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)
//这里只要改成DenseofRowMajor就可以按行写入。
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);

对于上面的最后一个,对矩阵的拼接,事实上根据已有矩阵在二维数组中的部分不同,可以横向和竖向拼接。
当代码如下时:

 double[] a = new double[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ,10,11};
 double[][] b = new double[][] { new double[]{ 1, 2, 3, 6 }, new double[]{ 0, 9, 8, 7 }, new double[]{ 10, 5, 2, 1 } };
Matrix<double> s = Matrix<double>.Build.DenseOfMatrix (M.Dense(3, 4, (i, j) => 100 * i + j));
Matrix<double> t = Matrix<double>.Build.DenseOfRowMajor(4,3,a);
Matrix<double> d = Matrix<double>.Build.DenseOfColumnArrays (b);
Matrix<double> f = Matrix<double>.Build.DenseOfMatrixArray(new Matrix<double>[,] { { t, d } }) ;
Console.WriteLine(d.ToString ());
Console.WriteLine(t.ToString());
Console.WriteLine(f.ToString());

输出如下:
MathNet.Numerics中的矩阵及其运算的简单整理_第1张图片
当修改一下DenseofMatrixArray中的入参如下时:

Matrix<double> f = Matrix<double>.Build.DenseOfMatrixArray(new Matrix<double>[,] { { t },{ d } }) ;

输出如下:
MathNet.Numerics中的矩阵及其运算的简单整理_第2张图片
如果需要改变矩阵中的某个值,可以:

f[1, 2] = 1.0;

5.向量的创建和矩阵几乎一样,以上面为参考即可。

6.矩阵和向量的运算:

(1)+、-和*是可以直接用的运算符,进行矩阵运算,但是要注意保证维数符合。

(2)矩阵的转置:

f=f.Transpose();

(3)矩阵的求逆:

f=f.Inverse ();

(4)求范数:

向量求解范数的方法资料上已经很简明:
Vectors support the following norms:

L1Norm or Manhattan norm (p=1): the sum of the absolute values.

L2Norm or Euclidean norm (p=2): the square root of the sum of the squared values.
This is the most common norm and assumed if nothing else is stated.

InfinityNorm (p=infinity): the maximum absolute value.
Norm§: generalized norm, essentially the p-th root of the sum of the absolute p-power of the values.

矩阵的范数与向量类似,但是注意如果要求p-norm需要调用RowNorms和ColumnNorms而不是NormalizeRows和NormalizeColumns。入参如果不知道数值也可以用:

t = t.NormalizeRows(t.L1Norm());

这种形式入参。
矩阵范数的资料如下:
Similarly, matrices support the following norms:

L1Norm (induced): the maximum absolute column sum.
L2Norm (induced): the largest singular value of the matrix (expensive).
InfinityNorm (induced): the maximum absolute row sum.
FrobeniusNorm (entry-wise): the square root of the sum of the squared values.
RowNorms§: the generalized p-norm for each row vector.
ColumnNorms§: the generalized p-norm for each column vector.

Vectors can be normalized to unit p-norm with the Normalize method, matrices can
normalize all rows or all columns to unit p-norm with NormalizeRows and NormalizeColumns.

(5)条件数:

M.Random(4,4).ConditionNumber();

(6)矩阵的迹(主对角线元素之和):

m.Trace();

(7)矩阵的行列式:

m.Determinant();

(8)矩阵的秩:

m.Rank();

(9)解空间(Ax=0的基础解系的个数):

m.Nullity();

(10)矩阵的range和kernel(range暂时不明白其现实意义,kernel是Ax=0的基础解系):

m.Range();
m.kernel();

但是要注意,这里因为是double型的变量,因此很难对0完全拟合,因此会出现和真正的解略有偏差,但一般都是10的负十几次方,可以忽略不计。比如如下一段代码,人工解出解系是(1,2,3):

double[] a = new double[] { 1,1,-1,1,-2,1,-5,1,1};
Matrix<double> t = Matrix<double>.Build.DenseOfRowMajor(3,3,a);
Console.WriteLine(t.ToString());
Console.WriteLine(t.Kernel ()[0].ToString ());

但是实际得出的结果是:
MathNet.Numerics中的矩阵及其运算的简单整理_第3张图片
可以看出,根的比例是大概1:2:3,但是并没有直接计算出(1,2,3)。

(11)解齐次和非齐次线性方程组:

double[] a = new double[] { 1,1,-1,1,-2,1,-4,2,-4};
Matrix<double> t = Matrix<double>.Build.DenseOfRowMajor(3,3,a);
Vector<double> h = Vector<double>.Build.DenseOfArray(new double[] { 5, 6, 8 });
Console.WriteLine(t.Solve (h).ToString ());

solve函数也可以用来解AX=B的矩阵相乘求解问题。

7.矩阵基本操作:

(1)对单个元素的赋值:

m[0,2]=-1.0;

(2)从矩阵中拆解出行、列、矩阵:

var m = M.Dense(6,4,(i,j) => 10*i + j);
m.Column(2);          // [2,12,22,32,42,52]
m.Row(3);             // [30,31,32,33]
m.SubMatrix(1,2,1,2); // [11,12; 21,22]

(3)重写整行/整列:

m.SetRow(3, V.Random(4));
m.SetColumn(3, V.Random(4));

(4)清除整个矩阵/整行/整列/部分矩阵:

m.Clear(); // set all elements to 0
m.ClearColumn(2); // set the 3rd column to 0 (0-based indexing)
m.ClearColumns(1,3); // set the 2nd and 4th columns to 0 (params-array)
m.ClearSubMatrix(1,2,1,2); // set the 2x2 submatrix with offset 1,1 to zero

(5)设定满足一定条件的数值归零。最主要的用途是由于浮点运算,有的时候数值应该是0但是实际上生成的是一个非常趋近于0的数字,可以调用CoerceZero方法来进行归零:

 

m.CoerceZero(1e-14); // 把所有小于10的-14次方的数字都归0
m.CoerceZero(x => x > 2 & x < 5);// 将大于2且小于5的数字归0

(6)对矩阵的添加删除行列以及矩阵组合操作:

var m2 = m.RemoveRow(2); // remove the 3rd rows
var m3 = m2.InsertColumn(3,v); // remove the 4th column

var m4 = m.Stack(m2); // new matrix with m on top and m2 on the bottom
var m5 = m2.Append(m3); // new matrix with m2 on the left and m3 on the right
var m6 = m.DiagonalStack(m3); // m on the top left and m3 on the bottom right

(7)Map用法,实际上就是对矩阵当作数组进行统一的一种运算,主要以Map和MapIndexed两种方法为主。以MapIndexed为例:

t.MapIndexed((x, y, z) => (x + y) * z, t);//t中每一个元素都变为行列之和乘上原本的数值

以上是根据https://numerics.mathdotnet.com/Matrix.html#Column-Space-Rank-and-Range进行整理的,此处仅为简单的翻译整理,如有侵权请联系删除。

你可能感兴趣的:(C#,c#)