diff --git a/Maths/MatrixMultiplication.js b/Maths/MatrixMultiplication.js new file mode 100644 index 000000000..306c689f6 --- /dev/null +++ b/Maths/MatrixMultiplication.js @@ -0,0 +1,91 @@ +// Wikipedia URL for General Matrix Multiplication Concepts: https://en.wikipedia.org/wiki/Matrix_multiplication + +// This algorithm has multiple functions that ultimately check if the inputs are actually matrices and if two Matrices (that can be different sizes) can be multiplied together. +// matrices that are of the same size [2x2]x[2x2], and the second is the multiplication of two matrices that are not the same size [2x3]x[3x2]. + +// MatrixCheck tests to see if all of the rows of the matrix inputted have similar size columns +const matrixCheck = (matrix) => { + let columnNumb + for (let index = 0; index < matrix.length; index++) { + if (index === 0) { + columnNumb = matrix[index].length + } else if (matrix[index].length !== columnNumb) { + console.log('The columns in this array are not equal') + } else { + return columnNumb + } + } +} + +// tests to see if the matrices have a like side, i.e. the row length on the first matrix matches the column length on the second matrix, or vise versa. +const twoMatricesCheck = (first, second) => { + const [firstRowLength, secondRowLength, firstColLength, secondColLength] = [first.length, second.length, matrixCheck(first), matrixCheck(second)] + if (firstRowLength !== secondColLength || secondRowLength !== firstColLength) { + console.log('These matrices do not have a common side') + return false + } else { + return true + } +} + +// returns an empty array that has the same number of rows as the left matrix being multiplied. +// Uses Array.prototype.map() to loop over the first (or left) matrix and returns an empty array on each iteration. +const initiateEmptyArray = (first, second) => { + if (twoMatricesCheck(first, second)) { + const emptyArray = first.map(() => { + return [''] + }) + return emptyArray + } else { + return false + } +} + +// Finally, `matrixMult` uses `Array.prototype.push()`, multiple layers of nested `for` loops, the addition assignment `+=` operator and multiplication operator `*` to perform the dot product between two matrices of differing sizes. +// Dot product, takes the row of the first matrix and multiplies it by the column of the second matrix, the `twoMatricesCheck` tested to see if they were the same size already. +// The dot product for each iteration is then saved to its respective index into `multMatrix`. +const matrixMult = (firstArray, secondArray) => { + const multMatrix = initiateEmptyArray(firstArray, secondArray) + for (let rm = 0; rm < firstArray.length; rm++) { + const rowMult = [] + for (let col = 0; col < firstArray[0].length; col++) { + rowMult.push(firstArray[rm][col]) + } + for (let cm = 0; cm < firstArray.length; cm++) { + const colMult = [] + for (let row = 0; row < secondArray.length; row++) { + colMult.push(secondArray[row][cm]) + } + let newNumb = 0 + for (let index = 0; index < rowMult.length; index++) { + newNumb += rowMult[index] * colMult[index] + } + multMatrix[rm][cm] = newNumb + } + } + return multMatrix +} + +const firstMatrix = [ + [1, 2], + [3, 4] +] + +const secondMatrix = [ + [5, 6], + [7, 8] +] + +console.log(matrixMult(firstMatrix, secondMatrix)) // [ [ 19, 22 ], [ 43, 50 ] ] + +const thirdMatrix = [ + [-1, 4, 1], + [7, -6, 2] +] +const fourthMatrix = [ + [2, -2], + [5, 3], + [3, 2] +] + +console.log(matrixMult(thirdMatrix, fourthMatrix)) // [ [ 21, 16 ], [ -10, -28 ] ] diff --git a/package-lock.json b/package-lock.json index 20ddcf663..acea3df50 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5815,6 +5815,19 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node": { + "version": "14.13.1", + "resolved": "https://registry.npmjs.org/node/-/node-14.13.1.tgz", + "integrity": "sha512-X8oMUs+fSAr+uTrVqiaunZPvXRVkVvo5J+6I1N01nlG7H+wmckYtvgxUBCBWo5HD1xAyL2vbIiwU+qW9ascTQg==", + "requires": { + "node-bin-setup": "^1.0.0" + } + }, + "node-bin-setup": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-bin-setup/-/node-bin-setup-1.0.6.tgz", + "integrity": "sha512-uPIxXNis1CRbv1DwqAxkgBk5NFV3s7cMN/Gf556jSw6jBvV7ca4F9lRL/8cALcZecRibeqU+5dFYqFFmzv5a0Q==" + }, "node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", diff --git a/package.json b/package.json index 450a58349..729e6f71b 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@babel/plugin-transform-runtime": "^7.11.5", "@babel/preset-env": "^7.11.5", "jsdom": "^16.3.0", + "node": "^14.13.1", "node-fetch": "2.6.1" }, "standard": {