I am trying to calculate nth Fibonacci number where n is larger than 1 million. The program works fine even for the 1 millionth Fibonacci number (it is really slow though). So to optimize, I added a new function, in which you multiply the last result by itself. But since the number is too great I can not figure out how many operations I need to perform.
Here is my code.
function multiplyByResult(result, baseMatrix) {
//[[0,1],[2,3]] [[0,1],[2,3 ]]
return {
0: baseMatrix[0] * result[0] + baseMatrix[1] * result[2],
1: baseMatrix[0] * result[1] + baseMatrix[1] * result[3],
2: baseMatrix[2] * result[0] + baseMatrix[3] * result[2],
3: baseMatrix[2] * result[1] + baseMatrix[3] * result[3],
};
}
function matrixSquare(matrix) {
//[[0,1],[2,3]] [[0,1],[2,3 ]]
return {
0: matrix[0] * matrix[0] + matrix[1] * matrix[2],
1: matrix[0] * matrix[1] + matrix[1] * matrix[3],
2: matrix[2] * matrix[0] + matrix[3] * matrix[2],
3: matrix[2] * matrix[1] + matrix[3] * matrix[3],
};
}
function matrixMultiplication(baseMatrix, mulitplierMatrix) {
//[[0],[2]]
return {
0:
baseMatrix[0] * mulitplierMatrix[0] + baseMatrix[1] * mulitplierMatrix[2],
2:
baseMatrix[2] * mulitplierMatrix[0] + baseMatrix[3] * mulitplierMatrix[2],
};
}
function matrixSolution(n) {
// [[0,1],[1,1]]
const baseMatrix = { 0: 0n, 1: 1n, 2: 1n, 3: 1n };
//[[0],[1]]
const mulitplierMatrix = { 0: 0n, 2: 1n };
let result = matrixSquare(baseMatrix);
if (n < 1000000)
for (let i = 2; i < n; i++) {
result = multiplyByResult(result, baseMatrix);
}
else {
let count = 1;
while (count < Math.log10(n)) {
result = matrixSquare(result);
count++;
}
}
return matrixMultiplication(result, mulitplierMatrix);
}
function fib(n) {
if (n === 0) return 0n;
if (n < 2 && n > 0) return 1n;
const count = n > 0 ? n : n * -1;
const res = matrixSolution(count);
if (n < 0 && n % 2 === 0) return res[0] * -1n;
return res[0];
}
This is the matrix implementation to find nth Fibonacci. I used JavaScript objects to represent matrices. The real problem is in matrixSolution function, I don't know how many times I should loop over to get the right result. Figuring out this entire code was already hard, and at this point I don't know what to think.