Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions MatrixExponentiation/Fibonacci.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package MatrixExponentiation;

import java.util.Scanner;

/** @author Anirudh Buvanesh (https://github.com/anirudhb11)
* For more information see https://www.geeksforgeeks.org/matrix-exponentiation/
* */
public class Fibonacci {
// Exponentiation matrix for Fibonacci sequence
private static final int [][] fibMatrix = {{1,1}, {1,0}};
private static final int [][] identityMatrix = {{1,0}, {0,1}};
//First 2 fibonacci numbers
private static final int [][] baseFibNumbers = {{1}, {0}};

/**
* Performs multiplication of 2 matrices
* @param matrix1
* @param matrix2
* @return The product of matrix1 and matrix2
*/

private static int[][] matrixMultiplication(int[][] matrix1, int[][] matrix2){
//Check if matrices passed can be multiplied
int rowsInMatrix1 = matrix1.length;
int columnsInMatrix1 = matrix1[0].length;

int rowsInMatrix2 = matrix2.length;
int columnsInMatrix2 = matrix2[0].length;

assert columnsInMatrix1 == rowsInMatrix2;
int [][] product = new int[rowsInMatrix1][columnsInMatrix2];
for (int rowIndex = 0; rowIndex < rowsInMatrix1; rowIndex ++){
for(int colIndex = 0; colIndex < columnsInMatrix2; colIndex++){
int matrixEntry = 0;
for(int intermediateIndex = 0; intermediateIndex < columnsInMatrix1; intermediateIndex++){
matrixEntry += matrix1[rowIndex][intermediateIndex] * matrix2[intermediateIndex][colIndex];
}
product[rowIndex][colIndex] = matrixEntry;
}
}
return product;
}

/**
* Calculates the fibonacci number using matrix exponentiaition technique
* @param n The input n for which we have to determine the fibonacci number Outputs the nth
* * fibonacci number
* @return a 2 X 1 array as { {F_n+1}, {F_n} }
*/
public static int[][] fib(int n){
if(n == 0){
return Fibonacci.identityMatrix;
}
else{
int [][] cachedResult = fib(n/2);
int [][] matrixExpResult = matrixMultiplication(cachedResult, cachedResult);
if(n%2 == 0){
return matrixExpResult;
}
else{
return matrixMultiplication(Fibonacci.fibMatrix, matrixExpResult);
}
}
}

public static void main(String[] args) {
// Returns [0, 1, 1, 2, 3, 5 ..] for n = [0, 1, 2, 3, 4, 5.. ]
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int [][] result = matrixMultiplication(fib(n), baseFibNumbers);
System.out.println("Fib(" + n + ") = "+ result[1][0] );
sc.close();
}
}