Created ModMatrix class

This commit is contained in:
2022-02-09 22:25:17 +00:00
parent 2b1a951ab9
commit b8bf7d1180

View 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);
}
}