From 340a323c8785c8b84bbf167803aa3896bbf33f11 Mon Sep 17 00:00:00 2001 From: Anirudh Buvanesh <39529765+anirudhb11@users.noreply.github.com> Date: Thu, 21 Oct 2021 10:36:30 +0530 Subject: [PATCH] Add matrix exponentiation based Fibonacci numbers (#2616) --- MatrixExponentiation/Fibonacci.java | 74 +++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 MatrixExponentiation/Fibonacci.java diff --git a/MatrixExponentiation/Fibonacci.java b/MatrixExponentiation/Fibonacci.java new file mode 100644 index 00000000..bdcc0681 --- /dev/null +++ b/MatrixExponentiation/Fibonacci.java @@ -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(); + } +}