(num)
| 159 | } |
| 160 | |
| 161 | const FibonacciMatrixExpo = (num) => { |
| 162 | const isBigInt = typeof num === 'bigint' |
| 163 | const ZERO = isBigInt ? 0n : 0 |
| 164 | const ONE = isBigInt ? 1n : 1 |
| 165 | // F(0) = 0, F(1) = 1 |
| 166 | // F(n) = F(n-1) + F(n-2) |
| 167 | // Consider below matrix multiplication: |
| 168 | |
| 169 | // | F(n) | |1 1| |F(n-1)| |
| 170 | // | | = | | * | | |
| 171 | // |F(n-1)| |1 0| |F(n-2)| |
| 172 | |
| 173 | // Let's rewrite it as F(n, n-1) = A * F(n-1, n-2) |
| 174 | // or F(n, n-1) = A * A * F(n-2, n-3) |
| 175 | // or F(n, n-1) = pow(A, n-1) * F(1, 0) |
| 176 | |
| 177 | if (num === ZERO) return num |
| 178 | |
| 179 | const isNeg = num < 0 |
| 180 | if (isNeg) num *= -ONE |
| 181 | |
| 182 | const A = [ |
| 183 | [ONE, ONE], |
| 184 | [ONE, ZERO] |
| 185 | ] |
| 186 | |
| 187 | const poweredA = matrixExpo(A, num - ONE) // A raised to the power n-1 |
| 188 | let F = [[ONE], [ZERO]] |
| 189 | F = matrixMultiply(poweredA, F) |
| 190 | return F[0][0] * (isNeg ? (-ONE) ** (num + ONE) : ONE) |
| 191 | } |
| 192 | |
| 193 | /* |
| 194 | Resource : https://math.hmc.edu/funfacts/fibonacci-number-formula/ |
no test coverage detected