# linearalgebra.lib

A library of linear algebra functions. Its official prefix is `la`.

This library adds some new linear algebra functions:

`determinant`

`minor`

`inverse`

`transpose2`

`matMul` matrix multiplication

`identity`

`diag`

How does it work? An `NxM` matrix can be flattened into a bus `si.bus(N*M)`. These buses can be passed to functions as long as `N` and sometimes `M` (if the matrix need not be square) are passed too.

#### Some things to think about going forward

##### Implications for ML in Faust

Next step of making a "Dense"/"Linear" layer from machine learning. Where in the libraries should `ReLU` go? What about 3D tensors instead of 2D matrices? Image convolutions take place on 3D tensors shaped `HxWxC`.

##### Design of matMul

Currently the design is `matMul(J, K, L, M, leftHandMat, rightHandMat)` where `leftHandMat` is `JxK` and `rightHandMat` is `LxM`.

It would also be neat to have `matMul(J, K, rightHandMat, L, M, leftHandMat)`.

Then a "packed" matrix could be consistently stored as a combination of a 2-channel "header" `N, M` and the values `si.bus(N*M)`.

This would ultimately enable `result = packedLeftHand : matMul(packedRightHand);` for the equivalent numpy code: `result = packedLeftHand @ packedRightHand;`.

#### References

- https://github.com/grame-cncm/faustlibraries/blob/master/linearalgebra.lib

### `(la.)determinant`

Calculates the determinant of a bus that represents an `NxN` matrix.

#### Usage

    si.bus(N*N) : determinant(N) : _

Where:

- `N`: the size of each axis of the matrix.

### `(la.)minor`

An utility for finding the matrix minor when inverting a matrix. It returns the determinant of the submatrix formed by deleting the row at index `ROW` and column at index `COL`. The following implementation doesn't work but looks simple.

    minor(N, ROW, COL) = par(r, N, par(c, N, select2((ROW==r)||(COL==c),_,!))) : determinant(N-1);

#### Usage

    si.bus(N*N) : minor(N, ROW, COL) : _

Where:

- `N`: the size of each axis of the matrix.
- `ROW`: the selected position on 0th dimension of the matrix (`0 <= ROW < N`)
- `COL`: the selected position on the 1st dimension of the matrix (`0 <= COL < N`)

#### References

- https://en.wikipedia.org/wiki/Minor_(linear_algebra)#First_minor

### `(la.)inverse`

Inverts a matrix. The incoming bus represents an `NxN` matrix. Note, this is an unsafe operation since not all matrices are invertible.

#### Usage

    si.bus(N*N) : inverse(N) : si.bus(N*N)

Where:

- `N`: the size of each axis of the matrix.

### `(la.)transpose2`

Transposes an `NxM` matrix stored in row-major order, resulting in an `MxN` matrix stored in row-major order.

#### Usage

    si.bus(N*M) : transpose2(N, M) : si.bus(M*N)

Where:

- `N`: the number of rows in the input matrix
- `M`: the number of columns in the input matrix

### `(la.)matMul`

Multiply a `JxK` matrix (mat1) and an `LxM` matrix (mat2) to produce a `JxM` matrix. Note that `K==L`. Both matrices should use row-major order. In terms of numpy, this function is `mat1 @ mat2`.

#### Usage

    matMul(J, K, L, M, si.bus(J*K), si.bus(L*M)) : si.bus(J*M)

Where:

- `J`: the number of rows in `mat1`
- `K`: the number of columns in `mat1`
- `L`: the number of rows in `mat2`
- `M`: the number of columns in `mat2`

### `(la.)identity`

Creates an `NxN` identity matrix.

#### Usage

    identity(N) : si.bus(N*N)

Where:

- `N`: The size of each axis of the identity matrix.

### `(la.)diag`

Creates a diagonal matrix of size `NxN` with specified values along the diagonal.

#### Usage

    si.bus(N) : diag(N) : si.bus(N*N)

Where:

- `N`: The size of each axis of the matrix.

#### Search

From here you can search these documents. Enter your search terms below.

#### Keyboard Shortcuts

Keys | Action
--- | ---
`?` | Open this help
`n` | Next page
`p` | Previous page
`s` | Search