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)