mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-26 05:59:22 +08:00
79 lines
2.8 KiB
Java
79 lines
2.8 KiB
Java
package com.thealgorithms.matrixexponentiation;
|
|
|
|
import java.util.Scanner;
|
|
|
|
/**
|
|
* @author Anirudh Buvanesh (https://github.com/anirudhb11) For more information
|
|
* see https://www.geeksforgeeks.org/matrix-exponentiation/
|
|
*
|
|
*/
|
|
public final class Fibonacci {
|
|
private Fibonacci() {
|
|
}
|
|
|
|
// Exponentiation matrix for Fibonacci sequence
|
|
private static final int[][] FIB_MATRIX = {{1, 1}, {1, 0}};
|
|
private static final int[][] IDENTITY_MATRIX = {{1, 0}, {0, 1}};
|
|
// First 2 fibonacci numbers
|
|
private static final int[][] BASE_FIB_NUMBERS = {{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.IDENTITY_MATRIX;
|
|
} else {
|
|
int[][] cachedResult = fib(n / 2);
|
|
int[][] matrixExpResult = matrixMultiplication(cachedResult, cachedResult);
|
|
if (n % 2 == 0) {
|
|
return matrixExpResult;
|
|
} else {
|
|
return matrixMultiplication(Fibonacci.FIB_MATRIX, 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), BASE_FIB_NUMBERS);
|
|
System.out.println("Fib(" + n + ") = " + result[1][0]);
|
|
sc.close();
|
|
}
|
|
}
|