Skip to content

Commit 87f0c64

Browse files
authored
Merge pull request TheAlgorithms#357 from c-utkarsh/add-matrix-exponentiation-recursive
Added Matrix Exponentiation (Recursive)
2 parents 8e90893 + b24d232 commit 87f0c64

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
Source:
3+
https://en.wikipedia.org/wiki/Exponentiation_by_squaring
4+
5+
Complexity:
6+
O(d^3 log n)
7+
where: d is the dimension of the square matrix
8+
n is the power the matrix is raised to
9+
*/
10+
11+
const Identity = (n) => {
12+
// Input: n: int
13+
// Output: res: Identity matrix of size n x n
14+
// Complexity: O(n^2)
15+
const res = []
16+
for (let i = 0; i < n; i++) {
17+
res[i] = []
18+
for (let j = 0; j < n; j++) {
19+
res[i][j] = i === j ? 1 : 0
20+
}
21+
}
22+
return res
23+
}
24+
25+
const MatMult = (matA, matB) => {
26+
// Input: matA: 2D Array of Numbers of size n x n
27+
// matB: 2D Array of Numbers of size n x n
28+
// Output: matA x matB: 2D Array of Numbers of size n x n
29+
// Complexity: O(n^3)
30+
const n = matA.length
31+
const matC = []
32+
for (let i = 0; i < n; i++) {
33+
matC[i] = []
34+
for (let j = 0; j < n; j++) {
35+
matC[i][j] = 0
36+
}
37+
}
38+
for (let i = 0; i < n; i++) {
39+
for (let j = 0; j < n; j++) {
40+
for (let k = 0; k < n; k++) {
41+
matC[i][j] += matA[i][k] * matB[k][j]
42+
}
43+
}
44+
}
45+
return matC
46+
}
47+
48+
const MatrixExponentiationRecursive = (mat, m) => {
49+
// Input: mat: 2D Array of Numbers of size n x n
50+
// Output: mat^n: 2D Array of Numbers of size n x n
51+
// Complexity: O(n^3 log m)
52+
if (m === 0) {
53+
// return identity matrix of size n x n
54+
return Identity(mat.length)
55+
} else if (m % 2 === 1) {
56+
// tmp = mat ^ m-1
57+
const tmp = MatrixExponentiationRecursive(mat, m - 1)
58+
/// return tmp * mat = (mat ^ m-1) * mat = mat ^ m
59+
return MatMult(tmp, mat)
60+
} else {
61+
// tmp = mat ^ m/2
62+
const tmp = MatrixExponentiationRecursive(mat, m >> 1)
63+
// return tmp * tmp = (mat ^ m/2) ^ 2 = mat ^ m
64+
return MatMult(tmp, tmp)
65+
}
66+
}
67+
68+
const main = () => {
69+
const mat = [[1, 0, 2], [2, 1, 0], [0, 2, 1]]
70+
71+
// mat ^ 0 = [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ]
72+
console.log(MatrixExponentiationRecursive(mat, 0))
73+
74+
// mat ^ 1 = [ [ 1, 0, 2 ], [ 2, 1, 0 ], [ 0, 2, 1 ] ]
75+
console.log(MatrixExponentiationRecursive(mat, 1))
76+
77+
// mat ^ 2 = [ [ 1, 4, 4 ], [ 4, 1, 4 ], [ 4, 4, 1 ] ]
78+
console.log(MatrixExponentiationRecursive(mat, 2))
79+
80+
// mat ^ 5 = [ [ 1, 4, 4 ], [ 4, 1, 4 ], [ 4, 4, 1 ] ]
81+
console.log(MatrixExponentiationRecursive(mat, 5))
82+
}
83+
84+
main()

0 commit comments

Comments
 (0)
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