mirror of
https://github.com/TheAlgorithms/JavaScript.git
synced 2025-07-05 00:01:37 +08:00
Added Matrix Exponentiation (Recursive)
This commit is contained in:
84
Maths/MatrixExponentiationRecursive.js
Normal file
84
Maths/MatrixExponentiationRecursive.js
Normal file
@ -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()
|
Reference in New Issue
Block a user