The math.js library I have used in a couple of previous posts includes comprehensive functionality for handling matrices, and in this post I will demonstrate how to use it for creating matrices as well as basic matrix arithmetic.
Matrix Arithmetic
Before getting into writing code I'll give a brief overview of the various arithmetic operations that can be applied to matrices.
Matrix Addition and Subtraction
To add or subtract two matrices both must have the same shape (ie. have the same number of rows and columns) and the resulting matrix will also be of the same shape. Each value is simply the corresponding value in the first matrix plus or minus the corresponding value in the second.
Scalar Addition and Subtraction
Any matrix can have a scalar (single value) added or subtracted. The result is the same shape and with the scalar added to or subtracted from each value in the original matrix.
Scalar Multiplication
Scalar multiplication works in the same way as addition and subtraction, with each value in the result being the corresponding value in the original matrix multiplied by the scalar.
Matrix Multiplication
This is where things get tricky. To be able to multiply two matrices together the second must have the same number of rows as the first has columns. The resulting matrix will have the same number of rows as the first, and the same number of columns as the second.
A textual description of matrix multiplication is going to be wordy and confusing so let's go with a diagram instead:
Even that might be a bit confusing so let's split it into four stages, each highlighted in turn.
- The value in row 0*, column 0 of the result is the dot product (sum of the products of corresponding values) of row 0 of the first matrix and column 0 of the second.
- The value in row 1, column 0 of the result is the dot product of row 1 of the first matrix and column 0 of the second.
- The value in row 0, column 1 of the result is the dot product of row 0 of the first matrix and column 1 of the second.
- The value in row 1, column 1 of the result is the dot product of row 1 of the first matrix and column 1 of the second.
* Matrix row and column indexes have traditionally started at 1 but when implemented in software we'll go with zero-based indexes.
The pattern is clear - for a given row/column in the result calculate the dot product of the same row in the first matrix and the same column in the second.
The Project
This project consists of a JavaScript file called matrices.js plus a few ancilliary files which you can download as a zip file, or clone/download from Github if you prefer. Both include the minimized version of math.js. You might wish to read the full documentation on the math.js library's matrix functionality here.
Source Code Links
This is the source code for matrices.js. As well as a window.onload function it contains the following five functions:
- matrixPlusScalar - add a scalar to a matrix
- matrixTimesScalar - multiply a matrix by a scalar
- matrixPlusMatrix - add two matrices
- matrixTimesMatrix - multiply two matrices
- printMatrix - print a matrix in a neat format
matrices.js
window.onload = function() { matrixPlusScalar(); // matrixTimesScalar(); // matrixPlusMatrix(); // matrixTimesMatrix(); } function matrixPlusScalar() { writeToConsole("Add scalar to matrix<br />====================<br /><br />"); const m1 = math.matrix([ [1,2,3],[4,5,6] ]); const m2 = math.add(m1, 7); printMatrix(m1); writeToConsole("<br />+ 7 =<br /><br />"); printMatrix(m2); writeToConsole("<br />"); } function matrixTimesScalar() { writeToConsole("Multiply matrix by scalar<br />=========================<br /><br />"); const m1 = math.matrix([ [1,2,3],[4,5,6] ]); const m2 = math.multiply(m1, 3); printMatrix(m1); writeToConsole("<br />* 3 =<br /><br />"); printMatrix(m2); writeToConsole("<br />"); } function matrixPlusMatrix() { writeToConsole("Add two matrices<br />================<br /><br />"); const m1 = math.matrix([ [1,2,3],[4,5,6] ]); const m2 = math.matrix([ [9,8,7],[6,5,4] ]); const m3 = math.add(m1, m2); printMatrix(m1); writeToConsole("<br />+<br /><br />"); printMatrix(m2); writeToConsole("<br />=<br /><br />"); printMatrix(m3); writeToConsole("<br />"); } function matrixTimesMatrix() { writeToConsole("Multiply two matrices<br />=====================<br /><br />"); const m1 = math.matrix([ [1,2,3],[4,5,6] ]); const m2 = math.matrix([ [7,10],[8,11],[9,12] ]); const m3 = math.multiply(m1, m2); printMatrix(m1); writeToConsole("<br />*<br /><br />"); printMatrix(m2); writeToConsole("<br />=<br /><br />"); printMatrix(m3); writeToConsole("<br />"); } function printMatrix(matrix) { const brackets = {"top_left": "\u23A1", "middle_left": "\u23A2", "bottom_left": "\u23A3", "top_right": "\u23A4", "middle_right": "\u23A5", "bottom_right": "\u23A6"}; const sizes = math.size(matrix); const rows = math.subset(sizes, math.index(0)); const columns = math.subset(sizes, math.index(1)); for(let r = 0; r < rows; r++) { if(r == 0) writeToConsole(brackets.top_left); else if(r == (rows - 1)) writeToConsole(brackets.bottom_left); else writeToConsole(brackets.middle_left); for(let c = 0; c < columns; c++) { writeToConsole((math.subset(matrix, math.index(r, c))).toString().padStart(4, " ")); } if(r == 0) writeToConsole(brackets.top_right); else if(r == rows - 1) writeToConsole(brackets.bottom_right); else writeToConsole(brackets.middle_right); writeToConsole("<br />"); } }
window.onload
This function simply calls the four subsequent functions. All but the first are commented out so we can uncomment and run them one at a time.
matrixPlusScalar
Here we see the syntax for creating a matrix with math.js for the first time:
const m1 = math.matrix([ [1,2,3],[4,5,6] ]);
This creates a matrix with two rows and three column. The values are hard-coded but you can of course use variables or even function calls.
The next line...
const m2 = math.add(m1, 7);
...shows the math.js add method. We then use the printMatrix function a couple of times, and I will describe this further down.
Open matrices.htm in your browser. This is the result.
matrixTimesScalar
This function works in a similar way although here we multiply by a scalar rather than add.
Comment out matrixPlusScalar in window.onload, uncomment matrixTimesScalar, and refresh the page.
matrixPlusMatrix
Slightly more complicated here: we create two matrices and add them.
Uncomment matrixPlusMatrix, and refresh the page again.
matrixTimesMatrix
Finally, two more matrices which are multiplied.
Do the comment/uncomment/refresh thing one last time.
printMatrix
The printMatrix function uses some obscure Unicode characters to print square brackets around the matrix values, which are themselves printed within nested loops.