Skip to content

Matrices

WhiteBlackGoose edited this page Feb 15, 2023 · 1 revision

In this page, we show the usage and API for matrices and vectors.

Creating a matrix, vector, row vector

First of all, a vector is a one-column matrix. A row vector is a one-row matrix. Let us create a matrix:

var m = MathS.Matrix(new Entity[,]
    {
        { 1, 2, 3 },
        { 4, 5, 6 }
    });

It has two rows and three columns. You can access them by normal indexing, where the first index is the number of row, and the second one is the number of column:

Console.WriteLine(m[0, 2]); // prints the second element of the zero-th row

Output:

3

Let us print a matrix:

Console.WriteLine(m);

Output:

[[1, 2, 3], [4, 5, 6]]

Similar to it, we can create a matrix from string:

Matrix m = "[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]";
Console.WriteLine(m);

Output:

[[1, 2, 3], [4, 5, 6]]

We can also create vectors.

var v = MathS.Vector(1, 2, 3, 4);
Console.WriteLine(v);

Output:

[1, 2, 3, 4]

This creates a column vector. We can verify it by addressing RowCount and ColumnCount properties of the vector:

Console.WriteLine(v.RowCount + " " + v.ColumnCount);

Output:

4 1

That is, 4 rows and 1 column.

There is overloaded ToString, which allows to print a matrix in a more convenient way:

var m = MathS.Matrix(new Entity[,]
    {
        { 1, 2, 3 },
        { 4, 5, 6 }
    });
Console.WriteLine(m.ToString(multilineFormat: true));

Output:

Matrix[2 x 3]
1   2   3
4   5   6

Basic operations and properties

Like it has been discussed already, you can check the number of rows and columns of a matrix with properties RowCount and ColumnCount. You can also read the value, that is located by the specified row index and column index.

But there is also one-argument indexing: it is relevant in case you want to get the row of your matrix. It also will return a single element if your matrix is vector. Example:

var m = MathS.Matrix(new Entity[,]
    {
        { 1, 2, 3 },
        { 4, 5, 6 }
    });
Console.WriteLine("The first row: " + m[0].ToString());
Console.WriteLine("The second row: " + m[1].ToString());
var v = MathS.Vector(1, 2, 3, 4, 5);
Console.WriteLine("The third element: " + v[2].ToString());
Console.WriteLine("The last element: " + v[4].ToString());

Output:

The first row: [[1, 2, 3]]
The second row: [[4, 5, 6]]
The third element: 3
The last element: 5

If you queried for a row, a row vector will be returned (a matrix with one row).

You can also work with a transposed matrix. Every matrix has its transposed, accessible by .T. It will return your matrix with swapped columns and rows. Example:

var m = MathS.Matrix(new Entity[,]
    {
        { 1, 2, 3 },
        { 4, 5, 6 }
    });
Console.WriteLine(m.ToString(multilineFormat: true));
Console.WriteLine(m.T.ToString(multilineFormat: true)); // transposed version

Output:

Matrix[2 x 3]
1   2   3
4   5   6
Matrix[3 x 2]
1   4
2   5
3   6

Creating modified versions of matrices

For the declarative style sake, there is no way to modify an existing matrix, but it is possible to get an existing matrix with some elements changed.

That is how you change a single element in a matrix:

var m = MathS.Matrix(new Entity[,]
    {
        { 1, 2, 3 },
        { 4, 5, 6 }
    });
var modified = m.WithElement(0, 2, 66);
Console.WriteLine(modified.ToString(multilineFormat: true));

Output:

Matrix[2 x 3]
1    2    66
4    5    6

WithElement changes one element, located at the specified pair of indices.

It is also overloaded for vectors and row vectors:

var v = MathS.ZeroVector(size: 10).T;
var modified = v.WithElement(4, 66).WithElement(6, 44);
Console.WriteLine(modified.ToString(multilineFormat: true));

Output:

Matrix[1 x 10]
0    0    0    0    66   0    44   0    0    0

You can replace entire rows or columns in matrices with WithRow and WithColumn:

var m = MathS.Matrix(new Entity[,]
    {
        { 1, 2, 3 },
        { 4, 5, 6 }
    });
var modified = m.WithRow(0, "[10, 20, 30]T");
Console.WriteLine(modified.ToString(multilineFormat: true));

Output:

Matrix[2 x 3]
10   20   30
4    5    6

Note, that in the fifth line we passed a transposed vector, that is, a row vector. Similar way, we can get a modified version with a column replaced:

var m = MathS.Matrix(new Entity[,]
    {
        { 1, 2, 3 },
        { 4, 5, 6 }
    });
var modified = m.WithColumn(2, "[30, 60]");
Console.WriteLine(modified.ToString(multilineFormat: true));

Output:

Matrix[2 x 3]
1    2    30
4    5    60

Finally, you can create a modified version with a more advanced modifier via With:

var m = MathS.ZeroMatrix(6).With
    ((r, c, e) => (r, c, e) switch
    {
        (_, 0, _) => 1,
        ( >= 1 and <= 4, >= 1 and <= 3, _) => 2,
        ( >= 1 and <= 4, > 3, _) => 3,
        (5, 5, _) => 4,
        _ => e
    });
Console.WriteLine(m.ToString(multilineFormat: true));

Output:

Matrix[6 x 6]
1   0   0   0   0   0
1   2   2   2   3   3
1   2   2   2   3   3
1   2   2   2   3   3
1   2   2   2   3   3
1   0   0   0   0   4

Here is a detailed explanation of this code:

var m = MathS.ZeroMatrix(6).With
    ((r, c, e) => (r, c, e) switch
    {
		// any row, in the column number 0
        (_, 0, _) => 1,
		
		// rows with indicies between 1 and 4, 
		// and columns between 1 and 3
        ( >= 1 and <= 4, >= 1 and <= 3, _) => 2,
		
		// rows between 1 and 4, all columns after 3
        ( >= 1 and <= 4, > 3, _) => 3,
		
		// the [5, 5]-th element to be set to 4
        (5, 5, _) => 4,
        _ => e
    });

Mathematical operations

Multiplication of matrices is performed according to standards. A vector is a one-column vector. In case of axes mismatch, either no multiplication happens, or an exception is thrown.

Addition and subtraction happen pointwise. In case of axes mismatch, either no operation happens, or an exception is thrown.

Division requires same-size square matrices as operands. It will first find the inverse of the right operand. If either of criterion is not met, either no divison happens, or an exception is thrown.

Example of multiplication:

var m = MathS.Matrix(new Entity[,]
    {
        { 1, 2 },
        { 3, 4 },
        { 5, 6 }
    });
var v = MathS.Vector(10, 20);
Console.WriteLine(m * v);

Output:

[50, 110, 170]

Subtraction:

var m = MathS.Matrix(new Entity[,]
    {
        { 1, 2 },
        { 3, 4 },
        { 5, 6 }
    });

var m1 = MathS.Matrix(new Entity[,]
    {
        { 1, 2 },
        { 3, 4 },
        { 5, 10 }
    });

Console.WriteLine((m1 - m).ToString(multilineFormat: true));

Output:

Matrix[3 x 2]
0   0
0   0
0   4

If you add, multiply or subtract a scalar, you may need to apply InnerSimplifed or Evaled properties. If your matrix collapses to 1x1, it will be interpreted as a scalar. For example:

var v = MathS.Vector(1, 2, 3);
Console.WriteLine(v.T * v);
Console.WriteLine((v.T * v).GetType());
Console.WriteLine((v.T * v).InnerSimplified.GetType());

Output:

[14]
AngouriMath.Entity+Matrix
AngouriMath.Entity+Number+Integer

Applying Abs onto a vector will compute its absolute length, as a sum of squares of its elements:

Console.WriteLine("(| [ a, b, c ] |)".Simplify());
Console.WriteLine("(| [ 2, 3, 6 ] |)".EvalNumerical());

Output:

sqrt(a ^ 2 + b ^ 2 + c ^ 2)
7

ComputeInverse(): tries to compute inverse. May throw an exception.

Pow(int): computes the binary power of a matrix. May throw an exception.

AsScalar(): if a matrix is 1x1, it takes its only element. Otherwise, an exception is thrown.

Determinant: the determinant of the matrix.

MainDiagonal: the vector of elements from the main diagonal.

Trace: the sum of the elements in the main diagonal.

Clone this wiki locally