package tk.amberide.engine.data.sparse; import tk.amberide.engine.data.sparse.SparseVector.SparseVectorIterator; import java.util.Iterator; public class SparseMatrix<T> implements Iterable<T>, Cloneable { private final int N; // N-by-N matrix private SparseVector[] rows; // the rows, each row is a sparse vector // initialize an N-by-N matrix of all 0s public SparseMatrix(int N) { this.N = N; rows = new SparseVector[N]; for (int i = 0; i < N; i++) { rows[i] = new SparseVector(N); } } public SparseMatrix<T> clone() { SparseMatrix<T> clone = new SparseMatrix<T>(N); SparseVector[] clonedRows = new SparseVector[rows.length]; for (int i = 0; i != clonedRows.length; i++) { clonedRows[i] = rows[i].clone(); } clone.rows = clonedRows; return clone; } // put A[i][j] = value public void put(int i, int j, T value) { if (i < 0 || i >= N) { throw new IndexOutOfBoundsException("illegal index: " + i + ", " + j); } if (j < 0 || j >= N) { throw new IndexOutOfBoundsException("illegal index: " + i + ", " + j); } rows[i].set(j, value); } // return A[i][j] public T get(int i, int j) { if (i < 0 || i >= N) { throw new IndexOutOfBoundsException("illegal index: " + i + ", " + j); } if (j < 0 || j >= N) { throw new IndexOutOfBoundsException("illegal index: " + i + ", " + j); } return (T) rows[i].get(j); } public SparseMatrixIterator<T> iterator() { return new SparseMatrixIterator<T>(); } public class SparseMatrixIterator<T> implements Iterator<T> { int index; SparseVectorIterator row = rows[0].iterator(); public boolean hasNext() { return index < rows.length - 1 || row.hasNext(); } public T next() { if (!row.hasNext()) { index++; row = rows[index].iterator(); } return row.hasNext() ? (T) row.next() : null; } public void remove() { row.remove(); } public int realX() { return index; } public int realY() { return row.realIndex(); } } }