From f713a5ff9c5fbf2a2ee2b08c9de75a43b800ada7 Mon Sep 17 00:00:00 2001 From: DDullahan Date: Thu, 30 Aug 2018 16:47:17 +0800 Subject: [PATCH] Added MatrixFastPower.java --- DataStructures/Matrix/MatrixFastPower.java | 139 +++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 DataStructures/Matrix/MatrixFastPower.java diff --git a/DataStructures/Matrix/MatrixFastPower.java b/DataStructures/Matrix/MatrixFastPower.java new file mode 100644 index 000000000..c2bdcf7cb --- /dev/null +++ b/DataStructures/Matrix/MatrixFastPower.java @@ -0,0 +1,139 @@ +import java.util.*; + +/** + * + * Java implementation of Matrix fast power + * It can calculate the high power of constant Matrix with O( log(K) ) + * where K is the power of the Matrix + * + * In order to do that, Matrix must be square Matrix ( columns equals rows) + * + * Notice : large power of Matrix may cause overflow + * + * + * other Matrix basic operator is based on @author Kyler Smith, 2017 + * + * @author DDullahan, 2018 + * + */ + +class Matrix { + private int[][] data; + + /** + * Constructor for the matrix takes in a 2D array + * + * @param pData + */ + public Matrix(int[][] pData) { + + /** Make a deep copy of the data */ + if(pData.length != 0) { + int[][] newData = new int[pData.length][pData[0].length]; + + for(int i = 0; i < pData.length; i++) + for(int j = 0; j < pData[0].length; j++) + newData[i][j] = pData[i][j]; + + this.data = newData; + } else { + this.data = null; + } + } + + /** + * Returns the element specified by the given location + * + * @param x : x cooridinate + * @param y : y cooridinate + * @return int : value at location + */ + public int getElement(int x, int y) { + return data[x][y]; + } + + /** + * Returns the number of rows in the Matrix + * + * @return rows + */ + public int getRows() { + if(this.data == null) + return 0; + + return data.length; + } + + /** + * Returns the number of rows in the Matrix + * + * @return columns + */ + public int getColumns() { + if(this.data == null) + return 0; + + return data[0].length; + } + + /** + * Multiplies this matrix with another matrix. + * + * @param other : Matrix to be multiplied with + * @return product + */ + public Matrix multiply(Matrix other) throws RuntimeException { + + int[][] newData = new int[this.data.length][other.getColumns()]; + + if(this.getColumns() != other.getRows()) + throw new RuntimeException("The two matrices cannot be multiplied."); + + int sum; + + for (int i = 0; i < this.getRows(); ++i) + for(int j = 0; j < other.getColumns(); ++j) { + sum = 0; + + for(int k = 0; k < this.getColumns(); ++k) { + sum += this.data[i][k] * other.getElement(k, j); + } + + newData[i][j] = sum; + } + + return new Matrix(newData); + } + + /** + * Matrix Fast Power + * + * @param k : power of Matrix + * @return product + */ + public Matrix MatrixFastPower(int k) throws RuntimeException { + + if(this.getColumns() != this.getRows()) + throw new RuntimeException("Matrix is not square Matrix."); + + int[][] newData = new int[this.getColumns()][this.getRows()]; + + for(int i = 0; i < this.getColumns(); i++) + newData[i][i] = 1; + + Matrix newMatrix = new Matrix(newData), + coMatrix = new Matrix(this.data); + + while(k != 0) { + + if((k & 1) != 0) + newMatrix = newMatrix.multiply(coMatrix); + + k >>= 1; + coMatrix = coMatrix.multiply(coMatrix); + + } + + return newMatrix; + } +}