Commit bae5af96 authored by Michael Günther Beyer's avatar Michael Günther Beyer
Browse files

params for clustering algorithms: more generic

parent c809f54a
Pipeline #89798 passed with stages
in 10 minutes and 42 seconds
...@@ -7,5 +7,5 @@ import java.util.Set; ...@@ -7,5 +7,5 @@ import java.util.Set;
// product if for clustering factory // product if for clustering factory
public interface ClusteringAlgorithm { public interface ClusteringAlgorithm {
public List<Set<ExpandedComponentInstanceSymbol>> cluster(ExpandedComponentInstanceSymbol component, int numClusters, Object... args); public List<Set<ExpandedComponentInstanceSymbol>> cluster(ExpandedComponentInstanceSymbol component, Object... args);
} }
...@@ -4,6 +4,7 @@ import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.Expanded ...@@ -4,6 +4,7 @@ import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.Expanded
import de.monticore.lang.monticar.generator.middleware.clustering.AutomaticClusteringHelper; 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.clustering.ClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.helpers.ComponentHelper; import de.monticore.lang.monticar.generator.middleware.helpers.ComponentHelper;
import de.se_rwth.commons.logging.Log;
import smile.clustering.SpectralClustering; import smile.clustering.SpectralClustering;
import java.util.*; import java.util.*;
...@@ -11,60 +12,92 @@ import java.util.*; ...@@ -11,60 +12,92 @@ import java.util.*;
// spectral clusterer product implementation // spectral clusterer product implementation
public class SpectralClusteringAlgorithm implements ClusteringAlgorithm { public class SpectralClusteringAlgorithm implements ClusteringAlgorithm {
@Override @Override
public List<Set<ExpandedComponentInstanceSymbol>> cluster(ExpandedComponentInstanceSymbol component, int numClusters, Object... args) { public List<Set<ExpandedComponentInstanceSymbol>> cluster(ExpandedComponentInstanceSymbol component, Object... args) {
List<ExpandedComponentInstanceSymbol> subcompsOrderedByName = ComponentHelper.getSubcompsOrderedByName(component); List<Set<ExpandedComponentInstanceSymbol>> res = new ArrayList<>();
Map<String, Integer> labelsForSubcomps = ComponentHelper.getLabelsForSubcomps(subcompsOrderedByName);
double[][] adjMatrix = AutomaticClusteringHelper.createAdjacencyMatrix(subcompsOrderedByName, // params
ComponentHelper.getInnerConnectors(component), Integer numClusters= null;
labelsForSubcomps); Integer l= null;
Double sigma= null;
SpectralClustering clustering; // find mandatory params
SpectralClusteringBuilder builder = new SpectralClusteringBuilder(adjMatrix, numClusters); Map<SpectralClusteringBuilder.SpectralParameters, Boolean> mandatoryParams = new HashMap<SpectralClusteringBuilder.SpectralParameters, Boolean>();
SpectralClusteringBuilder.SpectralParameters[] spectralParams = SpectralClusteringBuilder.SpectralParameters.values();
for (SpectralClusteringBuilder.SpectralParameters param : spectralParams) {
// set all mandatory params to "unset"
if (param.isMandatory()) mandatoryParams.put(param, false);
}
// Handle optional additional params for SpectralClustering. // Handle (optional) params for SpectralClustering.
// Additional params come as one or multiple key-value-pairs in the optional varargs array for this method, // Params come as one or multiple key-value-pairs in the optional varargs array for this method,
// with key as a string (containing the name of the parameter to pass thru to the spectral clusterer) followed by its value as an object // with key as a string (containing the name of the parameter to pass thru to the spectral clusterer) followed by its value as an object
String key; SpectralClusteringBuilder.SpectralParameters key;
Object value; Object value;
int v = 0; int v = 0;
while (v < args.length) { while (v < args.length) {
if (args[v] instanceof String) { if (args[v] instanceof SpectralClusteringBuilder.SpectralParameters) {
key = (String)args[v]; key = (SpectralClusteringBuilder.SpectralParameters)args[v];
if (v+1 < args.length) { if (v+1 < args.length) {
value = args[v + 1]; value = args[v + 1];
switch (key) { switch (key) {
case "l": case SPECTRAL_NUM_CLUSTERS:
if (value instanceof Integer) {
numClusters= (Integer) value;
}
break;
case SPECTRAL_L:
if (value instanceof Integer) { if (value instanceof Integer) {
builder.setL((Integer) value); l= (Integer) value;
} }
break; break;
case "sigma": case SPECTRAL_SIGMA:
if (value instanceof Double) { if (value instanceof Double) {
builder.setSigma((Double) value); sigma= (Double) value;
} }
break; break;
} }
// set mandatory param to "set"
if (key.isMandatory()) mandatoryParams.replace(key, true);
} }
} }
v = v + 2; v = v + 2;
} }
clustering = builder.build(); // are all mandatory params set?
//SpectralClustering clustering = new SpectralClustering(adjMatrix,numberOfClusters); boolean error= false;
Iterator iterator = mandatoryParams.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry param = (Map.Entry) iterator.next();
if (!(Boolean)param.getValue()) error= true;
}
int[] labels = clustering.getClusterLabel(); if (error) {
Log.error("SpectralClusteringAlgorithm: Mandatory parameter(s) missing!");
} else {
List<ExpandedComponentInstanceSymbol> subcompsOrderedByName = ComponentHelper.getSubcompsOrderedByName(component);
Map<String, Integer> labelsForSubcomps = ComponentHelper.getLabelsForSubcomps(subcompsOrderedByName);
double[][] adjMatrix = AutomaticClusteringHelper.createAdjacencyMatrix(subcompsOrderedByName,
ComponentHelper.getInnerConnectors(component),
labelsForSubcomps);
List<Set<ExpandedComponentInstanceSymbol>> res = new ArrayList<>(); SpectralClustering clustering;
SpectralClusteringBuilder builder = new SpectralClusteringBuilder(adjMatrix, numClusters);
if (l != null) builder.setL(l);
if (sigma != null) builder.setSigma(sigma);
clustering = builder.build();
for(int i = 0; i < clustering.getNumClusters(); i++){ int[] labels = clustering.getClusterLabel();
res.add(new HashSet<>());
}
subcompsOrderedByName.forEach(sc -> { for (int i = 0; i < clustering.getNumClusters(); i++) {
int curClusterLabel = labels[labelsForSubcomps.get(sc.getFullName())]; res.add(new HashSet<>());
res.get(curClusterLabel).add(sc); }
});
subcompsOrderedByName.forEach(sc -> {
int curClusterLabel = labels[labelsForSubcomps.get(sc.getFullName())];
res.get(curClusterLabel).add(sc);
});
}
return res; return res;
} }
......
...@@ -9,6 +9,22 @@ public class SpectralClusteringBuilder { ...@@ -9,6 +9,22 @@ public class SpectralClusteringBuilder {
private Integer l; private Integer l;
private Double sigma; private Double sigma;
// parameter list, true if mandatory
public enum SpectralParameters {
SPECTRAL_NUM_CLUSTERS(true),
SPECTRAL_L(false),
SPECTRAL_SIGMA(false);
private Boolean mandatory;
SpectralParameters(Boolean mandatory) {
this.mandatory = mandatory;
}
public Boolean isMandatory() {
return this.mandatory;
}
}
public SpectralClusteringBuilder(double[][] data, int k) { public SpectralClusteringBuilder(double[][] data, int k) {
this.data = data; this.data = data;
......
...@@ -6,6 +6,7 @@ import de.monticore.lang.monticar.generator.middleware.clustering.AutomaticClust ...@@ -6,6 +6,7 @@ import de.monticore.lang.monticar.generator.middleware.clustering.AutomaticClust
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringAlgorithm; import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringAlgorithmFactory; import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringAlgorithmFactory;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringKind; import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringKind;
import de.monticore.lang.monticar.generator.middleware.clustering.algorithms.SpectralClusteringBuilder;
import de.monticore.lang.monticar.generator.middleware.helpers.ComponentHelper; import de.monticore.lang.monticar.generator.middleware.helpers.ComponentHelper;
import de.monticore.lang.monticar.generator.middleware.impls.CPPGenImpl; import de.monticore.lang.monticar.generator.middleware.impls.CPPGenImpl;
import de.monticore.lang.monticar.generator.middleware.impls.RosCppGenImpl; import de.monticore.lang.monticar.generator.middleware.impls.RosCppGenImpl;
...@@ -105,7 +106,7 @@ public class AutomaticClusteringTest extends AbstractSymtabTest{ ...@@ -105,7 +106,7 @@ public class AutomaticClusteringTest extends AbstractSymtabTest{
System.out.println(algorithm); System.out.println(algorithm);
List<Set<ExpandedComponentInstanceSymbol>> clusters = algorithm.cluster(componentInstanceSymbol, 2); List<Set<ExpandedComponentInstanceSymbol>> clusters = algorithm.cluster(componentInstanceSymbol, SpectralClusteringBuilder.SpectralParameters.SPECTRAL_NUM_CLUSTERS, 2);
assertTrue(clusters.size() == 2); assertTrue(clusters.size() == 2);
......
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