mirror of
https://bitbucket.org/Mattrixwv/matrix.git
synced 2025-12-06 15:03:58 -05:00
Created ModMatrix class
This commit is contained in:
369
src/main/java/com/mattrixwv/matrix/ModMatrix.java
Normal file
369
src/main/java/com/mattrixwv/matrix/ModMatrix.java
Normal file
@@ -0,0 +1,369 @@
|
|||||||
|
//Matrix/src/main/java/com/mattrixwv/matrix/ModMatrix.java
|
||||||
|
//Mattrixwv
|
||||||
|
// Created: 02-09-22
|
||||||
|
//Modified: 02-09-22
|
||||||
|
package com.mattrixwv.matrix;
|
||||||
|
|
||||||
|
|
||||||
|
import com.mattrixwv.matrix.exceptions.InvalidGeometryException;
|
||||||
|
import com.mattrixwv.matrix.exceptions.InvalidScalarException;
|
||||||
|
|
||||||
|
|
||||||
|
public class ModMatrix extends IntegerMatrix{
|
||||||
|
protected int mod;
|
||||||
|
|
||||||
|
//Helper functions
|
||||||
|
protected void setMod(int mod){
|
||||||
|
if(mod <= 0){
|
||||||
|
throw new InvalidScalarException("The mod must be > 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mod = mod;
|
||||||
|
}
|
||||||
|
protected int modValue(int value){
|
||||||
|
int newValue = value % mod;
|
||||||
|
|
||||||
|
if(newValue < 0){
|
||||||
|
newValue += mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
protected int[] modValues(int[] values){
|
||||||
|
int[] newValues = new int[values.length];
|
||||||
|
|
||||||
|
for(int cnt = 0;cnt < values.length;++cnt){
|
||||||
|
newValues[cnt] = modValue(values[cnt]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newValues;
|
||||||
|
}
|
||||||
|
protected void modGrid(){
|
||||||
|
for(int row = 0;row < getNumRows();++row){
|
||||||
|
for(int col = 0;col < getNumCols();++col){
|
||||||
|
grid[row][col] = modValue(grid[row][col]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void setGrid(int[][] grid){
|
||||||
|
super.setGrid(grid);
|
||||||
|
modGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Constructors
|
||||||
|
public ModMatrix(int mod){
|
||||||
|
super();
|
||||||
|
setMod(mod);
|
||||||
|
modGrid();
|
||||||
|
}
|
||||||
|
public ModMatrix(int[][] grid, int mod){
|
||||||
|
super();
|
||||||
|
setMod(mod);
|
||||||
|
setGrid(grid);
|
||||||
|
}
|
||||||
|
public ModMatrix(ModMatrix matrix){
|
||||||
|
super();
|
||||||
|
setMod(matrix.mod);
|
||||||
|
setGrid(matrix.grid);
|
||||||
|
}
|
||||||
|
public ModMatrix(IntegerMatrix matrix, int mod){
|
||||||
|
super();
|
||||||
|
setMod(mod);
|
||||||
|
setGrid(matrix.grid);
|
||||||
|
}
|
||||||
|
public ModMatrix(int rows, int cols, int fill, int mod){
|
||||||
|
super(rows, cols, fill);
|
||||||
|
setMod(mod);
|
||||||
|
modGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Gets
|
||||||
|
public int getMod(){
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix getRow(int row){
|
||||||
|
return new ModMatrix(super.getRow(row), mod);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix getCol(int col){
|
||||||
|
return new ModMatrix(super.getCol(col), mod);
|
||||||
|
}
|
||||||
|
//Sets
|
||||||
|
@Override
|
||||||
|
public void set(int row, int col, int value){
|
||||||
|
super.set(row, col, modValue(value));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setRow(int row, int[] elements){
|
||||||
|
super.setRow(row, modValues(elements));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setRow(int row, IntegerMatrix matrix){
|
||||||
|
setRow(row, new ModMatrix(matrix, Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
public void setRow(int row, ModMatrix matrix){
|
||||||
|
super.setRow(row, matrix);
|
||||||
|
modGrid();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setCol(int col, int[] elements){
|
||||||
|
super.setCol(col, elements);
|
||||||
|
modGrid();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setCol(int col, IntegerMatrix matrix){
|
||||||
|
setCol(col, new ModMatrix(matrix, Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
public void setCol(int col, ModMatrix matrix){
|
||||||
|
super.setCol(col, matrix);
|
||||||
|
modGrid();
|
||||||
|
}
|
||||||
|
//Adds
|
||||||
|
@Override
|
||||||
|
public void addRow(int[] elements){
|
||||||
|
super.addRow(modValues(elements));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void addRow(IntegerMatrix matrix){
|
||||||
|
addRow(new ModMatrix(matrix, Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
public void addRow(ModMatrix matrix){
|
||||||
|
super.addRow(matrix);
|
||||||
|
modGrid();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void addCol(int[] elements){
|
||||||
|
super.addCol(modValues(elements));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void addCol(IntegerMatrix matrix){
|
||||||
|
addCol(new ModMatrix(matrix, Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
public void addCol(ModMatrix matrix){
|
||||||
|
super.addCol(matrix);
|
||||||
|
modGrid();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix appendRight(IntegerMatrix rightSide){
|
||||||
|
return appendRight(new ModMatrix(rightSide, Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
public ModMatrix appendRight(ModMatrix rightSide){
|
||||||
|
return new ModMatrix(super.appendRight(rightSide), mod);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix appendBottom(IntegerMatrix rightSide){
|
||||||
|
return appendBottom(new ModMatrix(rightSide, Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
public ModMatrix appendBottom(ModMatrix rightSide){
|
||||||
|
return new ModMatrix(super.appendBottom(rightSide), mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Simple operations
|
||||||
|
public static ModMatrix generateIdentity(int size){
|
||||||
|
return generateIdentity(size, Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
public static ModMatrix generateIdentity(int size, int mod){
|
||||||
|
return new ModMatrix(IntegerMatrix.generateIdentity(size), mod);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix add(IntegerMatrix rightSide){
|
||||||
|
return add(new ModMatrix(rightSide, Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
public ModMatrix add(ModMatrix rightSide){
|
||||||
|
return new ModMatrix(super.add(rightSide), mod);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix add(int scalar){
|
||||||
|
return new ModMatrix(super.add(scalar), mod);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix subtract(IntegerMatrix rightSide){
|
||||||
|
return subtract(new ModMatrix(rightSide, Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
public ModMatrix subtract(ModMatrix rightSide){
|
||||||
|
return new ModMatrix(super.subtract(rightSide), mod);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix subtract(int scalar){
|
||||||
|
return new ModMatrix(super.subtract(scalar), mod);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix multiply(IntegerMatrix matrix){
|
||||||
|
return multiply(new ModMatrix(matrix, Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
public ModMatrix multiply(ModMatrix matrix){
|
||||||
|
return new ModMatrix(super.multiply(matrix), mod);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix multiply(int scalar){
|
||||||
|
return new ModMatrix(super.multiply(scalar), mod);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix pow(int power){
|
||||||
|
//Make sure the matrix is square so it can be multiplied
|
||||||
|
if(!isSquare()){
|
||||||
|
throw new InvalidGeometryException("The matrix must be square to raise it to a power");
|
||||||
|
}
|
||||||
|
//Make sure the power is positive
|
||||||
|
if(power < 0){
|
||||||
|
throw new InvalidScalarException("The power must be >= 0");
|
||||||
|
}
|
||||||
|
else if(power == 0){
|
||||||
|
return new ModMatrix(getNumRows(), getNumCols(), 1, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create a new matrix for the product
|
||||||
|
ModMatrix newMatrix = clone();
|
||||||
|
//Multiply the current grid power times
|
||||||
|
for(int currentPower = 1;currentPower < power;++currentPower){
|
||||||
|
newMatrix = newMatrix.multiply(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Return the new grid
|
||||||
|
return newMatrix;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int dotProduct(IntegerMatrix rightSide){
|
||||||
|
return dotProduct(new ModMatrix(rightSide, Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
public int dotProduct(ModMatrix rightSide){
|
||||||
|
return super.dotProduct(rightSide);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix hadamardProduct(IntegerMatrix rightSide){
|
||||||
|
return hadamardProduct(new ModMatrix(rightSide, Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
public ModMatrix hadamardProduct(ModMatrix rightSide){
|
||||||
|
return new ModMatrix(super.hadamardProduct(rightSide), mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Complex operations
|
||||||
|
@Override
|
||||||
|
public ModMatrix transpose(){
|
||||||
|
return new ModMatrix(super.transpose(), mod);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int det(){
|
||||||
|
return determinant();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int determinant(){
|
||||||
|
return super.determinant();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix cof(){
|
||||||
|
return cofactor();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix cofactor(){
|
||||||
|
//Make sure the matrix is square
|
||||||
|
if(!isSquare()){
|
||||||
|
throw new InvalidGeometryException("A matrix must be square to find the cofactor matrix");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create a new grid
|
||||||
|
int[][] newGrid = new int[getNumRows()][getNumCols()];
|
||||||
|
//If the grid is 1x1 return the grid
|
||||||
|
if(getNumRows() == 1){
|
||||||
|
newGrid[0][0] = 1;
|
||||||
|
}
|
||||||
|
//Use the formula to find the cofactor matrix
|
||||||
|
else{
|
||||||
|
for(int row = 0;row < getNumRows();++row){
|
||||||
|
int multiplier = ((row % 2) == 0) ? 1 : -1;
|
||||||
|
for(int col = 0;col < getNumCols();++col){
|
||||||
|
newGrid[row][col] = multiplier * laplaceExpansionHelper(row, col).determinant();
|
||||||
|
multiplier = -multiplier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Return the new matrix
|
||||||
|
return new ModMatrix(newGrid, mod);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix adj(){
|
||||||
|
return adjoint();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix adjoint(){
|
||||||
|
return cofactor().transpose();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix inverse(){
|
||||||
|
//Make sure the matrix is square
|
||||||
|
if(!isSquare()){
|
||||||
|
throw new InvalidGeometryException("A matrix must be square for it to have an inverse");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Make sure the determinant is not 0
|
||||||
|
int determinant = determinant();
|
||||||
|
if(determinant == 0){
|
||||||
|
throw new InvalidScalarException("The determinant cannot be 0");
|
||||||
|
}
|
||||||
|
//Find the inverse of determinant % mod
|
||||||
|
int determinantInverse = -1;
|
||||||
|
for(int num = 1;num < mod;++num){
|
||||||
|
if(modValue(determinant * num) == 1){
|
||||||
|
determinantInverse = num;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(determinantInverse < 0){
|
||||||
|
throw new InvalidScalarException("There is no inverse for the determinant");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Find the matrix of cofactors and multiply the inverse determinant by cofactors and return
|
||||||
|
return adjoint().multiply(determinantInverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Object functions
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object rightSide){
|
||||||
|
if(rightSide.getClass().equals(this.getClass())){
|
||||||
|
ModMatrix rightMatrix = (ModMatrix)rightSide;
|
||||||
|
|
||||||
|
//Make sure they have the same number of elements
|
||||||
|
if(getNumRows() != rightMatrix.getNumRows()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(getNumCols() != rightMatrix.getNumCols()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check every element
|
||||||
|
for(int row = 0;row < getNumRows();++row){
|
||||||
|
for(int col = 0;col < getNumCols();++col){
|
||||||
|
if(grid[row][col] != rightMatrix.grid[row][col]){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If false hasn't been return yet then they are equal
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(rightSide.getClass().equals(int[][].class)){
|
||||||
|
int[][] rightMatrix = (int[][])rightSide;
|
||||||
|
|
||||||
|
return equals(new ModMatrix(rightMatrix, mod));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int hashCode(){
|
||||||
|
return grid.hashCode();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
return super.toString() + "\nmod(" + mod + ")";
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ModMatrix clone(){
|
||||||
|
return new ModMatrix(grid, mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user