diff --git a/DIRECTORY.md b/DIRECTORY.md index 3237c4e5..710a5a7f 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -111,6 +111,7 @@ * [Is Square Free](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/is_square_free.ts) * [Juggler Sequence](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/juggler_sequence.ts) * [Lowest Common Multiple](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/lowest_common_multiple.ts) + * [Matrix Multiplication](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/matrix_multiplication.ts) * [Number Of Digits](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/number_of_digits.ts) * [Pascals Triangle](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/pascals_triangle.ts) * [Perfect Cube](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/perfect_cube.ts) diff --git a/maths/matrix_multiplication.ts b/maths/matrix_multiplication.ts new file mode 100644 index 00000000..78b861aa --- /dev/null +++ b/maths/matrix_multiplication.ts @@ -0,0 +1,44 @@ +/** + * @function matrixMultiplication + * @description Multiply a matrix with either another matrix, a vector or a scalar + * @param {Number[][]} matA - An array of an array of numbers + * @param {Number[][] | Number[] | Number} b - Either an array of an array of numbers, an array of numbers, or a number + * @return {Number[][] | Number[]} - Either an array of an array of numbers, or an array of numbers + * @example matrixMultiplication([[1, 2], [3, 4]], [[1, 2], [3, 4]]) = [[7, 10], [15, 22]] + * @example GreatestCommonFactor([[1, 2], [3, 4]], 2) = [[2, 4], [6, 8]] + * @example GreatestCommonFactor([[1, 2], [3, 4]], [1, 2]) = [5, 11] + */ + +function matrixMultiplication(matA: number[][], b: number[][]): number[][]; +function matrixMultiplication(matA: number[][], b: number): number[][]; +function matrixMultiplication(matA: number[][], b: number[]): number[]; + +function matrixMultiplication(matA: number[][], b: any): Number[][] | Number[] | null { + let matC: any = null; + + if (typeof b === 'number') { + matC = matA.map(row => row.map(colVal => colVal * b)); + } else { + if (matA[0].length !== b.length) { + return null; + } + + if (typeof b[0] === 'number') { + matC = matA.map(row => row.reduce((sum, colVal, i) => sum + colVal * b[i], 0)); + } else { + matC = new Array(matA.length).fill(null).map(() => new Array(b[0].length).fill(0)); + let i: number, j: number, k: number; + + for (i = 0; i < matA.length; i++) { + for (j = 0; j < b[0].length; j++) { + for (k = 0; k < matA[0].length; k++) { + matC[i][j] += matA[i][k] * b[k][j]; + } + } + } + } + } + return matC; +} + +export { matrixMultiplication }; diff --git a/maths/test/matrix_multiplication.test.ts b/maths/test/matrix_multiplication.test.ts new file mode 100644 index 00000000..4c869f2a --- /dev/null +++ b/maths/test/matrix_multiplication.test.ts @@ -0,0 +1,170 @@ +import { matrixMultiplication } from '../matrix_multiplication'; + +describe('Matrix-matrix multiplication', () => { + it.each([ + [ + [ + [1, 2], + [3, 4] + ], + [ + [1, 2], + [3, 4] + ], + [ + [7, 10], + [15, 22] + ] + ], + [ + [ + [1, 2], + [3, 4] + ], + [ + [4, 3], + [2, 1] + ], + [ + [8, 5], + [20, 13] + ] + ], + [ + [ + [1, 2], + [3, 4] + ], + [ + [-1, 3], + [2, -4] + ], + [ + [3, -5], + [5, -7] + ] + ], + [ + [ + [1, 2], + [3, 4] + ], + [ + [1, 2] + ], + null + ], + [ + [ + [1, 2], + [3, 4] + ], + [ + [1, 2], + [3, 4], + [5, 6] + ], + null + ], + ])('Multiplying %j with %j should return %j', (matA, matB, expected) => { + expect(matrixMultiplication(matA, matB)).toEqual(expected); + }); +}); + +describe('Matrix-scalar multiplication', () => { + it.each([ + [ + [ + [1, 2], + [3, 4] + ], + 0, + [ + [0, 0], + [0, 0] + ] + ], + [ + [ + [1, 2], + [3, 4] + ], + 1, + [ + [1, 2], + [3, 4] + ] + ], + [ + [ + [1, 2], + [3, 4] + ], + 2, + [ + [2, 4], + [6, 8] + ] + ], + [ + [ + [1, 2], + [3, 4] + ], + -3, + [ + [-3, -6], + [-9, -12] + ] + ], + ])('Multiplying %j with %i should return %j', (matA, scalar, expected) => { + expect(matrixMultiplication(matA, scalar)).toEqual(expected); + }); +}); + +describe('Matrix-vector multiplication', () => { + it.each([ + [ + [ + [1, 2], + [3, 4] + ], + [1, 2], + [5, 11] + ], + [ + [ + [1, 2], + [3, 4] + ], + [3, 4], + [11, 25] + ], + [ + [ + [1, 2], + [3, 4] + ], + [-1, 0], + [-1, -3] + ], + [ + [ + [1, 2], + [3, 4] + ], + [1], + null + ], + [ + [ + [1, 2], + [3, 4] + ], + [1, 2, 3], + null + ], + ])('Multiplying %j with %j should return %j', (matA, vector, expected) => { + expect(matrixMultiplication(matA, vector)).toEqual(expected); + }); +});