From 8cb22496f5af8f020df85e1d9448812601889079 Mon Sep 17 00:00:00 2001 From: Matthew Ellison Date: Mon, 7 Feb 2022 22:31:09 +0000 Subject: [PATCH] Created DoubleMatrix --- .../com/mattrixwv/matrix/DoubleMatrix.java | 803 ++++++++++++++++++ 1 file changed, 803 insertions(+) create mode 100644 src/main/java/com/mattrixwv/matrix/DoubleMatrix.java diff --git a/src/main/java/com/mattrixwv/matrix/DoubleMatrix.java b/src/main/java/com/mattrixwv/matrix/DoubleMatrix.java new file mode 100644 index 0000000..bc8d4ee --- /dev/null +++ b/src/main/java/com/mattrixwv/matrix/DoubleMatrix.java @@ -0,0 +1,803 @@ +//Matrix/src/main/java/com/mattrixwv/matrix/DoubleMatrix.java +//Mattrixwv +// Created: 02-07-22 +//Modified: 02-07-22 +package com.mattrixwv.matrix; + + +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 DoubleMatrix{ + protected double[][] grid; + protected double delta; + + //Helper functions + protected void setGrid(double[][] grid){ + if(grid.length == 0){ + grid = new double[0][0]; + } + else if(grid[0].length == 0){ + grid = new double[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 + double[][] newGrid = new double[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 double[][] copyGrid(){ + //Allocate memory for the new grid + double[][] newGrid = new double[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 DoubleMatrix 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 + double[][] newGrid = new double[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 DoubleMatrix(newGrid); + } + + //Constructors + public DoubleMatrix(){ + grid = new double[0][0]; + delta = 0.0; + } + public DoubleMatrix(double[][] grid){ + setGrid(grid); + delta = 0.0; + } + public DoubleMatrix(DoubleMatrix matrix){ + setGrid(matrix.grid); + delta = 0.0; + } + public DoubleMatrix(int rows, int cols, double 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 double[rows][cols]; + for(int row = 0;row < rows;++row){ + for(int col = 0;col < cols;++col){ + grid[row][col] = fill; + } + } + delta = 0.0; + } + } + + //Gets + public double 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 DoubleMatrix 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 + double[][] newRow = new double[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 DoubleMatrix(newRow); + } + public int getNumRows(){ + return grid.length; + } + public DoubleMatrix 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 + double[][] newColumn = new double[grid.length][1]; + for(int row = 0;row < grid.length;++row){ + newColumn[row][0] = grid[row][col]; + } + + //Return the new matrix + return new DoubleMatrix(newColumn); + } + public int getNumCols(){ + if(grid.length > 0){ + return grid[0].length; + } + else{ + return 0; + } + } + //Sets + public void set(int row, int col, double 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, double[] 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, DoubleMatrix 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, double[] 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, DoubleMatrix 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(double[] elements){ + //Make sure the number of columns is valid + if((grid.length == 0) || (getNumCols() == elements.length)){ + double[][] newGrid = new double[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(DoubleMatrix 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(double[] elements){ + //Make sure the number of rows is valid + if(grid.length == 0){ + grid = new double[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){ + double[] workingRow = new double[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(DoubleMatrix 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 DoubleMatrix appendRight(DoubleMatrix 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 + double[][] newGrid = new double[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 DoubleMatrix(newGrid); + } + public DoubleMatrix appendBottom(DoubleMatrix 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 + double[][] newGrid = new double[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 DoubleMatrix(newGrid); + } + + //Simple operations + public static DoubleMatrix generateIdentity(int size){ + //Make sure the size is valid + if(size > 0){ + //Create a grid with the correct size + double[][] newGrid = new double[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] = 1; + } + else{ + newGrid[row][col] = 0; + } + } + } + + //Return the new matrix + return new DoubleMatrix(newGrid); + } + else{ + throw new InvalidGeometryException("An identity matrix must have a size > 0"); + } + } + public static DoubleMatrix generateFilled(int size, double fill){ + //Create a grid with the correct size + double[][] newGrid = new double[size][size]; + + //Set each element in the grid + for(int row = 0;row < size;++row){ + for(int col = 0;col < size;++col){ + newGrid[row][col] = fill; + } + } + + //Return the new matrix + return new DoubleMatrix(newGrid); + } + public DoubleMatrix add(DoubleMatrix 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 + double[][] 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] += rightSide.grid[row][col]; + } + } + + //Return the new matrix + return new DoubleMatrix(newGrid); + } + public DoubleMatrix add(double scalar){ + //Create a new grid with the same elements as the current grid + double[][] 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] += scalar; + } + } + + //Return the new matrix + return new DoubleMatrix(newGrid); + } + public DoubleMatrix subtract(DoubleMatrix 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 + double[][] 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] -= grid[row][col]; + } + } + + //Return the new matrix + return new DoubleMatrix(newGrid); + } + public DoubleMatrix subtract(double scalar){ + //Create a new grid with the same elements as the current grid + double[][] 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] -= scalar; + } + } + + //Return the new matrix + return new DoubleMatrix(newGrid); + } + public DoubleMatrix multiply(DoubleMatrix 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 + double[][] newGrid = new double[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) + double elementProductSum = 0; + for(int incrementCounter = 0;incrementCounter < grid.length;++incrementCounter){ + elementProductSum += grid[leftRow][incrementCounter] * rightSide.grid[incrementCounter][rightCol]; + } + newGrid[leftRow][rightCol] = elementProductSum; + } + } + + //Return the new matrix + return new DoubleMatrix(newGrid); + } + public DoubleMatrix multiply(double scalar){ + //Create a new grid with the same elements as the current grid + double[][] 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] *= scalar; + } + } + + //Return the new matrix + return new DoubleMatrix(newGrid); + } + public DoubleMatrix 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 DoubleMatrix(getNumRows(), getNumCols(), 1.0); + } + + //Create a new matrix for the product + DoubleMatrix 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 double dotProduct(DoubleMatrix 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 + double sum = 0; + 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 += grid[leftRow][incrementCounter] * rightSide.grid[incrementCounter][rightCol]; + } + } + } + + //Return the sum + return sum; + } + public DoubleMatrix hadamardProduct(DoubleMatrix 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 + double[][] 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] *= rightSide.grid[row][col]; + } + } + + //Return the new matrix + return new DoubleMatrix(newGrid); + } + + //Complex operations + public DoubleMatrix transpose(){ + //Create a new grid + double[][] newGrid = new double[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 DoubleMatrix(newGrid); + } + public double det(){ + return determinant(); + } + public double 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 + double det = 0; + 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] * grid[1][1]) - (grid[0][1] * grid[1][0]); + } + break; + //If the matrix is 3x3 use the formula + case 3 : { + det = (grid[0][0] * grid[1][1] * grid[2][2]) + (grid[0][1] * grid[1][2] * grid[2][0]) + (grid[0][2] * grid[1][0] * grid[2][1]) - + (grid[2][0] * grid[1][1] * grid[0][2]) - (grid[2][1] * grid[1][2] * grid[0][0]) - (grid[2][2] * grid[1][0] * 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] == 0){ + ++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] == 0){ + ++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 + int multiplier = 1; + if((zerosLocation % 2) == 1){ + multiplier = -1; + } + //Go through every column in the optimal row using the formula + for(int col = 0;col < getNumCols();++col){ + if(grid[zerosLocation][col] != 0){ + det += (multiplier * grid[zerosLocation][col] * laplaceExpansionHelper(zerosLocation, col).determinant()); + } + multiplier = -multiplier; + } + } + //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 + int multiplier = 1; + if((zerosLocation % 2) == 1){ + multiplier = -1; + } + //Go through every row in the coptimal column using the formula + for(int row = 0;row < getNumRows();++row){ + if(grid[row][zerosLocation] != 0){ + det += (multiplier * grid[row][zerosLocation] * laplaceExpansionHelper(row, zerosLocation).determinant()); + } + multiplier = -multiplier; + } + } + } + } + + //Return the determinant + return det; + } + public DoubleMatrix cof(){ + return cofactor(); + } + public DoubleMatrix 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 + double[][] newGrid = new double[getNumRows()][getNumCols()]; + //If the grid is 1x1 return the grid + if(getNumRows() == 1){ + newGrid[0][0] = grid[0][0]; + } + //Use the formula to find the cofactor matrix + else{ + for(int row = 0;row < getNumRows();++row){ + double multiplier = ((row % 2) == 0) ? 1.0 : -1.0; + for(int col = 0;col < getNumCols();++col){ + newGrid[row][col] = multiplier * laplaceExpansionHelper(row, col).determinant(); + multiplier = -multiplier; + } + } + } + + //Return the new matrix + return new DoubleMatrix(newGrid); + } + public DoubleMatrix adj(){ + return adjoint(); + } + public DoubleMatrix adjoint(){ + return cofactor().transpose(); + } + public DoubleMatrix 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 + double determinant = determinant(); + if(determinant == 0){ + throw new InvalidScalarException("The determinant cannot be 0"); + } + + //Return the new matrix + return adjoint().multiply(1 / determinant); + } + + //Object funtions + @Override + public boolean equals(Object rightSide){ + if(rightSide.getClass().equals(this.getClass())){ + DoubleMatrix rightMatrix = (DoubleMatrix)rightSide; + + //Make sure they have the same number of elements + if(grid.length != rightMatrix.grid.length){ + return false; + } + else if(getNumCols() != rightMatrix.getNumCols()){ + return false; + } + + //Check every element + for(int row = 0;row < grid.length;++row){ + for(int col = 0;col < grid[0].length;++col){ + if(Math.abs(grid[row][col] - rightMatrix.grid[row][col]) > delta){ + return false; + } + } + } + + //If false hasn't been returned yet then they are equal + return true; + } + else if(rightSide.getClass().equals(double[][].class)){ + double[][] rightMatrix = (double[][])rightSide; + + return equals(new DoubleMatrix(rightMatrix)); + } + else{ + return false; + } + } + public boolean equals(Object rightSide, double delta){ + setEqualsDelta(delta); + return equals(rightSide); + } + public void setEqualsDelta(double delta){ + this.delta = Math.abs(delta); + } + @Override + public int hashCode(){ + return grid.hashCode(); + } + @Override + public String toString(){ + StringJoiner matrix = new StringJoiner("\n"); + for(int rowCnt = 0;rowCnt < grid.length;++rowCnt){ + StringJoiner row = new StringJoiner(",", "[", "]"); + + for(int colCnt = 0;colCnt < grid[0].length;++colCnt){ + row.add(Double.toString(grid[rowCnt][colCnt])); + } + + matrix.add(row.toString()); + } + return matrix.toString(); + } + @Override + public DoubleMatrix clone(){ + return new DoubleMatrix(grid); + } +}