export function checkIfValidMatrix(matrix: number[][]): boolean { if (matrix.length <= 0) { return false; } // Just make sure each row has equally many columns var numberOfColumns = -1; matrix.forEach(row => { if (numberOfColumns == -1) { numberOfColumns = row.length; } if (row.length != numberOfColumns) { return false; } }); return true; } export function matrixMultiply(matrixOne: number[][], matrixTwo: number[][]): number[][] { if (!checkIfValidMatrix(matrixOne) || !checkIfValidMatrix(matrixTwo)) { throw new TypeError("Two valid matrices are required"); } var rowsFirstMatrix = matrixOne.length; var colsFirstMatrix = matrixOne[0].length; var rowsSecondMatrix = matrixTwo.length; var colsSecondMatrix = matrixTwo[0].length; if (colsFirstMatrix != rowsSecondMatrix) { throw new TypeError("The two matrices do not have the correct dimensions to be multiplied together"); } var result = []; for (var i = 0; i < rowsFirstMatrix; i++) { var currentRow = []; for (var j = 0; j < colsSecondMatrix; j++) { var currentResult = 0; for (var k = 0; k < colsFirstMatrix; k++) { currentResult += matrixOne[i][k] * matrixTwo[k][j]; } currentRow.push(currentResult); } result.push(currentRow); } return result; } export function vectorDotProduct(vectorOne: number[][], vectorTwo: number[][]): number { if (!checkIfValidMatrix(vectorOne) || !checkIfValidMatrix(vectorTwo)) { throw new TypeError("Two valid matrices are required"); } if (vectorOne[0].length != 1 || vectorTwo[0].length != 1) { throw new TypeError("Vectors can only have one column"); } if (vectorOne.length != vectorTwo.length) { throw new TypeError("The two vectors need to have the same dimensions"); } var result = 0; for (var i = 0; i < vectorOne.length; i++) { result += vectorOne[i][0] * vectorTwo[i][0]; } return result; } export function vectorCrossProduct(vectorOne: number[][], vectorTwo: number[][]): number[][] { if (!checkIfValidMatrix(vectorOne) || !checkIfValidMatrix(vectorTwo)) { throw new TypeError("Two valid matrices are required"); } if (vectorOne[0].length != 1 || vectorTwo[0].length != 1) { throw new TypeError("Vectors can only have one column"); } if (vectorOne.length != vectorTwo.length) { throw new TypeError("The two vectors need to have the same dimensions"); } if (vectorOne.length != 3) { throw new TypeError("The vectors need to be three-dimensional"); } return [ [vectorOne[1][0]*vectorTwo[2][0] - vectorOne[2][0]*vectorTwo[1][0]], [vectorOne[2][0]*vectorTwo[0][0] - vectorOne[0][0]*vectorTwo[2][0]], [vectorOne[0][0]*vectorTwo[1][0] - vectorOne[1][0]*vectorTwo[0][0]] ]; } export function matrixTranspose(matrix: number[][]): number[][] { if (!checkIfValidMatrix(matrix)) { throw new TypeError("A valid matrix is required"); } var result = []; for (var j = 0; j < matrix[0].length; j++) { var currentRow = []; for (var i = 0; i < matrix.length; i++) { currentRow.push(matrix[i][j]); } result.push(currentRow); } return result; } export function addVector(vectorOne: number[][], vectorTwo: number[][]): number[][] { if (!checkIfValidMatrix(vectorOne) || !checkIfValidMatrix(vectorTwo)) { throw new TypeError("Two valid matrices are required"); } if (vectorOne[0].length != 1 || vectorTwo[0].length != 1) { throw new TypeError("Vectors can only have one column"); } if (vectorOne.length != vectorTwo.length) { throw new TypeError("The two vectors need to have the same dimensions"); } var result = []; for (var i = 0; i < vectorOne.length; i++) { result.push([vectorOne[i][0] + vectorTwo[i][0]]); } return result; } export function subtractVector(vectorOne: number[][], vectorTwo: number[][]): number[][] { if (!checkIfValidMatrix(vectorOne) || !checkIfValidMatrix(vectorTwo)) { throw new TypeError("Two valid matrices are required"); } if (vectorOne[0].length != 1 || vectorTwo[0].length != 1) { throw new TypeError("Vectors can only have one column"); } if (vectorOne.length != vectorTwo.length) { throw new TypeError("The two vectors need to have the same dimensions"); } var result = []; for (var i = 0; i < vectorOne.length; i++) { result.push([vectorOne[i][0] - vectorTwo[i][0]]); } return result; } export function getVectorMagnitude(vector: number[][]): number { if (!checkIfValidMatrix(vector)) { throw new TypeError("A valid matrix is required"); } if (vector[0].length != 1) { throw new TypeError("Vectors can only have one column"); } var result = 0; for (var i = 0; i < vector.length; i++) { result += vector[i][0]**2; } return Math.sqrt(result); } export function normalizeVector(vector: number[][]) { if (!checkIfValidMatrix(vector)) { throw new TypeError("A valid matrix is required"); } if (vector[0].length != 1) { throw new TypeError("Vectors can only have one column"); } const magnitude = getVectorMagnitude(vector); var result = []; for (var i = 0; i < vector.length; i++) { result.push([vector[i][0] / magnitude]); } return result; } export function multiplyMatrixWithScalar(scalar: number, matrix: number[][]): number[][] { if (!checkIfValidMatrix(matrix)) { throw new TypeError("A valid matrix is required"); } var result = []; for (var i = 0; i < matrix.length; i++) { var row = []; for (var j = 0; j < matrix[i].length; j++) { row.push(scalar * matrix[i][j]); } result.push(row); } return result; }