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);
+  });
 });