package mikera.matrixx.impl; import java.util.List; import mikera.matrixx.AMatrix; import mikera.matrixx.Matrix; import mikera.matrixx.Matrixx; import mikera.vectorz.AVector; import mikera.vectorz.Op; import mikera.vectorz.Vectorz; import mikera.vectorz.util.ErrorMessages; /** * A matrix implemented as a composition of M length N vectors * @author Mike * */ public class VectorMatrixMN extends AVectorMatrix<AVector> { private static final long serialVersionUID = -3660730676103956050L; protected final AVector[] rowData; public VectorMatrixMN(int rowCount, int columnCount) { super(rowCount,columnCount); this.rowData=new AVector[rowCount]; for (int i=0; i<rowCount; i++) { rowData[i]=Vectorz.newVector(columnCount); } } protected VectorMatrixMN(AVector... rows) { super(rows.length,(rows.length>0)?rows[0].length():0); this.rowData=rows; } /** * Create a matrix from a list of rows * * @param rows * @return */ public static VectorMatrixMN create(List<?> rows) { int rc = rows.size(); AVector[] vs = new AVector[rc]; for (int i = 0; i < rc; i++) { vs[i] = Vectorz.toVector(rows.get(i)); } return VectorMatrixMN.wrap(vs); } public static VectorMatrixMN create(List<?> rows, int[] shape) { int rc = rows.size(); AVector[] vs = new AVector[rc]; for (int i = 0; i < rc; i++) { vs[i] = Vectorz.toVector(rows.get(i)); } return VectorMatrixMN.wrap(vs); } public static VectorMatrixMN wrap(AVector[] rows) { return new VectorMatrixMN(rows); } @Override public void multiply(double factor) { for (int i=0; i<rows; i++) { rowData[i].scale(factor); } } @Override public void applyOp(Op op) { for (int i=0; i<rows; i++) { rowData[i].applyOp(op); } } public static VectorMatrixMN create(AMatrix source) { int rc=source.rowCount(); VectorMatrixMN m=new VectorMatrixMN(source.rowCount(),source.columnCount()); for (int i=0; i<rc; i++) { m.rowData[i].set(source.getRow(i)); } return m; } public static VectorMatrixMN wrap(AMatrix source) { int rc=source.rowCount(); AVector[] rows=new AVector[rc]; for (int i=0; i<rc; i++) { rows[i]=source.getRowView(i); } return new VectorMatrixMN(rows); } @Override public void replaceRow(int i, AVector row) { if ((i<0)||(i>=rows)) throw new IndexOutOfBoundsException(ErrorMessages.invalidSlice(this, i)); rowData[i]=row; } @Override public void swapRows(int i, int j) { if (i!=j) { AVector t=rowData[i]; rowData[i]=rowData[j]; rowData[j]=t; } } @Override public AVector getRowView(int row) { if (row>=rows) throw new IndexOutOfBoundsException(ErrorMessages.invalidSlice(this, row)); return rowData[row]; } @Override public double get(int row, int column) { checkIndex(row,column); return rowData[row].unsafeGet(column); } @Override public void set(int row, int column, double value) { checkIndex(row,column); rowData[row].unsafeSet(column,value); } @Override public double unsafeGet(int row, int column) { return rowData[row].unsafeGet(column); } @Override public void unsafeSet(int row, int column, double value) { rowData[row].unsafeSet(column,value); } @Override public void addAt(int i, int j, double d) { rowData[i].addAt(j, d); } @Override public void transform(AVector source, AVector dest) { for (int i=0; i<rows; i++) { dest.unsafeSet(i,getRow(i).dotProduct(source)); } } @Override public double calculateElement(int i, AVector inputVector) { assert(i<rows); AVector row=rowData[i]; return row.dotProduct(inputVector); } @Override public boolean isSquare() { return rows==cols; } @Override public Matrix clone() { return Matrixx.create(this); } @Override public VectorMatrixMN exactClone() { AVector[] newRows=rowData.clone(); for (int i=0; i<rows; i++) { newRows[i]=newRows[i].exactClone(); } return new VectorMatrixMN(newRows); } }