From 7f81de90205cdd881c240e27d4da3d1cb4ca4529 Mon Sep 17 00:00:00 2001 From: Adam Ross <14985050+R055A@users.noreply.github.com> Date: Thu, 19 Oct 2023 20:13:41 +0200 Subject: [PATCH 1/2] Feat(maths): add matrix multiplication --- DIRECTORY.md | 1 + maths/matrix_multiplication.ts | 44 ++++++ maths/test/matrix_multiplication.test.ts | 170 +++++++++++++++++++++++ 3 files changed, 215 insertions(+) create mode 100644 maths/matrix_multiplication.ts create mode 100644 maths/test/matrix_multiplication.test.ts 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..b2dfadcb --- /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..dbec6cb8 --- /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); + }); +}); From f22d0960d266473d1270122760852ef7241370e5 Mon Sep 17 00:00:00 2001 From: Adam Ross <14985050+R055A@users.noreply.github.com> Date: Thu, 19 Oct 2023 20:27:24 +0200 Subject: [PATCH 2/2] Refactor maths/matrix_multiplication tabbing --- maths/matrix_multiplication.ts | 40 +-- maths/test/matrix_multiplication.test.ts | 320 +++++++++++------------ 2 files changed, 180 insertions(+), 180 deletions(-) diff --git a/maths/matrix_multiplication.ts b/maths/matrix_multiplication.ts index b2dfadcb..78b861aa 100644 --- a/maths/matrix_multiplication.ts +++ b/maths/matrix_multiplication.ts @@ -14,31 +14,31 @@ 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; + 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 === '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; + 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]; - } - } - } + 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; + } + return matC; } export { matrixMultiplication }; diff --git a/maths/test/matrix_multiplication.test.ts b/maths/test/matrix_multiplication.test.ts index dbec6cb8..4c869f2a 100644 --- a/maths/test/matrix_multiplication.test.ts +++ b/maths/test/matrix_multiplication.test.ts @@ -1,170 +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); - }); + 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); - }); + 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); - }); + 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); + }); });