/* * @author: cdehais */ package algebra; public class Matrix { protected Matrix() { } protected Matrix(String name) { this.name = name; } /** * Creates a named Matrix of size nRows x nCols. */ public Matrix(String name, int nRows, int nCols) throws java.lang.InstantiationException { this(nRows, nCols); this.name = name; } /** * Creates a Matrix of size nRows x nCols. */ public Matrix(int nRows, int nCols) throws java.lang.InstantiationException { allocValues(nRows, nCols); } /** * Creates an identity matrix of size @size */ public static Matrix createIdentity(int size) throws java.lang.InstantiationException { Matrix id = new Matrix(size, size); for (int i = 0; i < size; i++) { id.values[size * i + i] = 1.0; } id.name = "I" + size; return id; } /** * Extracts a submatrix of size nRows x nCols with top left corner at * (offsetRow, offsetCol) */ public Matrix getSubMatrix(int offsetRow, int offsetCol, int nRows, int nCols) throws InstantiationException { if ((offsetRow < 0) || (offsetCol < 0) || (nRows < 1) || (nCols < 1) || (offsetRow + nRows > this.nRows) || (offsetCol + nCols > this.nCols)) { throw new InstantiationException("Invalid submatrix"); } Matrix sub = new Matrix(nRows, nCols); for (int i = 0; i < nRows; i++) { for (int j = 0; j < nCols; j++) { sub.set(i, j, this.get(offsetRow + i, offsetCol + j)); } } return sub; } /** * Transposes the square Matrix. */ public Matrix transpose() { Matrix trans; try { trans = new Matrix(this.nCols, this.nRows); } catch (java.lang.InstantiationException e) { /* unreached */ return null; } for (int i = 0; i < nCols; i++) { for (int j = i + 1; j < nRows; j++) { trans.values[i * nCols + j] = this.values[j * nCols + i]; trans.values[j * nCols + i] = this.values[i * nCols + j]; } } return trans; } /** * Matrix/Matrix multiplication */ public Matrix multiply(Matrix M) throws SizeMismatchException { if (nCols != M.nRows) { throw new SizeMismatchException(this, M); } Matrix R; try { R = new Matrix(this.nRows, M.nCols); } catch (java.lang.InstantiationException e) { /* unreached */ return null; } for (int i = 0; i < R.nRows; i++) { for (int j = 0; j < R.nCols; j++) { for (int k = 0; k < this.nCols; k++) { R.values[i * R.nCols + j] += this.values[i * nCols + k] * M.values[k * nRows + j]; } } } return R; } /** * Matrix/vector multiplication */ public Vector multiply(Vector v) throws SizeMismatchException { if (nCols != v.size()) { throw new SizeMismatchException(this, v); } Vector u = null; try { u = new Vector(nRows); } catch (java.lang.InstantiationException e) { /* unreached */ } for (int i = 0; i < u.size(); i++) { double e = 0.0; for (int k = 0; k < this.nCols; k++) { e += values[i * nCols + k] * v.get(k); } u.set(i, e); } return u; } /** * Sets the element on row @i and column @j to the given value @value. */ public void set(int i, int j, double value) { values[i * nCols + j] = value; } /** * Gets the element on row @i and column @j. */ public double get(int i, int j) { return values[i * nCols + j]; } /** * Sets the matrix name */ public void setName(String name) { this.name = name; } /** * Returns a Matlab compatible representation of the Matrix. */ public String toString() { String repr = name + " = ["; int spacing = repr.length(); for (int i = 0; i < nRows; i++) { if (i > 0) { for (int j = 0; j < spacing; j++) { repr += " "; } } for (int j = 0; j < nCols; j++) { repr += values[nCols * i + j] + " "; } repr += ";\n"; } repr += "];"; return repr; } protected void allocValues(int nRows, int nCols) throws java.lang.InstantiationException { int size = nRows * nCols; if (size < 1) { throw new java.lang.InstantiationException("Both matrix dimensions must be strictly positive"); } this.values = new double[size]; this.nRows = nRows; this.nCols = nCols; } public String getName() { return name; } public int nRows() { return nRows; } public int nCols() { return nCols; } public String name = "M"; protected double values[]; private int nRows; private int nCols; }