"denote an edge from row i to row j");
if (!(matrix instanceof SparseMatrix)) {
throw new IllegalArgumentException("Input matrix must be a " +
"sparse matrix.");
}
SparseMatrix sm = (SparseMatrix)matrix;
String inMemProp =
props.getProperty(KEEP_SIMILARITY_MATRIX_IN_MEMORY_PROPERTY);
boolean keepSimMatrixInMem = (inMemProp != null)
? Boolean.parseBoolean(inMemProp) : true;
// IMPLEMENTATION NOTE: Ahn et al. used single-linkage HAC, which can be
// efficiently implemented in O(n^2) time as a special case of HAC.
// However, we currently don't optimize for this special case and
// instead use our HAC class. Because of the complexity of the edge
// similarity function, we build our own similarity matrix and then pass
// it in, rather than passing in the edge matrix directly.
final int rows = sm.rows();
numRows = rows;
LOGGER.fine("Generating link similarity matrix for " + rows + " nodes");
// Rather than create an O(row^3) matrix for representing the edges,
// compress the edge matrix by getting a mapping for each edge to a row
// in the new matrix.
final List<Edge> edgeList = new ArrayList<Edge>();
this.edgeList = edgeList;
for (int r = 0; r < rows; ++r) {
SparseDoubleVector row = sm.getRowVector(r);
int[] edges = row.getNonZeroIndices();
for (int col : edges) {
// Always add edges from the upper triangular
if (r > col)
edgeList.add(new Edge(r, col));
// Otherwise, we only add the edge from the lower triangular if
// it wasn't present in the upper. This avoids counting
// duplicate edges.
else if (r < col && sm.get(col, r) == 0)
edgeList.add(new Edge(r, col));
}
}
final int numEdges = edgeList.size();