// Start with a zero-sized matrix
super(0, 0);
// Get matrix information. Use the header if present, else just assume
// that the matrix stores real numbers without any symmetry
MatrixInfo info = null;
if (r.hasInfo())
info = r.readMatrixInfo();
else
info = new MatrixInfo(true, MatrixInfo.MatrixField.Real,
MatrixInfo.MatrixSymmetry.General);
// Check that the matrix is in an acceptable format
if (info.isPattern())
throw new UnsupportedOperationException(
"Pattern matrices are not supported");
if (info.isDense())
throw new UnsupportedOperationException(
"Dense matrices are not supported");
if (info.isComplex())
throw new UnsupportedOperationException(
"Complex matrices are not supported");
// Resize the matrix to correct size
MatrixSize size = r.readMatrixSize(info);
numRows = size.numRows();
numColumns = size.numColumns();
// Start reading entries
int numEntries = size.numEntries();
int[] row = new int[numEntries];
int[] column = new int[numEntries];
double[] entry = new double[numEntries];
r.readCoordinate(row, column, entry);
// Shift the indices from 1 based to 0 based
r.add(-1, row);
r.add(-1, column);
// Find the number of entries on each column
List<Set<Integer>> cnz = new ArrayList<Set<Integer>>(numColumns);
for (int i = 0; i < numColumns; ++i)
cnz.add(new HashSet<Integer>());
for (int i = 0; i < numEntries; ++i)
cnz.get(column[i]).add(row[i]);
// Allocate some more in case of symmetry
if (info.isSymmetric() || info.isSkewSymmetric())
for (int i = 0; i < numEntries; ++i)
if (row[i] != column[i])
cnz.get(row[i]).add(column[i]);
int[][] nz = new int[numColumns][];
for (int i = 0; i < numColumns; ++i) {
nz[i] = new int[cnz.get(i).size()];
int j = 0;
for (Integer rowind : cnz.get(i))
nz[i][j++] = rowind;
}
// Create the sparse matrix structure
construct(nz);
// Insert the entries
for (int i = 0; i < size.numEntries(); ++i)
set(row[i], column[i], entry[i]);
// Put in extra entries from symmetry or skew symmetry
if (info.isSymmetric())
for (int i = 0; i < numEntries; ++i) {
if (row[i] != column[i])
set(column[i], row[i], entry[i]);
}
else if (info.isSkewSymmetric())
for (int i = 0; i < numEntries; ++i) {
if (row[i] != column[i])
set(column[i], row[i], -entry[i]);
}
}