//Copyright (C) 2011 Zeno Gantner, Chris Newell
//
//This file is part of MyMediaLite.
//
//MyMediaLite is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//MyMediaLite 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 General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with MyMediaLite. If not, see <http://www.gnu.org/licenses/>.
package org.mymedialite.datatype;
/**
* Class for storing dense matrices.
*
* The data is stored in row-major mode.
* Indexes are zero-based.
*
* @param <T> the type of the matrix entries
* @version 2.03
*/
public class SymmetricMatrix<T> implements IMatrix<T> {
/**
* Data array: data is stored in columns..
*/
protected Object[][] data;
/**
* Dimension, the number of rows and columns.
*/
public int dim;
/**
*
*/
public boolean isSymmetric() {
return true;
}
/**
*
*/
public int numberOfRows() {
return dim;
}
/**
*
*/
public int numberOfColumns() {
return dim;
}
/**
* Initializes a new instance of the SymmetricMatrix class.
* @param dim the number of rows and columns
* @param d the default value for elements, or null
*/
public SymmetricMatrix(int dim, T d) {
if (dim < 0) throw new IllegalArgumentException("dim must be at least 0");
this.dim = dim;
this.data = new Object[dim][];
for (int i = 0; i < dim; i++)
data[i] = new Object[i + 1];
if(d != null) init(d);
}
/**
*
*/
public IMatrix<T> createMatrix(int num_rows, int num_columns) {
if (num_rows != num_columns)
throw new IllegalArgumentException("num_rows must equal num_columns for symmetric matrices");
return new SymmetricMatrix<T>(num_rows, null);
}
/**
* Initialize the matrix with a default value
* @param d the default value
*/
public void init(T d) {
for (int i = 0; i < dim; i++)
for (int j = 0; j <= i; j++)
data[i][j] = d;
}
/**
*
*/
public IMatrix<T> transpose() {
throw new UnsupportedOperationException();
}
/**
*
*/
@SuppressWarnings("unchecked")
public T get(int i, int j) {
if (i >= j)
return (T)data[i][j];
else
return (T)data[j][i];
}
public void set(int i, int j, T value) {
if (i >= j)
data[i][j] = value;
else
data[j][i] = value;
}
/**
*
*/
public void grow(int num_rows, int num_columns) {
if (num_rows != num_columns)
throw new IllegalArgumentException("num_rows must equal num_columns for symmetric matrices");
if (num_rows > dim) {
// Create new data structure
Object [][] new_data = new Object[num_rows][];
for (int i = 0; i < num_rows; i++)
new_data[i] = new Object[i + 1];
for (int i = 0; i < dim; i++)
// TODO use arraycopy here.
for (int j = 0; j <= i; j++)
new_data[i][j] = get(i, j);
// Replace old data structure
this.dim = num_rows;
this.data = new_data;
}
}
}