# module::MathMatrix [](https://github.com/Wandalen/wMathMatrix/actions/workflows/StandardPublish.yml) [](https://github.com/emersion/stability-badges#stable)
Abstract implementation of matrix math. MathMatrix introduces class Matrix, which is a multidimensional structure which, in the most trivial case, is a 2D matrix. A matrix of specific form could also be classified as a vector. MathMatrix heavily relly on MathVector, which introduces VectorAdapter. A Vector adapter is an implementation of the abstract interface, a kind of link that defines how to interpret data as the vector. An adapter is a special object to make algorithms more abstract and to use the same code for very different formats of vector specifying. Use module MathMatrix for arithmetic operations with matrices, to triangulate, permutate or transform matrix, to get a particular or the general solution of a system of linear equations, to get LU, QR decomposition, for SVD or PCA. Also, Matrix is a convenient and efficient data container. You may use it to continuously store multidimensional data.
### Try out from the repository
```
git clone https://github.com/Wandalen/wMathMatrix
cd wMathMatrix
will .npm.install
node sample/trivial/Sample.s
```
Make sure you have utility `willbe` installed. To install willbe: `npm i -g willbe@stable`. Willbe is required to build of the module.
### To add to your project
```
npm add 'wmathmatrix@stable'
```
`Willbe` is not required to use the module in your project as submodule.
### Why?
Because this implementation of linear algebra abstracts algorithms and data thanks smart data structures, minimizing the need to write extensive code and enabling building up more complex systems on top of it. The instance of the matrix does not own data buffer, but only information on how to interpret ( map ) the buffer into K-dimensional space. The matrix, as an advanced link, enables the zero-copy principle. The matrix can be used with either arithmetic purposes or to orchestrate multidimensional data.
Features of this implementation of matrix mathematics are:
- **Cleanliness**: the module does not inject methods, does not contaminate or alter the standard interface.
- **Zero-copy principle**: the module makes it possible to avoid redundant moving of memory thanks to the concept of the adapter.
- **Simplicity**: a regular array or typed buffer could be interpreted as a vector, no need to use special classes.
- **Usability**: the readability and conciseness of the code which uses the module are as important for us as the performance of the module.
- **Flexibility**: it's highly flexible, thanks to strides.
- **Reliability**: the module has good test coverage.
- **Accessibility**: the module has documentation.
- **Functional programming principles**: the module uses some principles of functional programming.
- **Native implementation**: under the NodeJS, it optionally uses binding to the native implementation of [BLAS-like](https://github.com/flame/blis) library ( not ready ).
- **GPGPU** implementation: under the browser, it optionally uses WebGL ( not ready ).
- **Performance**: the optimized build has high performance ( not ready ).
### Concepts of vector and vector adapter
The vector in this module means an ordered set of scalars. The vector is not an object, but an abstraction.
Vector adapter is an abstract interface and its implementation is a kind of link that defines how to interpret data as the vector. The interface of the adapter has many implementations.
To get more details have a look module MathVector.
### Concept of Matrix
Matrix is a rectangular array of numbers, symbols, or expressions, arranged in rows and columns.
By default, matrix has two dimensions. In our implementation matrix might have more than two dimensions.

### Static routine `Make`
Let's creates a matrix with specified dimensions.
```js
var matrix = _.Matrix.Make([ 2, 2 ]);
console.log( `matrix :\n${ matrix }` );
/* log : matrix :
Matrix.F32x.2x2 ::
+0 +0
+0 +0
*/
```
The created matrix `matrix` has dimension `2x2`, which is specified by the argument in the call of static routine.
### Explicit constructor
Matrix also could be created by explicitly calling the constructor. To do that, at least 3 options should be specified.
```js
var matrix = new _.Matrix
({
buffer : [ 1, 2, 3, 4 ],
dims : [ 2, 2 ],
inputRowMajor : 1,
});
console.log( `matrix :\n${ matrix }` );
/* log : matrix :
Matrix.Array.2x2 ::
+1 +2
+3 +4
*/
```
The constructor receives buffer, dimensions, and hint to calculate effective strides. Created matrix `matrix` has dimensions `2х2`, what is specified explicitly.
### Static routine `MakeSquare`
Let's create a square matrix from a passed buffer or a given dimension.
```js
var matrix = _.Matrix.MakeSquare
([
1, 2,
3, 4
]);
console.log( `matrix :\n${ matrix }` );
/* log : matrix :
Matrix.Array.2x2 ::
+1 +2
+3 +4
*/
```
Static routine `MakeSquare` deduces dimension `2x2` from the length of the vector that is passed as the input.
```js
var matrix = _.Matrix.MakeSquare( 2 );
console.log( `matrix :\n${ matrix }` );
/* log : matrix :
Matrix.F32x.2x2 ::
+0 +0
+0 +0
*/
```
The dimension `2x2` is given by the scalar` 2`. Scalar is sufficient to deduce dimensions because the created matrix is square.
### Standard strides
An object of the class `Matrix` could be created by an explicit call of the constructor.
```js
var matrix = new _.Matrix
({
buffer : [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
dims : [ 3, 2 ],
inputRowMajor : 0,
});
console.log( `matrix :\n${ matrix }` );
/* log : matrix :
Matrix.Array.3x2 ::
+1 +4
+2 +5
+3 +6
*/
console.log( `effective strides :\n${ matrix.stridesEffective }` );
/* log : effective strides :
[ 1, 3 ]
*/
```
Three options are the minimum amount of information required to call the matrix constructor. Data buffer `buffer`, information about dimensions `dims`, and the option `inputRowMajor` - hints on whether the input data will be transposed.
By default, the elements in the buffer are in such sequence:

Option `inputRowMajor : 1` alter algorithm of strides calculation.
```js
var matrix = new _.Matrix
({
buffer : [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
dims : [ 3, 2 ],
inputRowMajor : 1,
});
console.log( `matrix :\n${ matrix }` );
/* log : matrix :
Matrix.Array.3x2 ::
+1 +2
+3 +4
+5 +6
*/
console.log( `effective strides :\n${ matrix.stridesEffective }` );
/* log : effective strides :
[ 2, 1 ]
*/
```
With `inputRowMajor : 1` strides are `[ 2, 1 ]`, instead of `[ 1, 2 ]` of the previous example. Sequence looks like that:

The option `inputRowMajor` shows the constructor to calculate strides. Alternatively, it is possible to specify strides explicitly:
```js
var matrix = new _.Matrix
({
buffer : [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
dims : [ 3, 2 ],
strides : [ 2, 1 ],
});
console.log( `matrix :\n${ matrix }` );
/* log : matrix :
Matrix.Array.3x2 ::
+1 +2
+3 +4
+5 +6
*/
console.log( `effective strides :\n${ matrix.stridesEffective }` );
/* log : effective strides :
[ 2, 1 ]
*/
```
Unlike the previous example, strides in this example are specified explicitly, but the result is the same.

The diagram shows how the buffer maps into the matrix. All scalars follow one by one. By default, `strides` are calculated so that all scalars go one after another. The option `inputRowMajor` specifies in which sequence row and column go.
Alternatively, one of the [static routines](doc/eng/tutorial/MatrixCreation.md) `_.Matrix.Make*` may be used to create a matrix.