# MatrixMultiply

## MatrixMultiply(A, aRow, aCol, B, bRow, bCol)

Performs the matrix multiplication of matrix «A» by matrix «B».

Matrix «A» should be indexed by «aRow» and «aCol», and Matrix «B» by «bRow» and «bCol». The result is indexed by «aRow» and «bCol». The indexes «aCol» and «bRow» must have the same number of elements.

The indexes «aRow» and «bCol» should be distinct indexes in order to obtain a 2-D matrix result. If «aRow» and «bCol» are the same index, then the trace of AB is obtained (the trace is the diagonal elements).

## Details

When «aCol» and «bRow» are the same index, MatrixMultiply is equivalent to

`Sum(A*B, aCol)`

When all four indexes are distinct, it is equivalent to

`Sum(A*B[bRow = aCol], aCol)`

MatrixMultiply is particular convenient with «aRow» and «bRow» may be the same index (or when «aCol» and «bCol» may be the same), in which case the use of Sum to perform the multiplication becomes awkward.

## Matrix-Vector multiplication

MatrixMultiply assumes that both matrixes are 2-D, which is not the case when multiplying a matrix and a vector. The index parameters are not optional (but will be made so in a future release).

However, multiplying matricies and vectors is easily accomplished using Sum, and the awkward case mentioned above in Details does not occur. To multiply matrix «A» with vector x (where the vector is dimensioned by J), you need to identify which dimension of the matrix corresponds to the vector's index. For example, in the matrix product Ax where x is a row vector, the column dimension of «A» corresponds to x 's index. If x is a column vector, then it would be «A» 's rows. For illustration, suppose that «aCol» corresponds to x 's index, then the matrix-vector product is:

`Sum(A*x[@J = @aCol], aCol)`

The dual, where «A»'s rows correspond to x's index, the vector-matrix product is:

`Sum(A*x[@J = @aRow]], aRow)`

The following user-defined function encapsulates this as a single function with a usage fairly similar to MatrixMultiply:

`Function MatrixVectorMultiply(M: Array[I, J]; I, J: Index; x: Array[J2]; J2: Index) :=`
`if size(J) <> size(J2) then error("indexes J and J2 must be the same length in MatrixVectorMultiply");`
`Sum(M*x[@J2 = @J], J)`

It should be evident that this function evaluates `Mx`, where `x` is a row vector. You can also use it for the matrix product `xM` where `x` is a column vector just by transposing the order of the index parameters for `M`, e.g.:

`MatrixVectorMultiply(M, R, C, X, J) { matrix product M x }`
`MatrixVectorMultiply(M, C, R, X, J) { matrix product x M }`

### Treating vectors as 2-D matricies

An alternative approach sometimes used is to treat vectors as 2-D matrices, where on of those dimensions has only one element. To do this, you define an index with one element:

`Index One := `

With this index defined, you can use MatrixMultiply directly for Matrix-Vector products, e.g.:

`MatrixMultiply(A, aRow, bCol, x, J, One)`

The result has the `One` index. You can continue carrying the `One` index along through your expression, then as a final step, Subscript it away using `Result[One = 1]`.