Matrix is a two-dimensional data structure designed for c++ language. its usage is like 2D arrays in c++ and supports std namespace. This library also supports mathematics operators like multiplication, determinant, minor, cofactor and etc.
This library is used to store data in the ram because of its table based datatype and good dumping tool to recover table. Also, this library prepared for mathematics operations because of its huge support of operations.
Installation of Matrix is easy, You can clone this project in the Github and add it to your project.
#include "Matrix.h"
First of all, let's start with an example to show how to fill a matrix:
Matrix<int> m(2, 3);
m[0][0] = -1;
m[0][1] = 0;
m[0][2] = 1;
m[1][0] = 0;
m[1][1] = 4;
m[1][2] = 77;
All of the fields(cells) in Matrix must be a unique type of data. So you can specify it with a template typename on the declaration. Also, Matrix should have width and height for its structures. Fist parameter is for the number of rows and other for the number of columns.
Matrix<typename> matrix(n, m);
Another way to initialize Matrix object is using template parameters.
Matrix<typename, n, m> matrix;
Both ways are true and work well. To get back the number of rows and columns using an object, width and height members are called. width for the number of columns and height for the number of rows.
int width = matrix.width;
int height = matrix.height;
After declaration, it can be modified with two brackets like two-dimensional arrays in c++. The first bracket is for the row index and second one for column index.
matrix[0][0] = 6;
matrix[0][1] = 0;
matrix[1][0] = -7;
matrix[1][1] = 2;
Dumping Matrix object is another tool in this library and helps to debug applications easily in the console. There are three ways of debugging in Matrix library.
Here is an example of dumping Matrix object:
Matrix<string> mat(4, 3);
mat[0][0] = "Name";
mat[0][1] = "LastName";
mat[0][2] = "Email";
mat[1][0] = "Amir";
mat[1][1] = "Forsti";
mat[1][2] = "pwwiur@yahoo.com";
mat[2][0] = "Ali";
mat[2][1] = "Hajizadeh";
mat[2][2] = "example@mail.com";
mat[3][0] = "Hossein";
mat[3][1] = "Kazemi";
mat[3][2] = "example@mail.com";
mat.dump.array();
Result:
Array view:
arr[0]: Name
arr[1]: LastName
arr[2]: Email
arr[3]: Amir
arr[4]: Forsti
arr[5]: pwwiur@yahoo.com
arr[6]: Ali
arr[7]: Hajizadeh
arr[8]: example@mail.com
arr[9]: Hossein
arr[10]: Kazemi
arr[11]: example@mail.com
Note: Through the results of array dump, Matrix is a one-dimensional array that is performed to 2D activities.
mat.dump.table();
Result:
Table view:
Name LastName Email
-----------------------------------------------------
Amir Forstai pwwiur@yahoo.com
Ali Hajizadeh example@mail.com
Hossein Kazemi example@mail.com
mat.dump.matrix();
Result:
Matrix view:
- -
| Name LastName Email |
| Amir Forstai pwwiur@yahoo.com |
| Ali Hajizadeh example@mail.com |
| Hossein Kazemi example@mail.com |
- -
To use associative arrays without third-party libraries like std::map Matrix can be used for key, value structures.
// matrix 3x4 initialization for strings
Matrix<string> matrix(3, 3);
// setting columns
matrix[0][0] = "Name";
matrix[0][1] = "LastName";
matrix[0][2] = "Email";
// setting rows
matrix[1]["Name"] = "Amir";
matrix[1]["LastName"] = "Forstai";
matrix[1]["Email"] = "pwwiur@yahoo.com";
cout << "Your name is " << matrix[1]["Name"] << endl;
cout << "Your last name is " << matrix[1]["LastName"] << endl;
cout << "Your email is " << matrix[1]["LastName"];
Result
Your name is Amir
Your last name is "Forstai"
Your email is pwwiur@yahoo.com
In mathematics, matrix calculus is one of the special topics that coding its rules and operators is a time-consuming job. Hoply Matrix library comes with matrix calculus main operations that are easy to use.
Comparisons between two matrices and datatypes are one the most used programming issues. The table below is showing that how comparison operators are working in Matrix library.
Operator | Description |
A == B | Returns true when all of the cells in two matrices are equal peer to peer. |
A != B | Returns true when only one of the cells in two matrices is not equal to same cell in other. |
A > B | Returns true if width * height of A is greater than width * height of B or all of the cell values in A are greater than all of the cells in B peer to peer. |
A < B | Returns true if width * height of B is greater than width * height of A or all of the cell values in B are greater than all of the cells in A peer to peer. |
A >= B | Returns true if A is greater or equal to B. |
A <= B | Returns true if B is greater or equal to A. |
Example of comparison operators usage:
Matrix<int> A(1, 2);
A[0][0] = 3;
A[0][1] = 2;
Matrix<int> B(1, 2);
B[0][0] = 1;
B[0][1] = 0;
if(A < B){
cout << "B is greater than A";
}
else{
cout << "A is greater than B";
}
Result:
A is greater than B
Initialize operator is used to filling the matrix with new values. There is three different initializations method in Matrix library.
Example of initializing to a number:
Matrix<int> matrix(2, 3);
matrix = 105;
matrix.dump.matrix();
Result:
Matrix view:
- -
| 105 105 105 |
| 105 105 105 |
- -
Example of initializing identity matrix:
Matrix<int> matrix(4, 4);
matrix = 1;
matrix.dump.matrix();
Result:
Matrix view:
- -
| 1 0 0 0 |
| 0 1 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
- -
Example of matrix equalization:
Matrix<int> matrix1(1, 3);
matrix1[0][0] = 133;
matrix1[0][1] = 0;
matrix1[0][2] = -14;
Matrix<int> matrix2(1, 3);
matrix2 = matrix1;
matrix2.dump.matrix();
Result:
Matrix view:
- -
| 133 0 -14 |
- -
The result of plus operator for two matrices is collecting cells peer to peer.
Matrix<int> A(1, 3);
A[0][0] = 133;
A[0][1] = 0;
A[0][2] = -14;
Matrix<int> B(1, 3);
B[0][0] = 1;
B[0][1] = 1220;
B[0][2] = 6;
Matrix<int> result(1, 3);
result = A + B;
result.dump.matrix();
Result:
Matrix view:
- -
| 134 1220 -8 |
- -
Adding a single number using this operator to a matrix will affect all of the cells. As we saw in initialization operators, initializing a matrix to 1 is initializing an identity matrix, To have a matrix filled by number 1, Plus operator should be used.
Matrix<int> matrix(4, 4);
matrix = matrix + 1;
matrix.dump.matrix();
Result:
Matrix view:
- -
| 1 1 1 1 |
| 1 1 1 1 |
| 1 1 1 1 |
| 1 1 1 1 |
- -
Multiplication in matrix calculus is not the same as algebra calculus to multiple number peer to peer. This job takes some advantages to being done. Matrix library has done this. To multiply two matrices A and B, the width of A should be equal to the height of B.
Matrix<int> A(1, 2);
Matrix<int> B(2, 3);
Matrix<int> result(1, 3);
A[0][0] = 7;
A[0][1] = 10;
B[0][0] = 1;
B[0][1] = 4;
B[0][2] = 2;
B[1][0] = 1;
B[1][1] = 2;
B[1][2] = 100;
result = A * B;
result.dump.matrix();
Result:
Matrix view:
- -
| 17 48 1014 |
- -
How about multiplying a matrix with a number? The single number must be multiplied with all of the matrix cells.
Matrix<int> matrix(1, 4);
Matrix<int> result(1, 4);
matrix[0][0] = 7;
matrix[0][1] = 59;
matrix[0][0] = 10;
matrix[0][1] = 813;
result = matrix * 3;
result.dump.matrix();
Result:
Matrix view:
- -
| 21 177 30 2439 |
- -
Only square matrices can be raised to a power of a number. Raising a matrix to a power of number like x means multiplying matrix x time with itself. There are some assumptions that can happen. Raising to 0 will cause identity matrix and 1 will cause matrix itself, raising to a negative number will cause inversing matrix.
`A^0 = I`
`A^1 = A`
`A^-3 = (A^-1)^3`
`A^-1 = 1/det(A) cof(A)`
Example of using power operator in Matrix library:
Matrix<float> matrix(2, 2);
Matrix<float> result(2, 2);
matrix[0][0] = 3;
matrix[0][1] = 3.5;
matrix[1][0] = 3.2;
matrix[1][1] = 3.6;
result = matrix ^ -3;
result.dump.matrix();
Result:
Matrix view:
- -
| -2514 2404.06 |
| 2198 -2101.87 |
- -
Dividing is the opposite of multiplication in matrices. The denominator should be inverted first then multiplied to other.
`A/B = A B^-1`
The height of the first matrix should be equal to the width of the second matrix and the second matrix should be square in the division. Here is an example of division:
Matrix<float> A(1, 2);
A[0][0] = 118.4;
A[0][1] = 135.2;
Matrix<float> B(2, 2);
B[0][0] = 3;
B[0][1] = 3.5;
B[1][0] = 3.2;
B[1][1] = 3.6;
Matrix<float> result(1, 2);
result = A/B;
result.dump.matrix();
Result:
Matrix view:
- -
| 16 22 |
- -
Like multiplication of a matrix, Division to a single number can be done too. All of the cells in a matrix should be divided by the number.
Matrix<double> matrix(1, 4);
Matrix<double> result(1, 4);
matrix[0][0] = 21;
matrix[0][1] = 177;
matrix[0][0] = 30;
matrix[0][1] = 2439;
result = matrix / 3;
result.dump.matrix();
Result:
Matrix view:
- -
| 7 59 10 813 |
- -
Determinant of a square matrix can be easily calculated by det function.
Matrix<int> matrix(2, 2);
matrix[0][0] = 4;
matrix[0][1] = 7;
matrix[1][0] = 9;
matrix[1][1] = 1;
cout << det(matrix);
Result:
-59
Cofactor of a square matrix can be easily calculated by cofactor function.
To get cofactor of a cell this function gets 3 arguments.
Matrix<int> matrix(2, 2);
matrix[0][0] = 4;
matrix[0][1] = 7;
matrix[1][0] = 9;
matrix[1][1] = 1;
int i = 1;
int j = 1;
cout << cofactor(matrix, i, j);
Result:
4
To get all of the cofactors in a matrix, this function is used only with one argument like:
Matrix<int> matrix(2, 2);
matrix[0][0] = 4;
matrix[0][1] = 7;
matrix[1][0] = 9;
matrix[1][1] = 1;
Matrix<int> result(2, 2);
result = cofactor(matrix);
result.dump.matrix();
Result:
Matrix view:
- -
| 1 -7 |
| -9 4 |
- -
Minor of a square matrix can be easily calculated by Minor function.
Like cofactor function, minor function is used to calculate minor of a cell or all cells in a matrix result.
Matrix<int> matrix(2, 2);
matrix[0][0] = 4;
matrix[0][1] = 7;
matrix[1][0] = 9;
matrix[1][1] = 1;
int i = 1;
int j = 0;
cout << Minor(matrix, i, j);
Result
0
And calculating all minor in a matrix result is like:
Matrix<int> matrix(2, 2);
matrix[0][0] = 4;
matrix[0][3] = 7;
matrix[1][0] = 9;
matrix[1][1] = 1;
Matrix<int> result(2, 2);
result = Minor(matrix);
result.dump.matrix();
Result:
Matrix view:
- -
| 1 9 |
| 0 4 |
- -
Matrix object can hold Matrix objects or pointers to arrays. This helps developer to add n-dimensional objects.
Matrix<matrix<int, 4, 1>, 2, 3> matrices;
matrices[0][0][0][0]= 466;
cout << matrices[0][0][0][0];
Result:
466
For odd numbers of dimensions like 3D objects:
Matrix<int[14], 2, 3> threeD;
threeD[0][0][0] = 466;
cout << threeD[0][0][0];
Result:
466
Catching errors by try catch statement:
try{
...
}
catch(const char* e){
cout << e;
}
This library is developing under GPL-3 license and by using or modifying it you agree this projects license in its Github page.
Improve and report issues in Github project page.
Matrix data structure - 2018 May 28