mirror of
https://bitbucket.org/Mattrixwv/matrix.git
synced 2025-12-07 07:23:58 -05:00
Created BigIntegerMatrix
This commit is contained in:
783
src/main/java/com/mattrixwv/matrix/BigIntegerMatrix.java
Normal file
783
src/main/java/com/mattrixwv/matrix/BigIntegerMatrix.java
Normal file
@@ -0,0 +1,783 @@
|
||||
//Matrix/src/main/java/com/mattrixwv/BigIntegerMatrix.java
|
||||
//Mattrixwv
|
||||
// Created: 02-10-22
|
||||
//Modified: 02-10-22
|
||||
package com.mattrixwv.matrix;
|
||||
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import com.mattrixwv.matrix.exceptions.InvalidCoordinatesException;
|
||||
import com.mattrixwv.matrix.exceptions.InvalidGeometryException;
|
||||
import com.mattrixwv.matrix.exceptions.InvalidRowSizeException;
|
||||
import com.mattrixwv.matrix.exceptions.InvalidScalarException;
|
||||
|
||||
|
||||
public class BigIntegerMatrix{
|
||||
protected BigInteger[][] grid;
|
||||
|
||||
//Helper functions
|
||||
protected void setGrid(BigInteger[][] grid){
|
||||
if(grid.length == 0){
|
||||
this.grid = new BigInteger[0][0];
|
||||
}
|
||||
else if(grid[0].length == 0){
|
||||
this.grid = new BigInteger[grid.length][0];
|
||||
}
|
||||
else{
|
||||
//Make sure all rows are the same length
|
||||
int length = grid[0].length;
|
||||
for(int cnt = 1;cnt < grid.length;++cnt){
|
||||
if(grid[cnt].length != length){
|
||||
throw new InvalidRowSizeException("All rows in a matrix must be the same size");
|
||||
}
|
||||
}
|
||||
|
||||
//Copy every element over to a new grid
|
||||
BigInteger[][] newGrid = new BigInteger[grid.length][grid[0].length];
|
||||
for(int rowCnt = 0;rowCnt < grid.length;++rowCnt){
|
||||
for(int colCnt = 0;colCnt < grid[0].length;++colCnt){
|
||||
newGrid[rowCnt][colCnt] = grid[rowCnt][colCnt];
|
||||
}
|
||||
}
|
||||
|
||||
//Save the new grid
|
||||
this.grid = newGrid;
|
||||
}
|
||||
}
|
||||
protected BigInteger[][] copyGrid(){
|
||||
//Allocate memory for the new grid
|
||||
BigInteger[][] newGrid = new BigInteger[grid.length][grid[0].length];
|
||||
|
||||
//Copy every element from the current grid to the new one
|
||||
for(int row = 0;row < grid.length;++row){
|
||||
for(int col = 0;col < grid[0].length;++col){
|
||||
newGrid[row][col] = grid[row][col];
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new grid
|
||||
return newGrid;
|
||||
}
|
||||
protected boolean isSquare(){
|
||||
if(getNumRows() == 0){
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
return getNumRows() == getNumCols();
|
||||
}
|
||||
}
|
||||
//Returns a matrix with the supplied row and column removed
|
||||
protected BigIntegerMatrix laplaceExpansionHelper(int row, int col){
|
||||
//Make sure the matrix is square
|
||||
if(!isSquare()){
|
||||
throw new InvalidGeometryException("A matrix must be square for you to perform Laplace Expansion");
|
||||
}
|
||||
//Make sure the matrix is large enough to have this operation performed
|
||||
if((getNumRows() <= 1) || (getNumCols() <= 1)){
|
||||
throw new InvalidGeometryException("A matrix must be at least 2x2 for you to perform Laplace Expansion: " + getNumRows() + "x" + getNumCols());
|
||||
}
|
||||
//Make sure the row is valid
|
||||
if((row < 0) || (row >= getNumRows())){
|
||||
throw new InvalidCoordinatesException("An invalid row number was supplied: " + row + ". The matrix contains " + getNumRows() + " rows");
|
||||
}
|
||||
//Make sure the col is valid
|
||||
if((col < 0) || (col >= getNumCols())){
|
||||
throw new InvalidCoordinatesException("An invalid column number was supplied: " + col + ". The matrix contains " + getNumCols() + " columns");
|
||||
}
|
||||
|
||||
|
||||
//Create a new matrix that is one row and column smaller than the existing row
|
||||
BigInteger[][] newGrid = new BigInteger[getNumRows() - 1][getNumCols() - 1];
|
||||
//Traverse the matrix and set the values in the new matrix, skipping elements in the given row and col
|
||||
for(int workingRow = 0, newRow = 0;workingRow < getNumRows();++workingRow){
|
||||
//Skip the row we are expanding
|
||||
if(workingRow == row){
|
||||
continue;
|
||||
}
|
||||
for(int workingCol = 0, newCol = 0;workingCol < getNumCols();++workingCol){
|
||||
//Skip the column we are expanding
|
||||
if(workingCol == col){
|
||||
continue;
|
||||
}
|
||||
newGrid[newRow][newCol] = grid[workingRow][workingCol];
|
||||
++newCol;
|
||||
}
|
||||
++newRow;
|
||||
}
|
||||
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
|
||||
//Constructors
|
||||
public BigIntegerMatrix(){
|
||||
grid = new BigInteger[0][0];
|
||||
}
|
||||
public BigIntegerMatrix(BigInteger[][] grid){
|
||||
setGrid(grid);
|
||||
}
|
||||
public BigIntegerMatrix(BigIntegerMatrix matrix){
|
||||
setGrid(matrix.grid);
|
||||
}
|
||||
public BigIntegerMatrix(int rows, int cols, BigInteger fill){
|
||||
if(rows <= 0){
|
||||
throw new InvalidGeometryException("A filled matrix must have at least 1 row");
|
||||
}
|
||||
else if(cols <= 0){
|
||||
throw new InvalidGeometryException("A filled matrix must have at least 1 column");
|
||||
}
|
||||
else{
|
||||
grid = new BigInteger[rows][cols];
|
||||
for(int row = 0;row < rows;++row){
|
||||
for(int col = 0;col < cols;++col){
|
||||
grid[row][col] = fill;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Gets
|
||||
public BigInteger get(int row, int col){
|
||||
//Make sure the row and column are valid
|
||||
if(row >= grid.length){
|
||||
throw new InvalidCoordinatesException("Row cannot be greater than the number of rows");
|
||||
}
|
||||
else if(col >= grid[0].length){
|
||||
throw new InvalidCoordinatesException("Column cannot be greater than the number of columns");
|
||||
}
|
||||
|
||||
//Return the location in the grid
|
||||
return grid[row][col];
|
||||
}
|
||||
public BigIntegerMatrix getRow(int row){
|
||||
//Make sure the row number is valid
|
||||
if((row < 0) || (row >= grid.length)){
|
||||
throw new InvalidCoordinatesException("The row number " + row + " is not valid");
|
||||
}
|
||||
|
||||
//Generate a copy of the row
|
||||
BigInteger[][] newRow = new BigInteger[1][grid[row].length];
|
||||
for(int col = 0;col < grid[row].length;++col){
|
||||
newRow[0][col] = grid[row][col];
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newRow);
|
||||
}
|
||||
public int getNumRows(){
|
||||
if(grid == null){
|
||||
return 0;
|
||||
}
|
||||
else{
|
||||
return grid.length;
|
||||
}
|
||||
}
|
||||
public BigIntegerMatrix getCol(int col){
|
||||
//Make sure the column number is valid
|
||||
if((col < 0) || (grid.length == 0) || (col > grid[0].length)){
|
||||
throw new InvalidCoordinatesException("The column number " + col + " is not valid");
|
||||
}
|
||||
|
||||
//Generate a copy of the col
|
||||
BigInteger[][] newColumn = new BigInteger[grid.length][1];
|
||||
for(int row = 0;row < grid.length;++row){
|
||||
newColumn[row][0] = grid[row][col];
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newColumn);
|
||||
}
|
||||
public int getNumCols(){
|
||||
if(grid.length > 0){
|
||||
return grid[0].length;
|
||||
}
|
||||
else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
//Sets
|
||||
public void set(int row, int col, BigInteger value){
|
||||
//Make sure the row number is valid
|
||||
if((row < 0) || (row >= grid.length)){
|
||||
throw new InvalidCoordinatesException("Invalid row number " + row);
|
||||
}
|
||||
//Make sure the column number is valid
|
||||
if((col < 0) || (col >= getNumCols())){
|
||||
throw new InvalidCoordinatesException("Invalid column number " + col);
|
||||
}
|
||||
|
||||
//Save the element
|
||||
grid[row][col] = value;
|
||||
}
|
||||
public void setRow(int row, BigInteger[] elements){
|
||||
//Make sure the row number is valid
|
||||
if((row < 0) || (row >= grid.length)){
|
||||
throw new InvalidCoordinatesException("Invalid row number " + row);
|
||||
}
|
||||
//Make sure the number of elements is valid
|
||||
if(elements.length != getNumCols()){
|
||||
throw new InvalidGeometryException("Invalid number of elements " + elements.length + " must be " + getNumCols());
|
||||
}
|
||||
|
||||
//Save the elements
|
||||
for(int col = 0;col < elements.length;++col){
|
||||
grid[row][col] = elements[col];
|
||||
}
|
||||
}
|
||||
public void setRow(int row, BigIntegerMatrix matrix){
|
||||
//Make sure the matrix has a single row
|
||||
if(matrix.getNumRows() != 1){
|
||||
throw new InvalidGeometryException("Setting a row by Matrix requires the matrix contain a single row");
|
||||
}
|
||||
|
||||
//Set the row
|
||||
setRow(row, matrix.grid[0]);
|
||||
}
|
||||
public void setCol(int col, BigInteger[] elements){
|
||||
//Make sure the column number is valid
|
||||
if((col < 0) || (col >= getNumCols())){
|
||||
throw new InvalidCoordinatesException("Invalid column number " + col);
|
||||
}
|
||||
//Make sure the number of elements is valid
|
||||
if(elements.length != grid.length){
|
||||
throw new InvalidCoordinatesException("Invalid number of elements " + elements.length + " must be " + grid.length);
|
||||
}
|
||||
|
||||
//Save the elements
|
||||
for(int row = 0;row < elements.length;++row){
|
||||
grid[row][col] = elements[row];
|
||||
}
|
||||
}
|
||||
public void setCol(int col, BigIntegerMatrix matrix){
|
||||
//Make sure the matrix has a single column
|
||||
if(matrix.getNumCols() != 1){
|
||||
throw new InvalidGeometryException("Setting a column by Matrix requires the matrix contain a single column");
|
||||
}
|
||||
|
||||
//Set the column
|
||||
setCol(col, matrix.getCol(0));
|
||||
}
|
||||
//Adds
|
||||
public void addRow(BigInteger[] elements){
|
||||
//Make sure the number of columns is valid
|
||||
if((grid.length == 0) || (getNumCols() == elements.length)){
|
||||
BigInteger[][] newGrid = new BigInteger[grid.length + 1][elements.length];
|
||||
//Copy all existing data into the new grid
|
||||
for(int row = 0;row < grid.length;++row){
|
||||
newGrid[row] = grid[row];
|
||||
}
|
||||
grid = newGrid;
|
||||
}
|
||||
else{
|
||||
throw new InvalidGeometryException("Invalid number of elements " + elements.length + " must be " + getNumCols());
|
||||
}
|
||||
|
||||
//Add all elements to the grid
|
||||
for(int col = 0;col < elements.length;++col){
|
||||
grid[grid.length - 1][col] = elements[col];
|
||||
}
|
||||
}
|
||||
public void addRow(BigIntegerMatrix matrix){
|
||||
//Make sure the matrix has a single row
|
||||
if(matrix.getNumRows() != 1){
|
||||
throw new InvalidGeometryException("Adding a row by Matrix requires the matrix contain a single row");
|
||||
}
|
||||
|
||||
//Add the row
|
||||
addRow(matrix.grid[0]);
|
||||
}
|
||||
public void addCol(BigInteger[] elements){
|
||||
//Make sure the number of rows is valid
|
||||
if(grid.length == 0){
|
||||
grid = new BigInteger[1][elements.length];
|
||||
}
|
||||
else if(grid.length == elements.length){
|
||||
//Copy all existing data into the new grid
|
||||
for(int row = 0;row < grid.length;++row){
|
||||
BigInteger[] workingRow = new BigInteger[grid[row].length + 1];
|
||||
for(int workingCol = 0;workingCol < grid[row].length;++workingCol){
|
||||
workingRow[workingCol] = grid[row][workingCol];
|
||||
}
|
||||
grid[row] = workingRow;
|
||||
}
|
||||
}
|
||||
else{
|
||||
throw new InvalidGeometryException("Invalid number of elements " + elements.length + " must be " + getNumCols());
|
||||
}
|
||||
|
||||
//Add all elements to the grid
|
||||
for(int row = 0;row < elements.length;++row){
|
||||
grid[row][grid[row].length - 1] = elements[row];
|
||||
}
|
||||
}
|
||||
public void addCol(BigIntegerMatrix matrix){
|
||||
//Make sure the matrix has a single column
|
||||
if(matrix.getNumCols() != 1){
|
||||
throw new InvalidGeometryException("Adding a column by Matrix requires the matrix contain a single column");
|
||||
}
|
||||
|
||||
//Add the column
|
||||
addCol(matrix.getCol(0));
|
||||
}
|
||||
public BigIntegerMatrix appendRight(BigIntegerMatrix rightSide){
|
||||
//Make sure the matrices have the same number of rows
|
||||
if(getNumRows() != rightSide.getNumRows()){
|
||||
throw new InvalidGeometryException("Invalid number of rows. " + rightSide.getNumRows() + " must be " + getNumRows());
|
||||
}
|
||||
|
||||
//Traverse both matrices and set their values in the new matrix
|
||||
BigInteger[][] newGrid = new BigInteger[getNumRows()][getNumCols() + rightSide.getNumCols()];
|
||||
for(int row = 0;row < getNumRows();++row){
|
||||
//Set all elements from the current grid's row
|
||||
for(int col = 0;col < getNumCols();++col){
|
||||
newGrid[row][col] = grid[row][col];
|
||||
}
|
||||
//Set all elements from the right side grid's row
|
||||
for(int col = 0;col < rightSide.getNumCols();++col){
|
||||
newGrid[row][getNumCols() + col] = rightSide.grid[row][col];
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
public BigIntegerMatrix appendBottom(BigIntegerMatrix rightSide){
|
||||
//Make sure the matrices have the same number of columns
|
||||
if(getNumCols() != rightSide.getNumCols()){
|
||||
throw new InvalidGeometryException("Invalid number of columns. " + rightSide.getNumCols() + " must be " + getNumCols());
|
||||
}
|
||||
|
||||
//Traverse both matrices and set their values in the new matrix
|
||||
BigInteger[][] newGrid = new BigInteger[getNumRows() + rightSide.getNumRows()][getNumCols()];
|
||||
for(int col = 0;col < getNumCols();++col){
|
||||
//Set all elements from the current grid's column
|
||||
for(int row = 0;row < getNumRows();++row){
|
||||
newGrid[row][col] = grid[row][col];
|
||||
}
|
||||
//Set all elements from the right side grid's column
|
||||
for(int row = 0;row < rightSide.getNumRows();++row){
|
||||
newGrid[getNumRows() + row][col] = rightSide.grid[row][col];
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
|
||||
//Simple operations
|
||||
public static BigIntegerMatrix generateIdentity(int size){
|
||||
//Make sure the size is valid
|
||||
if(size > 0){
|
||||
//Create a grid with the correct size
|
||||
BigInteger[][] newGrid = new BigInteger[size][size];
|
||||
|
||||
//Go through every element and make sure it is set correctly
|
||||
for(int row = 0;row < size;++row){
|
||||
for(int col = 0;col < size;++col){
|
||||
if(col == row){
|
||||
newGrid[row][col] = BigInteger.ONE;
|
||||
}
|
||||
else{
|
||||
newGrid[row][col] = BigInteger.ZERO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
else{
|
||||
throw new InvalidGeometryException("An identity matrix must have a size > 0");
|
||||
}
|
||||
}
|
||||
public BigIntegerMatrix add(BigIntegerMatrix rightSide){
|
||||
//Make sure the matrices have compatable geometry
|
||||
if((getNumRows() != rightSide.getNumRows()) || (getNumCols() != rightSide.getNumCols())){
|
||||
throw new InvalidGeometryException("Both matrices must have the same number of rows and columns: " + getNumRows() + "x" + getNumCols() + " + " + rightSide.getNumRows() + "x" + rightSide.getNumCols());
|
||||
}
|
||||
|
||||
//Create a new grid with the same elements as the current grid
|
||||
BigInteger[][] newGrid = copyGrid();
|
||||
|
||||
//Add each element in the righ tmatrix to the corresponding element in the left matrix
|
||||
for(int row = 0;row < newGrid.length;++row){
|
||||
for(int col = 0;col < newGrid[0].length;++col){
|
||||
newGrid[row][col] = newGrid[row][col].add(rightSide.grid[row][col]);
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
public BigIntegerMatrix add(BigInteger scalar){
|
||||
//Create a new grid with the same elements as the current grid
|
||||
BigInteger[][] newGrid = copyGrid();
|
||||
|
||||
//Add the scalar to each element in the grid
|
||||
for(int row = 0;row < newGrid.length;++row){
|
||||
for(int col = 0;col < newGrid[0].length;++col){
|
||||
newGrid[row][col] = newGrid[row][col].add(scalar);
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
public BigIntegerMatrix subtract(BigIntegerMatrix rightSide){
|
||||
//Make sure the matrices have compatable geometry
|
||||
if((getNumRows() != rightSide.getNumRows()) || (getNumCols() != rightSide.getNumCols())){
|
||||
throw new InvalidGeometryException("Both matrices must have the same number of rows and columsn: " + getNumRows() + "x" + getNumCols() + " + " + rightSide.getNumRows() + "x" + rightSide.getNumCols());
|
||||
}
|
||||
|
||||
//Create a new grid with the same elements as the current gird
|
||||
BigInteger[][] newGrid = copyGrid();
|
||||
|
||||
//Subtract each element in the righ tmatrix from the corresponding element in the left matrix
|
||||
for(int row = 0;row < newGrid.length;++row){
|
||||
for(int col = 0;col < newGrid[0].length;++col){
|
||||
newGrid[row][col] = newGrid[row][col].subtract(grid[row][col]);
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
public BigIntegerMatrix subtract(BigInteger scalar){
|
||||
//Create a new grid with the same elements as the current grid
|
||||
BigInteger[][] newGrid = copyGrid();
|
||||
|
||||
//Subtract the scalar from each element in the grid
|
||||
for(int row = 0;row < newGrid.length;++row){
|
||||
for(int col = 0;col < newGrid[0].length;++col){
|
||||
newGrid[row][col] = newGrid[row][col].subtract(scalar);
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
public BigIntegerMatrix multiply(BigIntegerMatrix rightSide){
|
||||
//Make sure the matrices have compatable geometry
|
||||
if(getNumCols() != rightSide.getNumRows()){
|
||||
throw new InvalidGeometryException("The left matrix must have the same number of columns as the right matrix has rows: " + getNumRows() + "x" + getNumCols() + " + " + rightSide.getNumRows() + "x" + rightSide.getNumCols());
|
||||
}
|
||||
|
||||
//Create a new grid with the same elements as the current grid
|
||||
BigInteger[][] newGrid = new BigInteger[getNumRows()][rightSide.getNumCols()];
|
||||
|
||||
//Multiply each row in the left matrix with each column int he right matrix to come up with the current element
|
||||
for(int leftRow = 0;leftRow < grid.length;++leftRow){
|
||||
for(int rightCol = 0;rightCol < rightSide.getNumCols();++rightCol){
|
||||
//Get a sum of the product of each column in the current row (left) and each row in the current column (right)
|
||||
BigInteger elementProductSum = BigInteger.ZERO;
|
||||
for(int incrementCounter = 0;incrementCounter < grid.length;++incrementCounter){
|
||||
elementProductSum = elementProductSum.add(grid[leftRow][incrementCounter].multiply(rightSide.grid[incrementCounter][rightCol]));
|
||||
}
|
||||
newGrid[leftRow][rightCol] = elementProductSum;
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
public BigIntegerMatrix multiply(BigInteger scalar){
|
||||
//Create a new grid with the same elements as the current grid
|
||||
BigInteger[][] newGrid = copyGrid();
|
||||
|
||||
//Multiply every element in the grid by the scalar
|
||||
for(int row = 0;row < grid.length;++row){
|
||||
for(int col = 0;col < grid[0].length;++col){
|
||||
newGrid[row][col] = newGrid[row][col].multiply(scalar);
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
public BigIntegerMatrix 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 BigIntegerMatrix(getNumRows(), getNumCols(), BigInteger.ONE);
|
||||
}
|
||||
|
||||
//Create a new matrix for the product
|
||||
BigIntegerMatrix 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;
|
||||
}
|
||||
public BigInteger dotProduct(BigIntegerMatrix rightSide){
|
||||
//Make sure the matrices have compatable geometry
|
||||
if(getNumCols() != rightSide.getNumRows()){
|
||||
throw new InvalidGeometryException("The left matrix must have the same number of columns as the right matrix has rows: " + getNumRows() + "x" + getNumCols() + " + " + rightSide.getNumRows() + "x" + rightSide.getNumCols());
|
||||
}
|
||||
|
||||
//Multiply each row in the left matrix with each column in the right matrix to come up with the current element
|
||||
//?Would be simpler, but slower, to get the product matrix to come up with the current element
|
||||
BigInteger sum = BigInteger.ZERO;
|
||||
for(int leftRow = 0;leftRow < grid.length;++leftRow){
|
||||
for(int rightCol = 0;rightCol < rightSide.getNumCols();++rightCol){
|
||||
for(int incrementCounter = 0;incrementCounter < grid.length;++incrementCounter){
|
||||
sum = sum.add(grid[leftRow][incrementCounter].multiply(rightSide.grid[incrementCounter][rightCol]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Return the sum
|
||||
return sum;
|
||||
}
|
||||
public BigIntegerMatrix hadamardProduct(BigIntegerMatrix rightSide){
|
||||
//Make sure the matrices have compatable geometry
|
||||
if((getNumRows() != rightSide.getNumRows()) || (getNumCols() != rightSide.getNumCols())){
|
||||
throw new InvalidGeometryException("Both matrices must have the same number of rows and columns: " + getNumRows() + "x" + getNumCols() + " + " + rightSide.getNumRows() + "x" + rightSide.getNumCols());
|
||||
}
|
||||
|
||||
//Create a new grid with the same element as the current grid
|
||||
BigInteger[][] newGrid = copyGrid();
|
||||
|
||||
//Multiply each element in the right matrix to the corresponding element in the left matrix
|
||||
for(int row = 0;row < newGrid.length;++row){
|
||||
for(int col = 0;col < newGrid[0].length;++col){
|
||||
newGrid[row][col] = newGrid[row][col].multiply(rightSide.grid[row][col]);
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
|
||||
//Complex operations
|
||||
public BigIntegerMatrix transpose(){
|
||||
//Create a new grid
|
||||
BigInteger[][] newGrid = new BigInteger[getNumCols()][getNumRows()];
|
||||
|
||||
//Traverse every element in the existing grid and add each column to the new grid as a row
|
||||
for(int col = 0;col < getNumCols();++col){
|
||||
for(int row = 0;row < getNumRows();++row){
|
||||
newGrid[col][row] = grid[row][col];
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
public BigInteger det(){
|
||||
return determinant();
|
||||
}
|
||||
public BigInteger determinant(){
|
||||
//Make sure the matrix is square
|
||||
if(!isSquare()){
|
||||
throw new InvalidGeometryException("A matrix must be square for it to have a determinant");
|
||||
}
|
||||
//?Don't have to worry about a matrix existing. isSquare takes care of 0x0 matrix
|
||||
|
||||
//Determine the formula do use for the determinant
|
||||
BigInteger det = BigInteger.ZERO;
|
||||
switch(getNumRows()){
|
||||
//If the matrix is 1x1 return the number
|
||||
case 1 : det = grid[0][0]; break;
|
||||
//If the matrix is 2x2 use the formula
|
||||
case 2 : {
|
||||
det = (grid[0][0].multiply(grid[1][1])).subtract(grid[0][1].multiply(grid[1][0]));
|
||||
}
|
||||
break;
|
||||
//If the matrix is 3x3 use the formula
|
||||
case 3 : {
|
||||
det = grid[0][0].multiply(grid[1][1]).multiply(grid[2][2]).add(grid[0][1].multiply(grid[1][2]).multiply(grid[2][0])).add(grid[0][2].multiply(grid[1][0]).multiply(grid[2][1])).subtract
|
||||
(grid[2][0].multiply(grid[1][1]).multiply(grid[0][2])).subtract(grid[2][1].multiply(grid[1][2]).multiply(grid[0][0])).subtract(grid[2][2].multiply(grid[1][0]).multiply(grid[0][1]));
|
||||
}
|
||||
break;
|
||||
//If the matrix is larger break it down and try again
|
||||
default : {
|
||||
//Find the row/column with the largest number of 0's
|
||||
int zerosLocation = 0;
|
||||
int maxNumZeros = 0;
|
||||
boolean zerosRow = true;
|
||||
//Check the rows
|
||||
for(int row = 0;row < getNumRows();++row){
|
||||
int numZeros = 0;
|
||||
for(int col = 0;col < getNumCols();++col){
|
||||
if(grid[row][col].equals(BigInteger.ZERO)){
|
||||
++numZeros;
|
||||
}
|
||||
}
|
||||
if(numZeros > maxNumZeros){
|
||||
maxNumZeros = numZeros;
|
||||
zerosLocation = row;
|
||||
zerosRow = true;
|
||||
}
|
||||
}
|
||||
//Check the columns
|
||||
for(int col = 0;col < getNumCols();++col){
|
||||
int numZeros = 0;
|
||||
for(int row = 0;row < getNumRows();++row){
|
||||
if(grid[row][col].equals(BigInteger.ZERO)){
|
||||
++numZeros;
|
||||
}
|
||||
}
|
||||
if(numZeros > maxNumZeros){
|
||||
maxNumZeros = numZeros;
|
||||
zerosLocation = col;
|
||||
zerosRow = false;
|
||||
}
|
||||
}
|
||||
|
||||
//If the largest number of zeros were found in a row
|
||||
if(zerosRow){
|
||||
//Set a variable to make sure the appropriate + or - is applied to the scalar
|
||||
BigInteger multiplier = BigInteger.ONE;
|
||||
if((zerosLocation % 2) == 1){
|
||||
multiplier = BigInteger.ONE.negate();
|
||||
}
|
||||
//Go through every column in the optimal row using the formula
|
||||
for(int col = 0;col < getNumCols();++col){
|
||||
if(!grid[zerosLocation][col].equals(BigInteger.ZERO)){
|
||||
det = det.add(multiplier.multiply(grid[zerosLocation][col]).multiply(laplaceExpansionHelper(zerosLocation, col).determinant()));
|
||||
}
|
||||
multiplier = multiplier.negate();
|
||||
}
|
||||
}
|
||||
//If the largest number of zeros were found in a column
|
||||
else{
|
||||
//Set a variable to make sure the appropriate + or - is applied to the scalar
|
||||
BigInteger multiplier = BigInteger.ONE;
|
||||
if((zerosLocation % 2) == 1){
|
||||
multiplier = BigInteger.ONE.negate();
|
||||
}
|
||||
//Go through every row in the coptimal column using the formula
|
||||
for(int row = 0;row < getNumRows();++row){
|
||||
if(!grid[row][zerosLocation].equals(BigInteger.ZERO)){
|
||||
det = det.add(multiplier.multiply(grid[row][zerosLocation]).multiply(laplaceExpansionHelper(row, zerosLocation).determinant()));
|
||||
}
|
||||
multiplier = multiplier.negate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Return the determinant
|
||||
return det;
|
||||
}
|
||||
public BigIntegerMatrix cof(){
|
||||
return cofactor();
|
||||
}
|
||||
public BigIntegerMatrix 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
|
||||
BigInteger[][] newGrid = new BigInteger[getNumRows()][getNumCols()];
|
||||
//If the grid is 1x1 return the grid
|
||||
if(getNumRows() == 1){
|
||||
newGrid[0][0] = BigInteger.ONE;
|
||||
}
|
||||
//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] = laplaceExpansionHelper(row, col).determinant().multiply(BigInteger.valueOf(multiplier));
|
||||
multiplier = -multiplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return new BigIntegerMatrix(newGrid);
|
||||
}
|
||||
public BigIntegerMatrix adj(){
|
||||
return adjoint();
|
||||
}
|
||||
public BigIntegerMatrix adjoint(){
|
||||
return cofactor().transpose();
|
||||
}
|
||||
public BigIntegerMatrix 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
|
||||
BigInteger determinant = determinant();
|
||||
if(determinant.equals(BigInteger.ZERO)){
|
||||
throw new InvalidScalarException("The determinant cannot be 0");
|
||||
}
|
||||
|
||||
//Return the new matrix
|
||||
return adjoint().multiply(BigInteger.ONE.divide(determinant));
|
||||
}
|
||||
|
||||
//Object funtions
|
||||
@Override
|
||||
public boolean equals(Object rightSide){
|
||||
if(rightSide.getClass().equals(this.getClass())){
|
||||
BigIntegerMatrix rightMatrix = (BigIntegerMatrix)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].equals(rightMatrix.grid[row][col])){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//If false hasn't been returned yet then they are equal
|
||||
return true;
|
||||
}
|
||||
else if(rightSide.getClass().equals(BigInteger[][].class)){
|
||||
BigInteger[][] rightMatrix = (BigInteger[][])rightSide;
|
||||
|
||||
return equals(new BigIntegerMatrix(rightMatrix));
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public int hashCode(){
|
||||
return grid.hashCode();
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
StringJoiner matrix = new StringJoiner("\n");
|
||||
for(int rowCnt = 0;rowCnt < getNumRows();++rowCnt){
|
||||
StringJoiner row = new StringJoiner(",", "[", "]");
|
||||
|
||||
for(int colCnt = 0;colCnt < getNumCols();++colCnt){
|
||||
row.add(grid[rowCnt][colCnt].toString());
|
||||
}
|
||||
|
||||
matrix.add(row.toString());
|
||||
}
|
||||
return matrix.toString();
|
||||
}
|
||||
@Override
|
||||
public BigIntegerMatrix clone(){
|
||||
return new BigIntegerMatrix(grid);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user