/*
* MutableMatrix.java
*
* Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard
*
* This file is part of BEAST.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership and licensing.
*
* BEAST is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* BEAST is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with BEAST; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package dr.matrix;
/**
* An inteface for a mutable matrix.
*
* @version $Id: MutableMatrix.java,v 1.3 2005/05/24 20:26:01 rambaut Exp $
*
* @author Andrew Rambaut
*/
public interface MutableMatrix extends Matrix {
//***************************************************
// Setter methods
//***************************************************
/**
* sets the dimension of a square matrix
*/
void setDimension(int rows);
/**
* sets the dimension of a rectangular matrix
*/
void setDimension(int rows, int columns);
/**
* sets the matrix from another matrix object
*/
void setMatrix(Matrix matrix);
/**
* sets the matrix from an 2D array of doubles
*/
void setElements(double[][] values);
/**
* sets the matrix from an 1D array of doubles
*/
void setElements(double[] values);
/**
* sets all elements in a matrix with a single value
*/
void setElements(double value);
/**
* sets a single element
*/
void setElement(int row, int column, double value);
/**
* sets the ith element
*/
void setElement(int index, double value);
/**
* sets a single row
*/
void setRow(int row, double[] values);
/**
* sets a single column
*/
void setColumn(int column, double[] values);
/**
* sets the upper triangle
*/
void setUpperTriangle(double[] values) throws Matrix.NotSquareException;
/**
* sets the lower triangle
*/
void setLowerTriangle(double[] values) throws Matrix.NotSquareException;
/**
* sets the diagonal
*/
void setDiagonal(double[] values) throws Matrix.NotSquareException;
//***************************************************
// Manipulation methods
//***************************************************
/**
* transposes this matrix
*/
void makeTransposed();
/**
* makes the matrix symmetrical from the upper triangle
*/
void makeSymmetricFromUpperTriangle() throws Matrix.NotSquareException;
/**
* makes the matrix symmetrical from the lower triangle
*/
void makeSymmetricFromLowerTriangle() throws Matrix.NotSquareException;
/**
* makes the this matrix into an identity matrix
*/
void makeIdentity() throws Matrix.NotSquareException;
//***************************************************
// AbstractMutableMatrix class
//***************************************************
/**
* Abstract class providing a base for mutable matrix implementations. At the
* very least, classes derived from this need only implement
* setDimension(int, int), getRowCount(), getColumnCount(),
* setElement(int, int) and getElement(int, int).
*
* By using these access methods, it will not be very efficient.
*/
public abstract class AbstractMutableMatrix extends Matrix.AbstractMatrix
implements MutableMatrix {
/**
* Empty constructor
*/
public AbstractMutableMatrix() {
}
/**
* Construct a square matrix
*/
public AbstractMutableMatrix(int rows) {
setDimension(rows);
}
/**
* Construct a rectangular matrix
*/
public AbstractMutableMatrix(int rows, int columns) {
setDimension(rows, columns);
}
/**
* Constructor which copies from matrix
*/
public AbstractMutableMatrix(Matrix matrix) {
setDimension(matrix.getRowCount(), matrix.getColumnCount());
setMatrix(matrix);
}
/**
* Constructor which copies from 2D array of doubles
*/
public AbstractMutableMatrix(double[][] values) {
setDimension(values.length, values[0].length);
setElements(values);
}
/**
* Constructor which copies from 1D array of doubles.
*/
public AbstractMutableMatrix(int rows, int columns, double[] values) {
setDimension(rows, columns);
setElements(values);
}
/**
* Constructor which initialises every element to value.
*/
public AbstractMutableMatrix(int rows, int columns, double value) {
setDimension(rows, columns);
setElements(value);
}
//***************************************************
// Setter methods
//***************************************************
/**
* sets the dimension of a square matrix
*/
public void setDimension(int rows) {
setDimension(rows, rows);
}
/**
* sets the matrix from another matrix object. Both matrices
* must be the same size.
*/
public void setMatrix(Matrix matrix) {
int rc = matrix.getRowCount();
int cc = matrix.getColumnCount();
for (int r = 0; r < rc; r++) {
for (int c = 0; c < cc; c++) {
setElement(r, c, matrix.getElement(r, c));
}
}
}
/**
* sets the matrix from an 2D array of doubles. Both matrices
* must be the same size.
*/
public void setElements(double[][] values) {
setDimension(values.length, values[0].length);
for (int r = 0; r < values.length; r++) {
for (int c = 0; c < values[0].length; c++) {
setElement(r, c, values[r][c]);
}
}
}
/**
* sets the matrix from an 1D array of doubles. The dimension of
* the matrix must have already be set appropriately.
*/
public void setElements(double[] values) {
int k = 0;
int rc = getRowCount();
int cc = getColumnCount();
for (int r = 0; r < rc; r++) {
for (int c = 0; c < cc; c++) {
setElement(r, c, values[k]);
k++;
}
}
}
/**
* sets all elements in a matrix with a single value
*/
public void setElements(double value) {
int rc = getRowCount();
int cc = getColumnCount();
for (int r = 0; r < rc; r++) {
for (int c = 0; c < cc; c++) {
setElement(r, c, value);
}
}
}
/**
* sets the ith element
*/
public void setElement(int index, double value) {
int r = index / getColumnCount();
int c = index % getColumnCount();
setElement(r, c, value);
}
/**
* sets a single row
*/
public void setRow(int row, double[] values) {
int cc = getColumnCount();
for (int c = 0; c < cc; c++) {
setElement(row, c, values[c]);
}
}
/**
* sets a single column
*/
public void setColumn(int column, double[] values) {
int rc = getRowCount();
for (int r = 0; r < rc; r++) {
setElement(r, column, values[r]);
}
}
/**
* sets the upper triangle
*/
public void setUpperTriangle(double[] values) throws Matrix.NotSquareException {
if (!getIsSquare())
throw new Matrix.NotSquareException();
int k = 0;
int dim = getRowCount();
for (int r = 0; r < dim; r++) {
for (int c = r + 1; c < dim; c++) {
setElement(r, c, values[k]);
k++;
}
}
}
/**
* sets the lower triangle
*/
public void setLowerTriangle(double[] values) throws Matrix.NotSquareException {
if (!getIsSquare())
throw new Matrix.NotSquareException();
int k = 0;
int dim = getRowCount();
for (int r = 0; r < dim; r++) {
for (int c = 0; c < r; c++) {
setElement(r, c, values[k]);
k++;
}
}
}
/**
* sets the diagonal
*/
public void setDiagonal(double[] values) throws Matrix.NotSquareException {
if (!getIsSquare())
throw new Matrix.NotSquareException();
int dim = getRowCount();
for (int r = 0; r < dim; r++) {
setElement(r, r, values[r]);
}
}
//***************************************************
// Manipulation methods
//***************************************************
/**
* transposes this matrix
*/
public void makeTransposed() {
double[][] values = getElements2D();
int cc = getRowCount();
int rc = getColumnCount();
setDimension(rc, cc);
for (int r = 0; r < rc; r++) {
for (int c = 0; c < cc; c++) {
setElement(r, c, values[c][r]);
}
}
}
/**
* makes the matrix symmetrical from the upper triangle
*/
public void makeSymmetricFromUpperTriangle() throws Matrix.NotSquareException {
if (!getIsSquare())
throw new Matrix.NotSquareException();
double[] values = getUpperTriangle();
setLowerTriangle(values);
}
/**
* makes the matrix symmetrical from the lower triangle
*/
public void makeSymmetricFromLowerTriangle() throws Matrix.NotSquareException {
if (!getIsSquare())
throw new Matrix.NotSquareException();
double[] values = getUpperTriangle();
setLowerTriangle(values);
}
/**
* makes the this matrix into an identity matrix
*/
public void makeIdentity() throws Matrix.NotSquareException {
if (!getIsSquare())
throw new Matrix.NotSquareException();
setElements(0.0);
for (int i = 0; i < getRowCount(); i++)
setElement(i, i, 1.0);
}
}
}