From b24d232f0aa6e259a4a08efc1307363e17d3e61c Mon Sep 17 00:00:00 2001 From: utkarsh Date: Fri, 2 Oct 2020 16:40:48 +0530 Subject: [PATCH] Added Matrix Exponentiation (Recursive) --- Maths/MatrixExponentiationRecursive.js | 84 ++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 Maths/MatrixExponentiationRecursive.js diff --git a/Maths/MatrixExponentiationRecursive.js b/Maths/MatrixExponentiationRecursive.js new file mode 100644 index 0000000000..6ee00aa250 --- /dev/null +++ b/Maths/MatrixExponentiationRecursive.js @@ -0,0 +1,84 @@ +/* + Source: + https://en.wikipedia.org/wiki/Exponentiation_by_squaring + + Complexity: + O(d^3 log n) + where: d is the dimension of the square matrix + n is the power the matrix is raised to +*/ + +const Identity = (n) => { + // Input: n: int + // Output: res: Identity matrix of size n x n + // Complexity: O(n^2) + const res = [] + for (let i = 0; i < n; i++) { + res[i] = [] + for (let j = 0; j < n; j++) { + res[i][j] = i === j ? 1 : 0 + } + } + return res +} + +const MatMult = (matA, matB) => { + // Input: matA: 2D Array of Numbers of size n x n + // matB: 2D Array of Numbers of size n x n + // Output: matA x matB: 2D Array of Numbers of size n x n + // Complexity: O(n^3) + const n = matA.length + const matC = [] + for (let i = 0; i < n; i++) { + matC[i] = [] + for (let j = 0; j < n; j++) { + matC[i][j] = 0 + } + } + for (let i = 0; i < n; i++) { + for (let j = 0; j < n; j++) { + for (let k = 0; k < n; k++) { + matC[i][j] += matA[i][k] * matB[k][j] + } + } + } + return matC +} + +const MatrixExponentiationRecursive = (mat, m) => { + // Input: mat: 2D Array of Numbers of size n x n + // Output: mat^n: 2D Array of Numbers of size n x n + // Complexity: O(n^3 log m) + if (m === 0) { + // return identity matrix of size n x n + return Identity(mat.length) + } else if (m % 2 === 1) { + // tmp = mat ^ m-1 + const tmp = MatrixExponentiationRecursive(mat, m - 1) + /// return tmp * mat = (mat ^ m-1) * mat = mat ^ m + return MatMult(tmp, mat) + } else { + // tmp = mat ^ m/2 + const tmp = MatrixExponentiationRecursive(mat, m >> 1) + // return tmp * tmp = (mat ^ m/2) ^ 2 = mat ^ m + return MatMult(tmp, tmp) + } +} + +const main = () => { + const mat = [[1, 0, 2], [2, 1, 0], [0, 2, 1]] + + // mat ^ 0 = [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ] + console.log(MatrixExponentiationRecursive(mat, 0)) + + // mat ^ 1 = [ [ 1, 0, 2 ], [ 2, 1, 0 ], [ 0, 2, 1 ] ] + console.log(MatrixExponentiationRecursive(mat, 1)) + + // mat ^ 2 = [ [ 1, 4, 4 ], [ 4, 1, 4 ], [ 4, 4, 1 ] ] + console.log(MatrixExponentiationRecursive(mat, 2)) + + // mat ^ 5 = [ [ 1, 4, 4 ], [ 4, 1, 4 ], [ 4, 4, 1 ] ] + console.log(MatrixExponentiationRecursive(mat, 5)) +} + +main() pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy