package matrix.implementations.memory; import java.io.File; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import matrix.AbstractDataMatrixInstance; import matrix.general.MatrixReadException; import org.molgenis.data.Data; import org.molgenis.matrix.MatrixException; import decorators.NameConvention; /** * In memory representation of a matrix * * @author Morris Swertz */ public class MemoryDataMatrixInstance<E> extends AbstractDataMatrixInstance<E> { // matrix of row,col E[][] values; public MemoryDataMatrixInstance(List<String> rownames, List<String> colnames, List<E[]> valueList, Data data) throws MatrixException { int nrOfRows = valueList.size(); int nrOfCols = valueList.get(0).length; // see: // http://stackoverflow.com/questions/2927391/whats-the-reason-i-cant-create-generic-array-types-in-java E[][] values = (E[][]) new Object[nrOfRows][nrOfCols]; for (int rowIndex = 0; rowIndex < nrOfRows; rowIndex++) { E[] row = valueList.get(rowIndex); if (row.length != nrOfCols) { throw new MatrixException("Unequal number of columns in this matrix is not allowed"); } for (int colIndex = 0; colIndex < row.length; colIndex++) { values[rowIndex][colIndex] = row[colIndex]; } } // checks if (rownames.size() != values.length) throw new MatrixException( "rownames.length and values[] (rows) are of different sizes: " + rownames.size() + " vs " + values.length); int i = 0; for (E[] row : values) { if (colnames.size() != row.length) throw new MatrixException("colnames.length and values[" + i + "].length (col) are of different sizes: " + colnames.size() + " vs " + row.length); i++; } if (data == null) { data = new Data(); data.setName("nameless_memorymatrix"); } // configure this.setColNames(colnames); this.setRowNames(rownames); this.setNumberOfCols(colnames.size()); this.setNumberOfRows(rownames.size()); this.values = values; this.setData(data); } public MemoryDataMatrixInstance(List<String> rownames, List<String> colnames, E[][] values, Data data) throws MatrixException { // checks if (rownames.size() != values.length) throw new MatrixException( "rownames.length and values[] (rows) are of different sizes: " + rownames.size() + " vs " + values.length); int i = 0; for (E[] row : values) { if (colnames.size() != row.length) throw new MatrixException("colnames.length and values[" + i + "].length (col) are of different sizes: " + colnames.size() + " vs " + row.length); i++; } if (data == null) { data = new Data(); data.setName("nameless_memorymatrix"); } // configure this.setColNames(colnames); this.setRowNames(rownames); this.setNumberOfCols(colnames.size()); this.setNumberOfRows(rownames.size()); this.values = values; this.setData(data); } public void changeDataName(String name) { Data tmp = new Data(); tmp.setName(name); this.setData(tmp); } @Override public Object[] getCol(int i) throws MatrixException { // E[] result = create(values.length); Object[] result = new Object[values.length]; try { for (int j = 0; j < values.length; j++) { result[j] = values[j][i]; } } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixException("column with index " + i + " doesn't exist"); } return result; } @Override public E[] getRow(int i) throws MatrixReadException { try { return values[i]; } catch (ArrayIndexOutOfBoundsException e) { throw new MatrixReadException("row with index " + i + " doesn't exist"); } } @Override public E getElement(int row, int col) { return values[row][col]; } private E[] create(int rows) { return (E[]) new Double[rows]; } private E[][] create(int rows, int cols) { // FIXME return (E[][]) new Double[rows][cols]; } @Override public AbstractDataMatrixInstance<Object> getSubMatrixByOffset(int row, int nrows, int col, int ncols) throws Exception { List<String> rows = new ArrayList<String>(nrows); List<String> cols = new ArrayList<String>(ncols); Object[][] elements = new Object[nrows][ncols]; Object[][] allAlements = this.getElements(); rows = this.getRowNames().subList(row, row + nrows); cols = this.getColNames().subList(col, col + ncols); int rowPos = 0; for (int rowIndex = row; rowIndex < row + nrows; rowIndex++) { int colPos = 0; for (int colIndex = col; colIndex < col + ncols; colIndex++) { elements[rowPos][colPos] = allAlements[rowIndex][colIndex]; colPos++; } rowPos++; } return new MemoryDataMatrixInstance(rows, cols, elements, this.getData()); } @Override public AbstractDataMatrixInstance<Object> getSubMatrix(int[] rowIndices, int[] colIndices) throws MatrixException { List<String> rows = new ArrayList<String>(rowIndices.length); List<String> cols = new ArrayList<String>(colIndices.length); Object[][] elements = new Object[rowIndices.length][colIndices.length]; Object[][] allAlements = this.getElements(); for (int rowIndicesIndex = 0; rowIndicesIndex < rowIndices.length; rowIndicesIndex++) { rows.add(this.getRowNames().get(rowIndices[rowIndicesIndex])); for (int colIndicesIndex = 0; colIndicesIndex < colIndices.length; colIndicesIndex++) { elements[rowIndicesIndex][colIndicesIndex] = allAlements[rowIndices[rowIndicesIndex]][colIndices[colIndicesIndex]]; } } for (int colIndicesIndex = 0; colIndicesIndex < colIndices.length; colIndicesIndex++) { cols.add(this.getColNames().get(colIndices[colIndicesIndex])); } return new MemoryDataMatrixInstance(rows, cols, elements, this.getData()); } @Override public E[][] getElements() throws MatrixException { return values; } @Override public File getAsFile() throws Exception { File tmp = new File(System.getProperty("'java.io.tmpdir") + File.separator + NameConvention.escapeFileName(this.getData().getName()) + "_" + System.nanoTime()); boolean createTmp = tmp.createNewFile(); if (!createTmp) { throw new Exception("Creation of tmp file " + tmp.getAbsolutePath() + " failed."); } PrintWriter out = new PrintWriter(tmp); this.writeToCsvWriter(out); out.close(); // FIXME: close 'out'? return null; } @Override public void addColumn() throws Exception { throw new Exception("Action not possible"); } @Override public void addRow() throws Exception { throw new Exception("Action not possible"); } @Override public void updateElement() throws Exception { throw new Exception("Action not possible"); } }