Skip to content

Commit

Permalink
Matrix sparsity and typed matrix sparsity implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
pvarhegyi committed Oct 23, 2018
1 parent eb466bc commit 9c4ec8a
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 15 deletions.
21 changes: 20 additions & 1 deletion adapters/src/main/java/hu/bme/mit/ga/adapters/GraphIndexer.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
public final class GraphIndexer<N, T> {

private int numberOfEdges;

private Map<T, Double> typedEdges = new HashMap<>();
private Map<T, Multimap<N, N>> outgoing = new HashMap<>();
private Map<T, Multimap<N, N>> incoming = new HashMap<>();

Expand All @@ -32,6 +34,8 @@ public final class GraphIndexer<N, T> {

private Matrix adjacencyMatrixUntyped;

private DMatrixSparseTriplet adjacencyMatrixEjmlUntyped;

private int size;
private int rowsAdded = 0;
private Set<T> types = new HashSet<>();
Expand All @@ -50,8 +54,11 @@ public GraphIndexer(int size) {
adjacencyMatrix2.put(type, m2);
DMatrixSparseTriplet triplets = new DMatrixSparseTriplet(size, size, size);
adjacencyMatrixEjml.put(type, triplets);
typedEdges.put(type, 0.0);
}
adjacencyMatrixUntyped = SparseMatrix.Factory.zeros(size, size);
adjacencyMatrixEjmlUntyped = new DMatrixSparseTriplet(size, size, 0);

}

public void persist(final String path) throws FileNotFoundException {
Expand Down Expand Up @@ -82,18 +89,21 @@ public void addEdge(final T type, final N sourceNode, final N targetNode) {
}
outgoing.get(type).put(sourceNode, targetNode);
incoming.get(type).put(targetNode, sourceNode);
typedEdges.replace(type, typedEdges.get(type) + 1);
if (adjacencyMatrixUntyped != null && adjacencyMatrixEjml != null) {
long sourceNodeInd = nodeRowMap.get(sourceNode);
long targetNodeInd = nodeRowMap.get(targetNode);
adjacencyMatrix.get(type).setAsDouble(1.0, sourceNodeInd, targetNodeInd);
adjacencyMatrix.get(type).setAsDouble(1.0, targetNodeInd, sourceNodeInd);
adjacencyMatrix2.get(type).set(sourceNodeInd, targetNodeInd, (Number) 1.0);
adjacencyMatrix2.get(type).set(targetNodeInd, sourceNodeInd, (Number) 1.0);
adjacencyMatrixEjmlUntyped.set((int) sourceNodeInd, (int) targetNodeInd, 1);
adjacencyMatrixEjmlUntyped.set((int) targetNodeInd, (int) sourceNodeInd, 1);
adjacencyMatrixUntyped.setAsDouble(1.0, sourceNodeInd, targetNodeInd);
adjacencyMatrixUntyped.setAsDouble(1.0, targetNodeInd, sourceNodeInd);
adjacencyMatrixEjml.get(type).set((int) sourceNodeInd, (int) targetNodeInd, 1);
adjacencyMatrixEjml.get(type).set((int) targetNodeInd, (int) sourceNodeInd, 1);
numberOfEdges+=0;
numberOfEdges += 0;

}

Expand All @@ -102,6 +112,7 @@ public void addEdge(final T type, final N sourceNode, final N targetNode) {

public void addType(T type) {
types.add(type);
typedEdges.putIfAbsent(type, 0.0);
outgoing.put(type, ArrayListMultimap.create());
incoming.put(type, ArrayListMultimap.create());

Expand Down Expand Up @@ -291,5 +302,13 @@ public Map<T, DMatrixSparseTriplet> getAdjacencyMatrixEjml() {
return adjacencyMatrixEjml;
}

public Map<T, Double> getTypedEdges() {
return typedEdges;
}

public DMatrixSparseTriplet getAdjacencyMatrixEjmlUntyped() {
return adjacencyMatrixEjmlUntyped;
}


}
37 changes: 23 additions & 14 deletions analyzer-app/src/Analyzer.groovy
Original file line number Diff line number Diff line change
@@ -1,32 +1,41 @@
import analyzer.AnalyzerUtil
import hu.bme.mit.ga.adapters.csv.CsvGraphAdapter
import hu.bme.mit.ga.metrics.impl.simple.ClusteringCoefficient
import hu.bme.mit.ga.metrics.impl.simple.MatrixSparsity
import hu.bme.mit.ga.metrics.impl.typed.*
import org.supercsv.cellprocessor.constraint.NotNull

println('Graph metric analyzer')
println('=====================')

def graphs = ['test']
def graphs = ['panama']

// Set the reportUrl if you would like to receive a Slack notification when the analysis finished.
// The default configuration points to our research group's Slack.
//reportUrl = "https://hooks.slack.com/services/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"

def reps = 3
def reps = 1

def metrics = [
new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.EDGELIST),
new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.OJALGO),
new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.OJALGO_EW),
new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.OJALGO_EW_STREAM),
new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.UJMP),
new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.UJMP_EW),
new TypedClusteringCoefficientDef2(TypedClusteringCoefficientDef2.Implementation.EDGELIST),
new TypedClusteringCoefficientDef2(TypedClusteringCoefficientDef2.Implementation.OJALGO_EW),
new TypedClusteringCoefficientDef2(TypedClusteringCoefficientDef2.Implementation.OJALGO_MMM),
new TypedClusteringCoefficientDef2(TypedClusteringCoefficientDef2.Implementation.OJALGO_EW_STREAM),
new EdgeOverlap(EdgeOverlap.Implementation.OJALGO),
new EdgeOverlap(EdgeOverlap.Implementation.EDGELIST)
// new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.EDGELIST),
// new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.OJALGO),
// new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.OJALGO_EW),
// new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.OJALGO_EW_STREAM),
// new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.UJMP),
// new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.UJMP_EW),
// new TypedClusteringCoefficientDef2(TypedClusteringCoefficientDef2.Implementation.EDGELIST),
// new TypedClusteringCoefficientDef2(TypedClusteringCoefficientDef2.Implementation.OJALGO_EW),
// new TypedClusteringCoefficientDef2(TypedClusteringCoefficientDef2.Implementation.OJALGO_MMM),
// new TypedClusteringCoefficientDef2(TypedClusteringCoefficientDef2.Implementation.OJALGO_EW_STREAM),
// new EdgeOverlap(EdgeOverlap.Implementation.OJALGO),
// new EdgeOverlap(EdgeOverlap.Implementation.EDGELIST)
//new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.EJML_EW_STREAM),
// new EdgeOverlap(EdgeOverlap.Implementation.EDGELIST)
// new TypedMatrixSparsity(),
// new MatrixSparsity(),
new TypedClusteringCoefficientDef1(TypedClusteringCoefficientDef1.Implementation.EJML_EW_STREAM),
new TypedClusteringCoefficientDef2(TypedClusteringCoefficientDef2.Implementation.EJML_EW),
new EdgeOverlap()
]

graphs.each { graph ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package hu.bme.mit.ga.metrics.impl.simple;

import hu.bme.mit.ga.adapters.GraphAdapter;
import hu.bme.mit.ga.adapters.GraphIndexer;
import hu.bme.mit.ga.base.data.ScalarData;
import hu.bme.mit.ga.metrics.AbstractGraphMetric;
import org.ejml.data.DMatrixRMaj;
import org.ejml.data.DMatrixSparseCSC;
import org.ejml.data.DMatrixSparseTriplet;
import org.ejml.ops.ConvertDMatrixStruct;
import org.ejml.simple.SimpleMatrix;
import org.ejml.sparse.csc.CommonOps_DSCC;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MatrixSparsity extends AbstractGraphMetric<ScalarData<Double>> {
public MatrixSparsity() {
super("MatrixSparsity", new ScalarData<>());
}
@Override
protected <N, T> void evaluateAll(GraphAdapter<N, T> adapter) {
GraphIndexer<N, T> indexer = adapter.getIndexer();
int size = indexer.getSize();
DMatrixSparseTriplet triplets = indexer.getAdjacencyMatrixEjmlUntyped();
DMatrixSparseCSC A = ConvertDMatrixStruct.convert(triplets, (DMatrixSparseCSC) null);
DMatrixRMaj rowSum = new DMatrixRMaj(size, 1);
CommonOps_DSCC.sumRows(A,rowSum);
double d = SimpleMatrix.wrap(rowSum).elementSum();
double n = size*size;
data.setValue(d/n);
}

@Override
public List<Map<String, Object>> getTsvMaps(String[] header) {
final List<Map<String, Object>> values = new ArrayList<>();
Map<String, Object> value = new HashMap<>();
value.put(header[0], "MatrixSparsity");
value.put(header[1], null);
value.put(header[2], null);
value.put(header[3], data.getValue());
values.add(value);
return values;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package hu.bme.mit.ga.metrics.impl.typed;

import hu.bme.mit.ga.adapters.GraphIndexer;
import hu.bme.mit.ga.base.data.MapData;
import hu.bme.mit.ga.adapters.GraphAdapter;
import hu.bme.mit.ga.metrics.AbstractGraphMetric;
import org.ejml.data.DMatrixRMaj;
import org.ejml.data.DMatrixSparseCSC;
import org.ejml.data.DMatrixSparseTriplet;
import org.ejml.ops.ConvertDMatrixStruct;
import org.ejml.simple.SimpleMatrix;
import org.ejml.sparse.csc.CommonOps_DSCC;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TypedMatrixSparsity extends AbstractGraphMetric<MapData<String, Double>> {

public TypedMatrixSparsity() {
super("TypedMatrixSparsity", new MapData<>());
}

@Override
protected <N, T> void evaluateAll(GraphAdapter<N, T> adapter) {
for (T type : adapter.getIndexer().getTypes()) {
evaluateT(adapter, type);
}
}

protected <N, T> void evaluateT(GraphAdapter<N, T> adapter, T type) {
GraphIndexer indexer = adapter.getIndexer();
int n = adapter.getIndexer().getSize();
double nonzero = (double)indexer.getTypedEdges().get(type)*2;
double size = n*n;
data.put(type.toString(), nonzero / size);
}

@Override
public List<Map<String, Object>> getTsvMaps(String[] header) {
final List<Map<String, Object>> values = new ArrayList<>();
for (String type : data.getValues().keySet()) {
Double value = data.getValues().get(type);
Map<String, Object> row = new HashMap<>();
row.put(header[0], "TypedMatrixSparsity");
row.put(header[1], type);
row.put(header[2], null);
row.put(header[3], value);
values.add(row);
}
return values;
}
}

0 comments on commit 9c4ec8a

Please sign in to comment.