org.jgrasstools.gears.utils.math.matrixes.Matrix Maven / Gradle / Ivy
The newest version!
package org.jgrasstools.gears.utils.math.matrixes;
/**
* From: Java Number Cruncher
* The Java Programmer's Guide to Numerical Computation
* by Ronald Mak
*
*
* The matrix class.
*/
public class Matrix
{
/** number of rows */ protected int nRows;
/** number of columns */ protected int nCols;
/** 2-d array of values */ protected double values[][];
//--------------//
// Constructors //
//--------------//
/**
* Default constructor.
*/
protected Matrix() {}
/**
* Constructor.
* @param rowCount the number of rows
* @param colCount the number of columns
*/
public Matrix(int rowCount, int colCount)
{
nRows = (rowCount > 0) ? rowCount : 1;
nCols = (colCount > 0) ? colCount : 1;
values = new double[nRows][nCols];
}
/**
* Constructor.
* @param values the 2-d array of values
*/
public Matrix(double values[][]) { set(values); }
//---------//
// Getters //
//---------//
/**
* Get the row count.
* @return the row count
*/
public int rowCount() { return nRows; }
/**
* Get the column count.
* @return the column count
*/
public int columnCount() { return nCols; }
/**
* Get the value of element [r,c] in the matrix.
* @param r the row index
* @param c the column index
* @return the value
* @throws numbercruncher.MatrixException for an invalid index
*/
public double at(int r, int c) throws MatrixException
{
if ((r < 0) || (r >= nRows) || (c < 0) || (c >= nCols)) {
throw new MatrixException(MatrixException.INVALID_INDEX);
}
return values[r][c];
}
/**
* Get a row of this matrix.
* @param r the row index
* @return the row as a row vector
* @throws numbercruncher.MatrixException for an invalid index
*/
public RowVector getRow(int r) throws MatrixException
{
if ((r < 0) || (r >= nRows)) {
throw new MatrixException(MatrixException.INVALID_INDEX);
}
RowVector rv = new RowVector(nCols);
for (int c = 0; c < nCols; ++c) {
rv.values[0][c] = this.values[r][c];
}
return rv;
}
/**
* Get a column of this matrix.
* @param c the column index
* @return the column as a column vector
* @throws numbercruncher.MatrixException for an invalid index
*/
public ColumnVector getColumn(int c) throws MatrixException
{
if ((c < 0) || (c >= nCols)) {
throw new MatrixException(MatrixException.INVALID_INDEX);
}
ColumnVector cv = new ColumnVector(nRows);
for (int r = 0; r < nRows; ++r) {
cv.values[r][0] = this.values[r][c];
}
return cv;
}
/**
* Copy the values of this matrix.
* @return the values
*/
public double[][] values() { return values; }
/**
* Copy the values of this matrix.
* @return the copied values
*/
public double[][] copyValues2D()
{
double v[][] = new double[nRows][nCols];
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < nCols; ++c) {
v[r][c] = values[r][c];
}
}
return v;
}
//---------//
// Setters //
//---------//
/**
* Set the value of element [r,c].
* @param r the row index
* @param c the column index
* @param value the value
* @throws numbercruncher.MatrixException for an invalid index
*/
public void set(int r, int c, double value) throws MatrixException
{
if ((r < 0) || (r >= nRows) || (c < 0) || (c >= nCols)) {
throw new MatrixException(MatrixException.INVALID_INDEX);
}
values[r][c] = value;
}
/**
* Set this matrix from a 2-d array of values.
* If the rows do not have the same length, then the matrix
* column count is the length of the shortest row.
* @param values the 2-d array of values
*/
protected void set(double values[][])
{
this.nRows = values.length;
this.nCols = values[0].length;
this.values = values;
for (int r = 1; r < nRows; ++r) {
nCols = Math.min(nCols, values[r].length);
}
}
/**
* Set a row of this matrix from a row vector.
* @param rv the row vector
* @param r the row index
* @throws numbercruncher.MatrixException for an invalid index or
* an invalid vector size
*/
public void setRow(RowVector rv, int r) throws MatrixException
{
if ((r < 0) || (r >= nRows)) {
throw new MatrixException(MatrixException.INVALID_INDEX);
}
if (nCols != rv.nCols) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
for (int c = 0; c < nCols; ++c) {
this.values[r][c] = rv.values[0][c];
}
}
/**
* Set a column of this matrix from a column vector.
* @param cv the column vector
* @param c the column index
* @throws numbercruncher.MatrixException for an invalid index or
* an invalid vector size
*/
public void setColumn(ColumnVector cv, int c)
throws MatrixException
{
if ((c < 0) || (c >= nCols)) {
throw new MatrixException(MatrixException.INVALID_INDEX);
}
if (nRows != cv.nRows) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
for (int r = 0; r < nRows; ++r) {
this.values[r][c] = cv.values[r][0];
}
}
//-------------------//
// Matrix operations //
//-------------------//
/**
* Return the transpose of this matrix.
* @return the transposed matrix
*/
public Matrix transpose()
{
double tv[][] = new double[nCols][nRows]; // transposed values
// Set the values of the transpose.
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < nCols; ++c) {
tv[c][r] = values[r][c];
}
}
return new Matrix(tv);
}
/**
* Add another matrix to this matrix.
* @param m the matrix addend
* @return the sum matrix
* @throws numbercruncher.MatrixException for invalid size
*/
public Matrix add(Matrix m) throws MatrixException
{
// Validate m's size.
if ((nRows != m.nRows) && (nCols != m.nCols)) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
double sv[][] = new double[nRows][nCols]; // sum values
// Compute values of the sum.
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < nCols; ++c) {
sv[r][c] = values[r][c] + m.values[r][c];
}
}
return new Matrix(sv);
}
/**
* Subtract another matrix from this matrix.
* @param m the matrix subrrahend
* @return the difference matrix
* @throws numbercruncher.MatrixException for invalid size
*/
public Matrix subtract(Matrix m) throws MatrixException
{
// Validate m's size.
if ((nRows != m.nRows) && (nCols != m.nCols)) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
double dv[][] = new double[nRows][nCols]; // difference values
// Compute values of the difference.
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < nCols; ++c) {
dv[r][c] = values[r][c] - m.values[r][c];
}
}
return new Matrix(dv);
}
/**
* Multiply this matrix by a constant.
* @param k the constant
* @return the product matrix
*/
public Matrix multiply(double k)
{
double pv[][] = new double[nRows][nCols]; // product values
// Compute values of the product.
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < nCols; ++c) {
pv[r][c] = k*values[r][c];
}
}
return new Matrix(pv);
}
/**
* Multiply this matrix by another matrix.
* @param m the matrix multiplier
* @return the product matrix
* @throws numbercruncher.MatrixException for invalid size
*/
public Matrix multiply(Matrix m) throws MatrixException
{
// Validate m's dimensions.
if (nCols != m.nRows) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
double pv[][] = new double[nRows][m.nCols]; // product values
// Compute values of the product.
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < m.nCols; ++c) {
double dot = 0;
for (int k = 0; k < nCols; ++k) {
dot += values[r][k] * m.values[k][c];
}
pv[r][c] = dot;
}
}
return new Matrix(pv);
}
/**
* Multiply this matrix by a column vector: this*cv
* @param cv the column vector
* @return the product column vector
* @throws numbercruncher.MatrixException for invalid size
*/
public ColumnVector multiply(ColumnVector cv)
throws MatrixException
{
// Validate cv's size.
if (nRows != cv.nRows) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
double pv[] = new double[nRows]; // product values
// Compute the values of the product.
for (int r = 0; r < nRows; ++r) {
double dot = 0;
for (int c = 0; c < nCols; ++c) {
dot += values[r][c] * cv.values[c][0];
}
pv[r] = dot;
}
return new ColumnVector(pv);
}
/**
* Multiply a row vector by this matrix: rv*this
* @param rv the row vector
* @return the product row vector
* @throws numbercruncher.MatrixException for invalid size
*/
public RowVector multiply(RowVector rv) throws MatrixException
{
// Validate rv's size.
if (nCols != rv.nCols) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
double pv[] = new double[nRows]; // product values
// Compute the values of the product.
for (int c = 0; c < nCols; ++c) {
double dot = 0;
for (int r = 0; r < nRows; ++r) {
dot += rv.values[0][r] * values[r][c];
}
pv[c] = dot;
}
return new RowVector(pv);
}
}