192 lines
4.5 KiB
Java
192 lines
4.5 KiB
Java
/**
|
|
*
|
|
* 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 MatrixFastPower {
|
|
|
|
/**
|
|
* Matrix Fast Power
|
|
*
|
|
* @param matrix : square Matrix
|
|
* @param k : power of Matrix
|
|
* @return product
|
|
*/
|
|
public static Matrix FastPower(Matrix matrix, int k) throws RuntimeException {
|
|
|
|
if(matrix.getColumns() != matrix.getRows())
|
|
throw new RuntimeException("Matrix is not square Matrix.");
|
|
|
|
int[][] newData = new int[matrix.getColumns()][matrix.getRows()];
|
|
|
|
for(int i = 0; i < matrix.getColumns(); i++)
|
|
newData[i][i] = 1;
|
|
|
|
Matrix newMatrix = new Matrix(newData),
|
|
coMatrix = new Matrix(matrix.data);
|
|
|
|
while(k != 0) {
|
|
|
|
if((k & 1) != 0)
|
|
newMatrix = newMatrix.multiply(coMatrix);
|
|
|
|
k >>= 1;
|
|
coMatrix = coMatrix.multiply(coMatrix);
|
|
|
|
}
|
|
|
|
return newMatrix;
|
|
}
|
|
|
|
public static void main(String[] argv) {
|
|
|
|
int[][] data = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
|
|
Matrix matrix = new Matrix(data);
|
|
|
|
System.out.println("original matrix : ");
|
|
System.out.println(matrix.toString());
|
|
|
|
matrix = MatrixFastPower.FastPower(matrix, 5);
|
|
|
|
System.out.println("after power : ");
|
|
System.out.println(matrix.toString());
|
|
|
|
matrix = MatrixFastPower.FastPower(matrix, 1000000);
|
|
|
|
System.out.println("notice, large power may cause overflow : ");
|
|
System.out.print(matrix.toString());
|
|
System.out.println("you can use mod to fix that :-) ");
|
|
|
|
}
|
|
}
|
|
class Matrix {
|
|
public 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);
|
|
}
|
|
|
|
/**
|
|
* Returns the Matrix as a String in the following format
|
|
*
|
|
* [ a b c ] ...
|
|
* [ x y z ] ...
|
|
* [ i j k ] ...
|
|
* ...
|
|
*
|
|
* @return Matrix as String
|
|
* TODO: Work formatting for different digit sizes
|
|
*/
|
|
public String toString() {
|
|
String str = "";
|
|
|
|
for(int i = 0; i < this.data.length; i++) {
|
|
str += "[ ";
|
|
|
|
for(int j = 0; j < this.data[0].length; j++) {
|
|
str += data[i][j];
|
|
str += " ";
|
|
}
|
|
|
|
str += "]";
|
|
str += "\n";
|
|
}
|
|
|
|
return str;
|
|
}
|
|
|
|
}
|