Added ClusteringInput: Caches adjacency matrix, distance matrix, and abstracts usage and creation

parent 69d859ae
Pipeline #111011 failed with stages
in 30 minutes and 56 seconds
......@@ -108,7 +108,7 @@ public class DistributedTargetGenerator extends CMakeGenerator {
//Cluster
if(clusteringParameters.getAlgorithmParameters().size() > 0) {
clusteringResults = AutomaticClusteringHelper.executeClusteringFromParams(componentInstanceSymbol, clusteringParameters.getAlgorithmParameters());
clusteringResults = ClusteringResultList.fromParametersList(componentInstanceSymbol, clusteringParameters.getAlgorithmParameters());
Optional<Integer> nOpt = clusteringParameters.getNumberOfClusters();
for(ClusteringResult c : clusteringResults){
String prefix = nOpt.isPresent() && !c.hasNumberOfClusters(nOpt.get()) ? "[IGNORED]" : "";
......
......@@ -2,7 +2,7 @@ package de.monticore.lang.monticar.generator.middleware.Simulation;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.monticar.generator.middleware.clustering.AutomaticClusteringHelper;
import de.monticore.lang.monticar.generator.middleware.clustering.FlattenArchitecture;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringInput;
import de.monticore.lang.monticar.generator.middleware.clustering.algorithms.SpectralClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.clustering.algorithms.SpectralClusteringBuilder;
......@@ -18,11 +18,12 @@ public class MonteCarloIntegration {
double sum = 0;
if(index == 1){
ClusteringInput clusteringInput = new ClusteringInput(componentInstanceSymbol);
for(int i = 0; i<iterations; i++){
// This would be with Spectral Clustering
SpectralClusteringAlgorithm spectralClusteringAlgorithm = new SpectralClusteringAlgorithm();
Object[] params = new Object[]{SpectralClusteringBuilder.SpectralParameters.SPECTRAL_NUM_CLUSTERS, numberOfClusters};
List<Set<EMAComponentInstanceSymbol>> clusters = spectralClusteringAlgorithm.cluster(componentInstanceSymbol, params);
List<Set<EMAComponentInstanceSymbol>> clusters = spectralClusteringAlgorithm.cluster(clusteringInput, params);
//iterate through all clusters and add all cost of the ROS Tags between clusters
sum += AutomaticClusteringHelper.getTypeCostHeuristic(componentInstanceSymbol, clusters);
......
......@@ -7,12 +7,10 @@ import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instance
import de.monticore.lang.embeddedmontiarc.tagging.middleware.ros.RosConnectionSymbol;
import de.monticore.lang.math._ast.ASTNumberExpression;
import de.monticore.lang.monticar.common2._ast.ASTCommonMatrixType;
import de.monticore.lang.monticar.generator.middleware.cli.algorithms.AlgorithmCliParameters;
import de.monticore.lang.monticar.ts.MCTypeSymbol;
import de.monticore.lang.monticar.ts.references.MCASTTypeSymbolReference;
import de.monticore.lang.monticar.ts.references.MCTypeReference;
import de.monticore.symboltable.CommonSymbol;
import de.se_rwth.commons.logging.Log;
import org.jgrapht.Graph;
import org.jgrapht.alg.ConnectivityInspector;
import org.jgrapht.graph.DefaultEdge;
......@@ -291,18 +289,4 @@ public class AutomaticClusteringHelper {
}
public static ClusteringResultList executeClusteringFromParams(EMAComponentInstanceSymbol emaComponentInstance, List<AlgorithmCliParameters> algoParams) {
ClusteringResultList res = new ClusteringResultList();
for (int i = 0; i < algoParams.size(); i++) {
System.out.println("Clustering with algorithm " + (i + 1) + "/" + algoParams.size() + ": " + algoParams.get(i).toString());
ClusteringResult result = ClusteringResult.fromParameters(emaComponentInstance, algoParams.get(i));
if (result.isValid()) {
res.add(result);
} else {
Log.warn("Ignoring the result! It is invalid!");
}
}
return res;
}
}
......@@ -7,12 +7,12 @@ import java.util.Set;
// product if for clustering factory
public interface ClusteringAlgorithm {
List<Set<EMAComponentInstanceSymbol>> cluster(EMAComponentInstanceSymbol component, Object... args);
List<Set<EMAComponentInstanceSymbol>> cluster(ClusteringInput clusteringInput, Object... args);
//TODO: add arguments as typed state of the algorithms(instead of untyped)
default List<Set<EMAComponentInstanceSymbol>> clusterWithState(EMAComponentInstanceSymbol component){
default List<Set<EMAComponentInstanceSymbol>> clusterWithState(ClusteringInput clusteringInput){
Object[] args = getArgs();
return cluster(component, args);
return cluster(clusteringInput, args);
}
default Object[] getArgs(){
......
package de.monticore.lang.monticar.generator.middleware.clustering;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.monticar.generator.middleware.helpers.ComponentHelper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ClusteringInput {
private EMAComponentInstanceSymbol instanceSymbol;
private double[][] adjacencyMatrix;
private boolean initAdjMatrix = false;
private double[][] distanceMatrix;
private boolean initDistMatrix = false;
private List<EMAComponentInstanceSymbol> subcompsOrderedByName;
private boolean initSubcomposOrderedByName = false;
private Map<String, Integer> labelsForSubcomps;
private boolean initLabelsForSubcomps = false;
public ClusteringInput(EMAComponentInstanceSymbol instanceSymbol) {
this.instanceSymbol = instanceSymbol;
}
public EMAComponentInstanceSymbol getComponent() {
return instanceSymbol;
}
public double[][] getAdjacencyMatrix(){
if(!initAdjMatrix){
initAdjMatrix = true;
adjacencyMatrix = AutomaticClusteringHelper.guaranteedConnectedAdjacencyMatrix(getSubcompsOrderedByName(), ComponentHelper.getInnerConnectors(instanceSymbol),getLabelsForSubcomps());
}
return getCopyOf(adjacencyMatrix);
}
public double[][] getDistanceMatrix(){
if(!initDistMatrix){
initDistMatrix = true;
distanceMatrix = AutomaticClusteringHelper.getDistanceMatrix(getAdjacencyMatrix());
}
return getCopyOf(distanceMatrix);
}
public List<EMAComponentInstanceSymbol> getSubcompsOrderedByName(){
if(!initSubcomposOrderedByName){
initSubcomposOrderedByName = true;
subcompsOrderedByName = ComponentHelper.getSubcompsOrderedByName(instanceSymbol);
}
return new ArrayList<>(subcompsOrderedByName);
}
public Map<String, Integer> getLabelsForSubcomps(){
if(!initLabelsForSubcomps){
initLabelsForSubcomps = true;
labelsForSubcomps = ComponentHelper.getLabelsForSubcomps(subcompsOrderedByName);
}
return new HashMap<>(labelsForSubcomps);
}
private double[][] getCopyOf(double[][] old){
double[][] res = new double[old.length][old[0].length];
for (int i = 0; i < old.length; i++) {
if (old[i].length >= 0) System.arraycopy(old[i], 0, res[i], 0, old[i].length);
}
return res;
}
}
......@@ -22,16 +22,16 @@ import java.util.Set;
public class ClusteringResult {
Double score = null;
private EMAComponentInstanceSymbol component;
private ClusteringInput clusteringInput;
private AlgorithmCliParameters parameters;
private List<Set<EMAComponentInstanceSymbol>> clustering;
private long duration;
private int componentNumber;
private boolean valid;
private ClusteringResult(EMAComponentInstanceSymbol component, AlgorithmCliParameters parameters,
private ClusteringResult(ClusteringInput clusteringInput, AlgorithmCliParameters parameters,
List<Set<EMAComponentInstanceSymbol>> clustering, long duration, int componentNumber, boolean valid) {
this.component = component;
this.clusteringInput = clusteringInput;
this.parameters = parameters;
this.clustering = clustering;
this.duration = duration;
......@@ -39,15 +39,15 @@ public class ClusteringResult {
this.valid = valid;
}
public static ClusteringResult fromParameters(EMAComponentInstanceSymbol component, AlgorithmCliParameters parameters) {
public static ClusteringResult fromParameters(ClusteringInput clusteringInput, AlgorithmCliParameters parameters) {
List<Set<EMAComponentInstanceSymbol>> res;
long startTime = System.currentTimeMillis();
try {
res = parameters.asClusteringAlgorithm().clusterWithState(component);
res = parameters.asClusteringAlgorithm().clusterWithState(clusteringInput);
} catch (Exception e) {
Log.warn("Marking this result as invalid. Error clustering the component.", e);
return new ClusteringResult(component, parameters, new ArrayList<>(), -1, component.getSubComponents().size(), false);
return new ClusteringResult(clusteringInput, parameters, new ArrayList<>(), -1, clusteringInput.getComponent().getSubComponents().size(), false);
}
long endTime = System.currentTimeMillis();
......@@ -69,18 +69,22 @@ public class ClusteringResult {
for (Set<EMAComponentInstanceSymbol> cluster : res) {
componentNumber += cluster.size();
}
return new ClusteringResult(component, parameters, res, endTime - startTime, componentNumber, curValid);
return new ClusteringResult(clusteringInput, parameters, res, endTime - startTime, componentNumber, curValid);
}
public double getScore(){
if(score == null){
score = AutomaticClusteringHelper.getTypeCostHeuristic(component, clustering);
score = AutomaticClusteringHelper.getTypeCostHeuristic(clusteringInput.getComponent(), clustering);
}
return score;
}
public EMAComponentInstanceSymbol getComponent() {
return component;
return clusteringInput.getComponent();
}
public ClusteringInput getClusteringInput() {
return clusteringInput;
}
public AlgorithmCliParameters getParameters() {
......@@ -115,15 +119,15 @@ public class ClusteringResult {
"//Score: " + this.getScore() + "\n" +
"//Durration in ms: " + this.getDuration() + "\n";
String content = MiddlewareTagGenImpl.getFileContent(component, this.clustering);
String content = MiddlewareTagGenImpl.getFileContent(clusteringInput.getComponent(), this.clustering);
res.setFileContent(prefix + content);
return res;
}
//TODO: refactor to File?
public void saveVisualization(String path, String fileName){
Graph g = ModelVisualizer.buildGraph(component, parameters.toString());
ModelVisualizer.visualizeClustering(g, clustering, component);
Graph g = ModelVisualizer.buildGraph(clusteringInput.getComponent(), parameters.toString());
ModelVisualizer.visualizeClustering(g, clustering, clusteringInput.getComponent());
ModelVisualizer.saveGraphAsImage(g, path, fileName);
}
......
package de.monticore.lang.monticar.generator.middleware.clustering;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.monticar.generator.FileContent;
import de.monticore.lang.monticar.generator.middleware.cli.algorithms.AlgorithmCliParameters;
import de.se_rwth.commons.logging.Log;
import java.util.ArrayList;
......@@ -14,6 +16,24 @@ public class ClusteringResultList extends ArrayList<ClusteringResult> {
super();
}
public static ClusteringResultList fromParametersList(EMAComponentInstanceSymbol emaComponentInstance, List<AlgorithmCliParameters> algoParams) {
ClusteringResultList res = new ClusteringResultList();
ClusteringInput clusteringInput = new ClusteringInput(emaComponentInstance);
//create AdjacencyMatrix to make execution speed comparision fairer
clusteringInput.getAdjacencyMatrix();
for (int i = 0; i < algoParams.size(); i++) {
System.out.println("Clustering with algorithm " + (i + 1) + "/" + algoParams.size() + ": " + algoParams.get(i).toString());
ClusteringResult result = ClusteringResult.fromParameters(clusteringInput, algoParams.get(i));
if (result.isValid()) {
res.add(result);
} else {
Log.warn("Ignoring the result! It is invalid!");
}
}
return res;
}
public Optional<ClusteringResult> getBestResultWithFittingN(int n){
ClusteringResultList filteredList = new ClusteringResultList();
for(ClusteringResult c : this){
......
......@@ -3,13 +3,15 @@ package de.monticore.lang.monticar.generator.middleware.clustering.algorithms;
import com.clust4j.algo.AffinityPropagation;
import com.clust4j.algo.AffinityPropagationParameters;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.monticar.generator.middleware.clustering.AutomaticClusteringHelper;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.helpers.ComponentHelper;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringInput;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.RealMatrix;
import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class AffinityPropagationAlgorithm implements ClusteringAlgorithm {
......@@ -25,15 +27,9 @@ public class AffinityPropagationAlgorithm implements ClusteringAlgorithm {
}
@Override
public List<Set<EMAComponentInstanceSymbol>> cluster(EMAComponentInstanceSymbol component, Object... args) {
public List<Set<EMAComponentInstanceSymbol>> cluster(ClusteringInput clusteringInput, Object... args) {
List<EMAComponentInstanceSymbol> subcompsOrderedByName = ComponentHelper.getSubcompsOrderedByName(component);
Map<String, Integer> labelsForSubcomps = ComponentHelper.getLabelsForSubcomps(subcompsOrderedByName);
double[][] adjMatrix = AutomaticClusteringHelper.guaranteedConnectedAdjacencyMatrix(subcompsOrderedByName,
ComponentHelper.getInnerConnectors(component),
labelsForSubcomps);
RealMatrix mat = new Array2DRowRealMatrix(adjMatrix);
RealMatrix mat = new Array2DRowRealMatrix(clusteringInput.getAdjacencyMatrix());
AffinityPropagation clustering = new AffinityPropagationParameters().fitNewModel(mat);
final int[] labels = clustering.getLabels();
......@@ -45,8 +41,8 @@ public class AffinityPropagationAlgorithm implements ClusteringAlgorithm {
res.add(new HashSet<>());
}
subcompsOrderedByName.forEach(sc -> {
int curClusterLabel = labels[labelsForSubcomps.get(sc.getFullName())];
clusteringInput.getSubcompsOrderedByName().forEach(sc -> {
int curClusterLabel = labels[clusteringInput.getLabelsForSubcomps().get(sc.getFullName())];
res.get(curClusterLabel).add(sc);
});
......
package de.monticore.lang.monticar.generator.middleware.clustering.algorithms;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.monticar.generator.middleware.clustering.AutomaticClusteringHelper;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.helpers.ComponentHelper;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringInput;
import de.se_rwth.commons.logging.Log;
import smile.clustering.DBSCAN;
......@@ -23,7 +22,7 @@ public class DBSCANClusteringAlgorithm implements ClusteringAlgorithm {
}
@Override
public List<Set<EMAComponentInstanceSymbol>> cluster(EMAComponentInstanceSymbol component, Object... args) {
public List<Set<EMAComponentInstanceSymbol>> cluster(ClusteringInput clusteringInput, Object... args) {
List<Set<EMAComponentInstanceSymbol>> res = new ArrayList<>();
......@@ -80,24 +79,19 @@ public class DBSCANClusteringAlgorithm implements ClusteringAlgorithm {
if (error) {
Log.error("DBSCANClusteringAlgorithm: Mandatory parameter(s) missing!");
} else {
List<EMAComponentInstanceSymbol> subcompsOrderedByName = ComponentHelper.getSubcompsOrderedByName(component);
Map<String, Integer> labelsForSubcomps = ComponentHelper.getLabelsForSubcomps(subcompsOrderedByName);
double[][] adjMatrix = AutomaticClusteringHelper.guaranteedConnectedAdjacencyMatrix(subcompsOrderedByName,
ComponentHelper.getInnerConnectors(component),
labelsForSubcomps);
double[][] adjMatrix = clusteringInput.getAdjacencyMatrix();
DBSCAN clustering;
DBSCANClusteringBuilder builder = new DBSCANClusteringBuilder(adjMatrix, minPts, radius);
clustering = builder.build();
clustering = builder.build();
int[] labels = clustering.getClusterLabel();
for (int i = 0; i < clustering.getNumClusters(); i++) {
res.add(new HashSet<>());
}
subcompsOrderedByName.forEach(sc -> {
int curClusterLabel = labels[labelsForSubcomps.get(sc.getFullName())];
clusteringInput.getSubcompsOrderedByName().forEach(sc -> {
int curClusterLabel = labels[clusteringInput.getLabelsForSubcomps().get(sc.getFullName())];
res.get(curClusterLabel).add(sc);
});
}
......
......@@ -3,7 +3,7 @@ package de.monticore.lang.monticar.generator.middleware.clustering.algorithms;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.monticar.generator.middleware.clustering.AutomaticClusteringHelper;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.helpers.ComponentHelper;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringInput;
import de.se_rwth.commons.logging.Log;
import net.sf.javaml.clustering.mcl.SparseMatrix;
import net.sf.javaml.core.Dataset;
......@@ -78,7 +78,7 @@ public class MarkovClusteringAlgorithm implements ClusteringAlgorithm {
}
@Override
public List<Set<EMAComponentInstanceSymbol>> cluster(EMAComponentInstanceSymbol component, Object... args) {
public List<Set<EMAComponentInstanceSymbol>> cluster(ClusteringInput clusteringInput, Object... args) {
List<Set<EMAComponentInstanceSymbol>> res = new ArrayList<>();
......@@ -147,11 +147,7 @@ public class MarkovClusteringAlgorithm implements ClusteringAlgorithm {
if (error) {
Log.error("MarkovClusteringAlgorithm: Mandatory parameter(s) missing!");
} else {
List<EMAComponentInstanceSymbol> subcompsOrderedByName = ComponentHelper.getSubcompsOrderedByName(component);
Map<String, Integer> labelsForSubcomps = ComponentHelper.getLabelsForSubcomps(subcompsOrderedByName);
double[][] adjMatrix = AutomaticClusteringHelper.guaranteedConnectedAdjacencyMatrix(subcompsOrderedByName,
ComponentHelper.getInnerConnectors(component),
labelsForSubcomps);
double[][] adjMatrix = clusteringInput.getAdjacencyMatrix();
// |nodes| instances of data with one attribute denoting the node order
Dataset original_ds= new DefaultDataset();
......@@ -181,8 +177,8 @@ public class MarkovClusteringAlgorithm implements ClusteringAlgorithm {
res.add(new HashSet<>());
}
subcompsOrderedByName.forEach(sc -> {
int curClusterLabel = labels[labelsForSubcomps.get(sc.getFullName())];
clusteringInput.getSubcompsOrderedByName().forEach(sc -> {
int curClusterLabel = labels[clusteringInput.getLabelsForSubcomps().get(sc.getFullName())];
res.get(curClusterLabel).add(sc);
});
}
......
package de.monticore.lang.monticar.generator.middleware.clustering.algorithms;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.monticar.generator.middleware.clustering.AutomaticClusteringHelper;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.helpers.ComponentHelper;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringInput;
import de.se_rwth.commons.logging.Log;
import smile.clustering.SpectralClustering;
......@@ -23,7 +22,7 @@ public class SpectralClusteringAlgorithm implements ClusteringAlgorithm {
}
@Override
public List<Set<EMAComponentInstanceSymbol>> cluster(EMAComponentInstanceSymbol component, Object... args) {
public List<Set<EMAComponentInstanceSymbol>> cluster(ClusteringInput clusteringInput, Object... args) {
List<Set<EMAComponentInstanceSymbol>> res = new ArrayList<>();
......@@ -86,11 +85,7 @@ public class SpectralClusteringAlgorithm implements ClusteringAlgorithm {
if (error) {
Log.error("SpectralClusteringAlgorithm: Mandatory parameter(s) missing!");
} else {
List<EMAComponentInstanceSymbol> subcompsOrderedByName = ComponentHelper.getSubcompsOrderedByName(component);
Map<String, Integer> labelsForSubcomps = ComponentHelper.getLabelsForSubcomps(subcompsOrderedByName);
double[][] adjMatrix = AutomaticClusteringHelper.guaranteedConnectedAdjacencyMatrix(subcompsOrderedByName,
ComponentHelper.getInnerConnectors(component),
labelsForSubcomps);
double[][] adjMatrix = clusteringInput.getAdjacencyMatrix();
SpectralClustering clustering;
SpectralClusteringBuilder builder = new SpectralClusteringBuilder(adjMatrix, numClusters);
......@@ -104,8 +99,8 @@ public class SpectralClusteringAlgorithm implements ClusteringAlgorithm {
res.add(new HashSet<>());
}
subcompsOrderedByName.forEach(sc -> {
int curClusterLabel = labels[labelsForSubcomps.get(sc.getFullName())];
clusteringInput.getSubcompsOrderedByName().forEach(sc -> {
int curClusterLabel = labels[clusteringInput.getLabelsForSubcomps().get(sc.getFullName())];
res.get(curClusterLabel).add(sc);
});
}
......
......@@ -49,7 +49,7 @@ public class AutomaticClusteringTest extends AbstractSymtabTest{
SpectralClusteringAlgorithm clusteringAlgorithm = new SpectralClusteringAlgorithm();
Object[] params = new Object[]{SpectralClusteringBuilder.SpectralParameters.SPECTRAL_NUM_CLUSTERS, 2};
List<Set<EMAComponentInstanceSymbol>> clusters = clusteringAlgorithm.cluster(flattendComponent, params);
List<Set<EMAComponentInstanceSymbol>> clusters = clusteringAlgorithm.cluster(new ClusteringInput(flattendComponent), params);
AutomaticClusteringHelper.annotateComponentWithRosTagsForClusters(flattendComponent, clusters);
......@@ -570,8 +570,12 @@ public class AutomaticClusteringTest extends AbstractSymtabTest{
assertNotNull(componentInstanceSymbol);
List<Set<EMAComponentInstanceSymbol>> clusters = null;
if (params != null) clusters = algorithm.cluster(componentInstanceSymbol, params); else
clusters = algorithm.cluster(componentInstanceSymbol);
ClusteringInput clusteringInput = new ClusteringInput(componentInstanceSymbol);
if (params != null){
clusters = algorithm.cluster(clusteringInput, params);
}else{
clusters = algorithm.cluster(clusteringInput);
}
Graph graph = ModelVisualizer.buildGraph(componentInstanceSymbol, algoNameShort);
ModelVisualizer.visualizeClustering(graph, clusters, componentInstanceSymbol);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment