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;
// product if for clustering factory
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
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.se_rwth.commons.logging.Log;
import smile.clustering.SpectralClustering;
import java.util.*;
......@@ -11,60 +12,92 @@ import java.util.*;
// spectral clusterer product implementation
public class SpectralClusteringAlgorithm implements ClusteringAlgorithm {
@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);
Map<String, Integer> labelsForSubcomps = ComponentHelper.getLabelsForSubcomps(subcompsOrderedByName);
double[][] adjMatrix = AutomaticClusteringHelper.createAdjacencyMatrix(subcompsOrderedByName,
ComponentHelper.getInnerConnectors(component),
labelsForSubcomps);
List<Set<ExpandedComponentInstanceSymbol>> res = new ArrayList<>();
// params
Integer numClusters= null;
Integer l= null;
Double sigma= null;
SpectralClustering clustering;
SpectralClusteringBuilder builder = new SpectralClusteringBuilder(adjMatrix, numClusters);
// find mandatory params
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.
// Additional params come as one or multiple key-value-pairs in the optional varargs array for this method,
// Handle (optional) params for SpectralClustering.
// 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
String key;
SpectralClusteringBuilder.SpectralParameters key;
Object value;
int v = 0;
while (v < args.length) {
if (args[v] instanceof String) {
key = (String)args[v];
if (args[v] instanceof SpectralClusteringBuilder.SpectralParameters) {
key = (SpectralClusteringBuilder.SpectralParameters)args[v];
if (v+1 < args.length) {
value = args[v + 1];
switch (key) {
case "l":
case SPECTRAL_NUM_CLUSTERS:
if (value instanceof Integer) {
numClusters= (Integer) value;
}
break;
case SPECTRAL_L:
if (value instanceof Integer) {
builder.setL((Integer) value);
l= (Integer) value;
}
break;
case "sigma":
case SPECTRAL_SIGMA:
if (value instanceof Double) {
builder.setSigma((Double) value);
sigma= (Double) value;
}
break;
}
// set mandatory param to "set"
if (key.isMandatory()) mandatoryParams.replace(key, true);
}
}
v = v + 2;
}
clustering = builder.build();
//SpectralClustering clustering = new SpectralClustering(adjMatrix,numberOfClusters);
// are all mandatory params set?
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++){
res.add(new HashSet<>());
}
int[] labels = clustering.getClusterLabel();
subcompsOrderedByName.forEach(sc -> {
int curClusterLabel = labels[labelsForSubcomps.get(sc.getFullName())];
res.get(curClusterLabel).add(sc);
});
for (int i = 0; i < clustering.getNumClusters(); i++) {
res.add(new HashSet<>());
}
subcompsOrderedByName.forEach(sc -> {
int curClusterLabel = labels[labelsForSubcomps.get(sc.getFullName())];
res.get(curClusterLabel).add(sc);
});
}
return res;
}
......
......@@ -9,6 +9,22 @@ public class SpectralClusteringBuilder {
private Integer l;
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) {
this.data = data;
......
......@@ -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.ClusteringAlgorithmFactory;
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.impls.CPPGenImpl;
import de.monticore.lang.monticar.generator.middleware.impls.RosCppGenImpl;
......@@ -105,7 +106,7 @@ public class AutomaticClusteringTest extends AbstractSymtabTest{
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);
......
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