aboutsummaryrefslogtreecommitdiffstats
path: root/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic
diff options
context:
space:
mode:
authorLibravatar 20001LastOrder <boqi.chen@mail.mcgill.ca>2019-07-10 10:56:00 -0400
committerLibravatar 20001LastOrder <boqi.chen@mail.mcgill.ca>2019-07-10 10:56:00 -0400
commit991dacefdb8f78fccc359d3d2ec836dc2e7fc80a (patch)
tree6b18aa59c5f711a845aa9e3e5cf3fd3632ad7a33 /Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic
parentadd sample domain for measuring realistic metrics (diff)
downloadVIATRA-Generator-991dacefdb8f78fccc359d3d2ec836dc2e7fc80a.tar.gz
VIATRA-Generator-991dacefdb8f78fccc359d3d2ec836dc2e7fc80a.tar.zst
VIATRA-Generator-991dacefdb8f78fccc359d3d2ec836dc2e7fc80a.zip
measurements for the different violation types, comparison for differenct generation config
Diffstat (limited to 'Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic')
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend2
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend42
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/CostDistance.xtend20
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/EuclideanDistance.xtend73
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/JSDistance.xtend19
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend69
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/EMFGraph.xtend11
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/Graph.xtend20
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend42
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/PartialInterpretationGraph.xtend27
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend19
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend76
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/EdgeTypeMetric.xtend41
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/Metric.xtend2
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MetricSampleGroup.xtend4
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/NodeTypeMetric.xtend44
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/TypedOutDegree.xtend60
17 files changed, 432 insertions, 139 deletions
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend
index 1745bc35..58ac7aea 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend
@@ -35,7 +35,7 @@ class Main {
35 35
36 //human input has different package declaration 36 //human input has different package declaration
37// reader = new GraphReader(Yakindumm2PackageImpl.eINSTANCE); 37// reader = new GraphReader(Yakindumm2PackageImpl.eINSTANCE);
38 val human = new RWInformation("inputs/Fake_Random_Random/", "outputs/", 1); 38 val human = new RWInformation("inputs/config7/", "outputs/", 1);
39 calculateAllModels(human.inputFolder, human.outputFolder,human.numRuns, reader); 39 calculateAllModels(human.inputFolder, human.outputFolder,human.numRuns, reader);
40 40
41 41
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend
index 45986ecf..cdce185a 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend
@@ -1,5 +1,6 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app 1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app
2 2
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.EuclideanDistance
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.JSDistance 4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.JSDistance
4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.KSDistance 5import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.KSDistance
5import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.StateData 6import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.StateData
@@ -8,6 +9,7 @@ import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric
8import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric 9import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric
9import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric 10import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric
10import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric 11import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric
12import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.TypedOutDegree
11import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.predictor.LinearModel 13import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.predictor.LinearModel
12import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 14import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
13import java.util.ArrayList 15import java.util.ArrayList
@@ -21,6 +23,7 @@ class PartialInterpretationMetricDistance {
21 23
22 var KSDistance ks; 24 var KSDistance ks;
23 var JSDistance js; 25 var JSDistance js;
26 var EuclideanDistance ed;
24 var Map<Object, StateData> stateAndHistory; 27 var Map<Object, StateData> stateAndHistory;
25 var OLSMultipleLinearRegression regression; 28 var OLSMultipleLinearRegression regression;
26 List<StateData> samples; 29 List<StateData> samples;
@@ -32,6 +35,7 @@ class PartialInterpretationMetricDistance {
32 new(){ 35 new(){
33 ks = new KSDistance(Domain.Yakinduum); 36 ks = new KSDistance(Domain.Yakinduum);
34 js = new JSDistance(Domain.Yakinduum); 37 js = new JSDistance(Domain.Yakinduum);
38 ed = new EuclideanDistance(Domain.Yakinduum);
35 regression = new OLSMultipleLinearRegression(); 39 regression = new OLSMultipleLinearRegression();
36 regression.noIntercept = false; 40 regression.noIntercept = false;
37 stateAndHistory = new HashMap<Object, StateData>(); 41 stateAndHistory = new HashMap<Object, StateData>();
@@ -44,6 +48,7 @@ class PartialInterpretationMetricDistance {
44 metrics.add(new OutDegreeMetric()); 48 metrics.add(new OutDegreeMetric());
45 metrics.add(new NodeActivityMetric()); 49 metrics.add(new NodeActivityMetric());
46 metrics.add(new MultiplexParticipationCoefficientMetric()); 50 metrics.add(new MultiplexParticipationCoefficientMetric());
51 metrics.add(new TypedOutDegree());
47 52
48 val metricCalculator = new PartialInterpretationGraph(partial, metrics, null); 53 val metricCalculator = new PartialInterpretationGraph(partial, metrics, null);
49 var metricSamples = metricCalculator.evaluateAllMetricsToSamples(); 54 var metricSamples = metricCalculator.evaluateAllMetricsToSamples();
@@ -51,6 +56,24 @@ class PartialInterpretationMetricDistance {
51 var mpc = ks.mpcDistance(metricSamples.mpcSamples); 56 var mpc = ks.mpcDistance(metricSamples.mpcSamples);
52 var na = ks.naDistance(metricSamples.naSamples); 57 var na = ks.naDistance(metricSamples.naSamples);
53 var outDegree = ks.outDegreeDistance(metricSamples.outDegreeSamples); 58 var outDegree = ks.outDegreeDistance(metricSamples.outDegreeSamples);
59 var typedOutDegree = ks.typedOutDegreeDistance(metricSamples.typedOutDegreeSamples);
60
61 return new MetricDistanceGroup(mpc, na, outDegree, typedOutDegree);
62 }
63
64 def MetricDistanceGroup calculateMetricEuclidean(PartialInterpretation partial){
65 val metrics = new ArrayList<Metric>();
66 metrics.add(new OutDegreeMetric());
67 metrics.add(new NodeActivityMetric());
68 metrics.add(new MultiplexParticipationCoefficientMetric());
69 metrics.add(new TypedOutDegree());
70
71 val metricCalculator = new PartialInterpretationGraph(partial, metrics, null);
72 var metricSamples = metricCalculator.evaluateAllMetricsToSamples();
73
74 var mpc = ed.mpcDistance(metricSamples.mpcSamples);
75 var na = ed.naDistance(metricSamples.naSamples);
76 var outDegree = ed.outDegreeDistance(metricSamples.outDegreeSamples);
54 77
55 return new MetricDistanceGroup(mpc, na, outDegree); 78 return new MetricDistanceGroup(mpc, na, outDegree);
56 } 79 }
@@ -132,14 +155,13 @@ class PartialInterpretationMetricDistance {
132 } 155 }
133 156
134 def double[] calculateFeature(int step, int violations){ 157 def double[] calculateFeature(int step, int violations){
135 var features = newDoubleArrayOfSize(5); 158 var features = newDoubleArrayOfSize(2);
136 //constant term 159 //constant term
137 features.set(0, 1); 160 features.set(0, 1);
138 161
139 features.set(1, 1.0 / step); 162 features.set(1, 1.0 / step);
140 features.set(2, violations); 163// features.set(2, violations);
141 features.set(3, Math.pow(violations, 2)); 164// features.set(3, Math.pow(violations, 2));
142 features.set(4, Math.pow(violations, 0.5));
143 165
144 return features; 166 return features;
145 } 167 }
@@ -149,6 +171,14 @@ class MetricDistanceGroup{
149 var double mpcDistance; 171 var double mpcDistance;
150 var double naDistance; 172 var double naDistance;
151 var double outDegreeDistance; 173 var double outDegreeDistance;
174 var double typedOutDegreeDistance;
175
176 new(double mpcDistance, double naDistance, double outDegreeDistance, double typedOutDegreeDistance){
177 this.mpcDistance = mpcDistance;
178 this.naDistance = naDistance;
179 this.outDegreeDistance = outDegreeDistance;
180 this.typedOutDegreeDistance = typedOutDegreeDistance;
181 }
152 182
153 new(double mpcDistance, double naDistance, double outDegreeDistance){ 183 new(double mpcDistance, double naDistance, double outDegreeDistance){
154 this.mpcDistance = mpcDistance; 184 this.mpcDistance = mpcDistance;
@@ -156,6 +186,10 @@ class MetricDistanceGroup{
156 this.outDegreeDistance = outDegreeDistance; 186 this.outDegreeDistance = outDegreeDistance;
157 } 187 }
158 188
189 def double getTypedOutDegreeDistance(){
190 return this.typedOutDegreeDistance;
191 }
192
159 def double getMPCDistance(){ 193 def double getMPCDistance(){
160 return this.mpcDistance 194 return this.mpcDistance
161 } 195 }
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/CostDistance.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/CostDistance.xtend
index 33d10fa3..613f0f43 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/CostDistance.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/CostDistance.xtend
@@ -1,9 +1,25 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance 1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance
2 2
3import java.text.DecimalFormat
4import java.util.HashMap
5import java.util.List
3import org.eclipse.xtend.lib.annotations.Accessors 6import org.eclipse.xtend.lib.annotations.Accessors
4 7
5class CostDistance { 8abstract class CostDistance {
6 9 def abstract double naDistance(List<Double> samples);
10 def abstract double mpcDistance(List<Double> samples);
11 def abstract double outDegreeDistance(List<Double> samples);
12
13 def protected pmfFromSamples(double[] samples, DecimalFormat formatter){
14 var length = samples.length;
15 var pmfMap = new HashMap<String, Double>();
16
17 for(sample : samples){
18 pmfMap.put(formatter.format(sample), pmfMap.getOrDefault(formatter.format(sample), 0.0) + 1.0 / length);
19 }
20
21 return pmfMap;
22 }
7} 23}
8 24
9class StateData{ 25class StateData{
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/EuclideanDistance.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/EuclideanDistance.xtend
new file mode 100644
index 00000000..b945d97b
--- /dev/null
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/EuclideanDistance.xtend
@@ -0,0 +1,73 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance
2
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain
4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.RepMetricsReader
5import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup
6import com.google.common.collect.Sets
7import java.text.DecimalFormat
8import java.util.ArrayList
9import java.util.HashMap
10import java.util.List
11import java.util.Map
12import java.util.Set
13
14class EuclideanDistance extends CostDistance{
15 var MetricSampleGroup g;
16 var HashMap<String, Double> mpcPMF;
17 var HashMap<String, Double> naPMF;
18 var HashMap<String, Double> outDegreePMF;
19 var DecimalFormat formatter;
20
21 new(Domain d){
22 var metrics = RepMetricsReader.read(d);
23 this.g = metrics;
24
25 var mpcSamples = metrics.mpcSamples;
26 var naSamples = metrics.naSamples.stream.mapToDouble([it]).toArray();
27 var outDegreeSamples = metrics.outDegreeSamples.stream.mapToDouble([it]).toArray();
28
29 //needs to format the number to string avoid precision issue
30 formatter = new DecimalFormat("#0.00000");
31
32 mpcPMF = pmfFromSamples(mpcSamples, formatter);
33 naPMF = pmfFromSamples(naSamples, formatter);
34 outDegreePMF = pmfFromSamples(outDegreeSamples, formatter);
35 }
36
37 override naDistance(List<Double> samples) {
38 var pmfMap = pmfFromSamples(samples, formatter);
39 return euclideanDistance(pmfMap, naPMF);
40 }
41
42 override mpcDistance(List<Double> samples) {
43 var pmfMap = pmfFromSamples(samples, formatter);
44 return euclideanDistance(pmfMap, mpcPMF);
45 }
46
47 override outDegreeDistance(List<Double> samples) {
48 var pmfMap = pmfFromSamples(samples, formatter);
49 return euclideanDistance(pmfMap, outDegreePMF);
50 }
51
52
53 def private euclideanDistance(HashMap<String, Double> pmf1, HashMap<String, Double> pmf2){
54 var keys = Sets.union(pmf1.keySet(), pmf2.keySet());
55 var pmfList1 = pmfMapToList(pmf1, keys);
56 var pmfList2 = pmfMapToList(pmf2, keys);
57 var distance = 0.0;
58 for(var i = 0; i < pmfList1.size(); i++){
59 distance += Math.pow(pmfList1.get(i) + pmfList2.get(i), 2);
60 }
61
62 return Math.sqrt(distance);
63 }
64
65 def private pmfMapToList(Map<String, Double> map, Set<String> keys){
66 var list = new ArrayList<Double>();
67 for(key : keys){
68 var value = map.getOrDefault(key, 0.0);
69 list.add(value);
70 }
71 return list;
72 }
73} \ No newline at end of file
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/JSDistance.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/JSDistance.xtend
index ced9eadb..df65b81f 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/JSDistance.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/JSDistance.xtend
@@ -7,7 +7,7 @@ import java.text.DecimalFormat
7import java.util.HashMap 7import java.util.HashMap
8import java.util.List 8import java.util.List
9 9
10class JSDistance { 10class JSDistance extends CostDistance {
11 var HashMap<String, Double> mpcPMF; 11 var HashMap<String, Double> mpcPMF;
12 var HashMap<String, Double> naPMF; 12 var HashMap<String, Double> naPMF;
13 var HashMap<String, Double> outDegreePMF; 13 var HashMap<String, Double> outDegreePMF;
@@ -27,17 +27,6 @@ class JSDistance {
27 outDegreePMF = pmfFromSamples(outDegreeSamples, formatter); 27 outDegreePMF = pmfFromSamples(outDegreeSamples, formatter);
28 } 28 }
29 29
30 def private pmfFromSamples(double[] samples, DecimalFormat formatter){
31 var length = samples.length;
32 var pmfMap = new HashMap<String, Double>();
33
34 for(sample : samples){
35 pmfMap.put(formatter.format(sample), pmfMap.getOrDefault(formatter.format(sample), 0.0) + 1.0 / length);
36 }
37
38 return pmfMap;
39 }
40
41 def private combinePMF(HashMap<String, Double> pmf1, HashMap<String, Double> pmf2){ 30 def private combinePMF(HashMap<String, Double> pmf1, HashMap<String, Double> pmf2){
42 var pmfMap = new HashMap<String, Double>(); 31 var pmfMap = new HashMap<String, Double>();
43 32
@@ -68,7 +57,7 @@ class JSDistance {
68 return distance; 57 return distance;
69 } 58 }
70 59
71 def double mpcDistance(List<Double> samples){ 60 override double mpcDistance(List<Double> samples){
72 // map list to array 61 // map list to array
73 var map = pmfFromSamples(samples.stream().mapToDouble([it]).toArray(), formatter); 62 var map = pmfFromSamples(samples.stream().mapToDouble([it]).toArray(), formatter);
74 //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1 63 //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1
@@ -76,7 +65,7 @@ class JSDistance {
76 return jsDivergence(map, mpcPMF); 65 return jsDivergence(map, mpcPMF);
77 } 66 }
78 67
79 def double naDistance(List<Double> samples){ 68 override double naDistance(List<Double> samples){
80 // map list to array 69 // map list to array
81 var map = pmfFromSamples(samples.stream().mapToDouble([it]).toArray(), formatter); 70 var map = pmfFromSamples(samples.stream().mapToDouble([it]).toArray(), formatter);
82 71
@@ -85,7 +74,7 @@ class JSDistance {
85 return jsDivergence(map, naPMF); 74 return jsDivergence(map, naPMF);
86 } 75 }
87 76
88 def double outDegreeDistance(List<Double> samples){ 77 override double outDegreeDistance(List<Double> samples){
89 // map list to array 78 // map list to array
90 var map = pmfFromSamples(samples.stream().mapToDouble([it]).toArray(), formatter); 79 var map = pmfFromSamples(samples.stream().mapToDouble([it]).toArray(), formatter);
91 //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1 80 //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend
index 58e0a8a3..86f5f23c 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend
@@ -2,46 +2,65 @@ package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance
2 2
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain 3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain
4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.RepMetricsReader 4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.RepMetricsReader
5import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup
6import java.util.HashMap
7import java.util.HashSet
5import java.util.List 8import java.util.List
9import java.util.Set
6import org.apache.commons.math3.stat.inference.KolmogorovSmirnovTest 10import org.apache.commons.math3.stat.inference.KolmogorovSmirnovTest
7 11
8class KSDistance { 12class KSDistance extends CostDistance {
9 var static ksTester = new KolmogorovSmirnovTest(); 13 var static ksTester = new KolmogorovSmirnovTest();
10 var double[] mpcSamples; 14 var MetricSampleGroup g;
11 var double[] naSamples;
12 var double[] outDegreeSamples;
13
14 new(Domain d){ 15 new(Domain d){
15 var metrics = RepMetricsReader.read(d); 16 var metrics = RepMetricsReader.read(d);
16 mpcSamples = metrics.mpcSamples; 17 this.g = metrics;
17 naSamples = metrics.naSamples.stream.mapToDouble([it]).toArray();
18 outDegreeSamples = metrics.outDegreeSamples.stream.mapToDouble([it]).toArray();
19 } 18 }
20 19
21 def double mpcDistance(List<Double> samples){ 20 override double mpcDistance(List<Double> samples){
22 // map list to array
23 var arr = samples.stream.mapToDouble([it]).toArray();
24
25 //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1 21 //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1
26 if(arr.size < 2) return 1; 22 if(samples.size < 2) return 1;
27 return ksTester.kolmogorovSmirnovStatistic(mpcSamples, arr); 23 return ksTester.kolmogorovSmirnovStatistic(g.mpcSamples, samples);
28 } 24 }
29 25
30 def double naDistance(List<Double> samples){ 26 override double naDistance(List<Double> samples){
31 // map list to array
32 var arr = samples.stream.mapToDouble([it]).toArray();
33
34 //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1 27 //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1
35 if(arr.size < 2) return 1; 28 if(samples.size < 2) return 1;
36 return ksTester.kolmogorovSmirnovStatistic(naSamples as double[], arr); 29 return ksTester.kolmogorovSmirnovStatistic(g.naSamples as double[], samples);
37 } 30 }
38 31
39 def double outDegreeDistance(List<Double> samples){ 32 override double outDegreeDistance(List<Double> samples){
33 //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1
34 if(samples.size < 2) return 1;
35 return ksTester.kolmogorovSmirnovStatistic(g.outDegreeSamples, samples);
36 }
37
38 def double typedOutDegreeDistance(HashMap<String, List<Integer>> map){
39 var value = 0.0;
40 // map list to array 40 // map list to array
41 var arr = samples.stream.mapToDouble([it]).toArray(); 41 val keySet = new HashSet<String>(map.keySet);
42 keySet.addAll(g.typedOutDegreeSamples.keySet);
43 for(key : keySet){
44 if(!map.containsKey(key) ){
45 value += 1;
46 }else if(!g.typedOutDegreeSamples.containsKey(key)){
47 value += map.get(key).size * 100;
48 }else{
49 var double[] rep = g.typedOutDegreeSamples.get(key).stream().mapToDouble([it|it]).toArray();
50 var double[] ins = map.get(key).stream().mapToDouble([it|it]).toArray();
51 if((rep.size < 2 || ins.size < 2) ){
52 if(rep.size < 2 && rep.containsAll(ins)){
53 value += 0;
54 }else{
55 value += 1;
56 }
57 }else if(rep.size >= 2 && ins.size >= 2){
58 value += ksTester.kolmogorovSmirnovStatistic(rep, ins);
59 }
60 }
61 }
42 62
43 //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1 63
44 if(arr.size < 2) return 1; 64 return value;
45 return ksTester.kolmogorovSmirnovStatistic(outDegreeSamples, arr);
46 } 65 }
47} \ No newline at end of file 66} \ No newline at end of file
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/EMFGraph.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/EMFGraph.xtend
index 5c161f4b..b4c57bd8 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/EMFGraph.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/EMFGraph.xtend
@@ -2,13 +2,14 @@ package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph
2 2
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric 3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric
4import java.util.ArrayList 4import java.util.ArrayList
5import java.util.HashSet
5import java.util.List 6import java.util.List
6import org.eclipse.emf.common.util.EList 7import org.eclipse.emf.common.util.EList
7import org.eclipse.emf.ecore.EObject 8import org.eclipse.emf.ecore.EObject
8import org.eclipse.emf.ecore.EReference 9import org.eclipse.emf.ecore.EReference
9 10
10class EMFGraph extends Graph{ 11class EMFGraph extends Graph{
11 def void init (EObject root, List<Metric> metrics, String name, List<String> referenceTypes){ 12 def void init (EObject root, List<Metric> metrics, String name, List<EReference> referenceTypes){
12 val otherContents = root.eAllContents.toList(); 13 val otherContents = root.eAllContents.toList();
13 otherContents.add(root); 14 otherContents.add(root);
14 init(otherContents, metrics, name, referenceTypes); 15 init(otherContents, metrics, name, referenceTypes);
@@ -21,13 +22,15 @@ class EMFGraph extends Graph{
21 * @param name: name of the instance model 22 * @param name: name of the instance model
22 * @param ReferenceTypes: reference types defined in the meta model 23 * @param ReferenceTypes: reference types defined in the meta model
23 */ 24 */
24 def void init(List<EObject> objects, List<Metric> metrics, String name, List<String> referenceTypes){ 25 def void init(List<EObject> objects, List<Metric> metrics, String name, List<EReference> referenceTypes){
25 objects.forEach[it| 26 objects.forEach[it|
26 statistic.addNode(it); 27 var types = new HashSet(it.eClass.EAllSuperTypes.map[it|it.name]);
28 types.add(it.eClass.name);
29 statistic.addNodeWithAllTypes(it, types);
27 ] 30 ]
28 31
29 referenceTypes.forEach[it| 32 referenceTypes.forEach[it|
30 statistic.addType(it); 33 statistic.addEdgeType(it.name);
31 ]; 34 ];
32 35
33 objects.forEach[source| 36 objects.forEach[source|
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/Graph.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/Graph.xtend
index cf4aedba..6b400b0d 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/Graph.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/Graph.xtend
@@ -2,11 +2,15 @@ package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph
2 2
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric 3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric
4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup 4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup
5import java.util.ArrayList
6import java.util.List
7import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric 5import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric
8import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric 6import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric
9import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric 7import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric
8import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.TypedOutDegree
9import java.util.ArrayList
10import java.util.HashMap
11import java.util.List
12import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeTypeMetric
13import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.EdgeTypeMetric
10 14
11abstract class Graph { 15abstract class Graph {
12 16
@@ -42,11 +46,17 @@ abstract class Graph {
42 46
43 for(metric : this.metrics){ 47 for(metric : this.metrics){
44 if(metric instanceof MultiplexParticipationCoefficientMetric){ 48 if(metric instanceof MultiplexParticipationCoefficientMetric){
45 sample.mpcSamples = metric.evaluateSamples(this.statistic); 49 sample.mpcSamples = metric.evaluateSamples(this.statistic) as ArrayList<Double>;
46 }else if(metric instanceof NodeActivityMetric){ 50 }else if(metric instanceof NodeActivityMetric){
47 sample.naSamples = metric.evaluateSamples(this.statistic); 51 sample.naSamples = metric.evaluateSamples(this.statistic) as ArrayList<Double>;
48 }else if(metric instanceof OutDegreeMetric){ 52 }else if(metric instanceof OutDegreeMetric){
49 sample.outDegreeSamples = metric.evaluateSamples(this.statistic); 53 sample.outDegreeSamples = metric.evaluateSamples(this.statistic) as ArrayList<Double>;
54 }else if(metric instanceof TypedOutDegree){
55 sample.typedOutDegreeSamples = metric.evaluateSamples(this.statistic) as HashMap<String, List<Integer>>;
56 }else if(metric instanceof NodeTypeMetric){
57 sample.nodeTypeSamples = metric.evaluateSamples(this.statistic) as HashMap<String, Double>;
58 }else if (metric instanceof EdgeTypeMetric){
59 sample.edgeTypeSamples = metric.evaluateSamples(this.statistic) as HashMap<String, Double>;
50 } 60 }
51 } 61 }
52 62
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend
index 7ed58094..9b8fd0e3 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend
@@ -5,20 +5,22 @@ import com.google.common.collect.Multimap
5import java.util.HashMap 5import java.util.HashMap
6import java.util.HashSet 6import java.util.HashSet
7import java.util.List 7import java.util.List
8import java.util.Map
9import java.util.Set
8import org.eclipse.emf.ecore.EObject 10import org.eclipse.emf.ecore.EObject
9 11
10class GraphStatistic { 12class GraphStatistic {
11 val incomingEdges = new HashMap<String, Multimap<EObject, EObject>>; 13 val incomingEdges = new HashMap<String, Multimap<EObject, EObject>>;
12 val outcomingEdges = new HashMap<String, Multimap<EObject, EObject>>; 14 val outcomingEdges = new HashMap<String, Multimap<EObject, EObject>>;
13 15
14 val edgeTypes = new HashSet<String>(); 16 val edgeTypes = new HashSet<String>();
15 val nodes = new HashSet<EObject>(); 17 val nodeToType = new HashMap<EObject, Set<String>>();
16 18
17 /** 19 /**
18 * Add an edge type to to the graph 20 * Add an edge type to to the graph
19 * @param type: type to add 21 * @param type: type to add
20 */ 22 */
21 def void addType(String type){ 23 def void addEdgeType(String type){
22 if(edgeTypes.contains(type)){ 24 if(edgeTypes.contains(type)){
23 return; 25 return;
24 } 26 }
@@ -28,15 +30,20 @@ class GraphStatistic {
28 } 30 }
29 31
30 /** 32 /**
31 * Add a node to he graph 33 * Add a node to the graph with one type in its type hierarchy
32 * @param node: node to add 34 * @param node: node to add
33 */ 35 */
34 def void addNode(EObject n){ 36 def void addNodeWithType(EObject n, String Type){
35 if(nodes.contains(n)){ 37 var types = nodeToType.getOrDefault(n, new HashSet<String>());
36 return; 38 types.add(Type);
37 } 39 nodeToType.put(n, types);
38 40 }
39 nodes.add(n); 41
42 /**
43 * Add a node to the graph with all types in its type hierarchy
44 */
45 def void addNodeWithAllTypes(EObject n, Set<String> types){
46 nodeToType.put(n, types);
40 } 47 }
41 48
42 /** 49 /**
@@ -82,7 +89,7 @@ class GraphStatistic {
82 } 89 }
83 90
84 /** 91 /**
85 * calculate the number of edge types for a given degree. 92 * calculate the number of edge types for a given node.
86 */ 93 */
87 def int numOfEdgeTypes(EObject o){ 94 def int numOfEdgeTypes(EObject o){
88 var count = 0; 95 var count = 0;
@@ -100,8 +107,17 @@ class GraphStatistic {
100 return edgeTypes.toList(); 107 return edgeTypes.toList();
101 } 108 }
102 109
110 def Map<EObject, Set<String>> getNodeToTypesMap(){
111 return nodeToType;
112 }
113
103 def List<EObject> getAllNodes(){ 114 def List<EObject> getAllNodes(){
104 return nodes.toList(); 115 return nodeToType.keySet().toList();
105 } 116 }
117
118 def HashMap<String, Multimap<EObject, EObject>> getOutgoingEdges(){
119 return outcomingEdges;
120 }
121
106} 122}
107 123
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/PartialInterpretationGraph.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/PartialInterpretationGraph.xtend
index 14337ab0..91d7c5f9 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/PartialInterpretationGraph.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/PartialInterpretationGraph.xtend
@@ -4,11 +4,13 @@ import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration 4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink 5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.BooleanElementImpl 7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialComplexTypeInterpretationImpl
8import java.util.ArrayList 8import java.util.ArrayList
9import java.util.List 9import java.util.List
10 10
11class PartialInterpretationGraph extends Graph{ 11class PartialInterpretationGraph extends Graph{
12 val typeToExclude = "undefinedpart";
13 val classSuffix = " class";
12 14
13 /** 15 /**
14 * Define a new PartialInterpretationGraph by parse every element from a PartialInterpretation 16 * Define a new PartialInterpretationGraph by parse every element from a PartialInterpretation
@@ -16,17 +18,21 @@ class PartialInterpretationGraph extends Graph{
16 new(PartialInterpretation partial, List<Metric> metrics, String name){ 18 new(PartialInterpretation partial, List<Metric> metrics, String name){
17 //the edge types are defined in terms of RelationDeclaration 19 //the edge types are defined in terms of RelationDeclaration
18 partial.problem.relations.filter(RelationDeclaration).forEach[ 20 partial.problem.relations.filter(RelationDeclaration).forEach[
19 this.statistic.addType(it.name); 21 //only need the name of the reference type (remove everything with and after "reference")
22 this.statistic.addEdgeType(it.name.split(" ").get(0));
20 ] 23 ]
21 // add all elements 24 // add all elements
22 val elements = getElements(partial); 25 val typeInterpretations = getTypes(partial);
23 for(element : elements){ 26 for(type : typeInterpretations){
24 statistic.addNode(element) 27 var typeName = type.interpretationOf.name.replace(classSuffix, '');
28 for(node : type.elements){
29 this.statistic.addNodeWithType(node, typeName);
30 }
25 } 31 }
26 32
27 for(relationInterpretation : partial.partialrelationinterpretation) { 33 for(relationInterpretation : partial.partialrelationinterpretation) {
28 val type = relationInterpretation.interpretationOf.name 34 //only need the name of the reference type (remove everything with and after "reference")
29 35 val type = relationInterpretation.interpretationOf.name.split(" ").get(0);
30 for(edge : relationInterpretation.relationlinks.filter(BinaryElementRelationLink)){ 36 for(edge : relationInterpretation.relationlinks.filter(BinaryElementRelationLink)){
31 statistic.addEdge(edge.param1, edge.param2, type); 37 statistic.addEdge(edge.param1, edge.param2, type);
32 } 38 }
@@ -62,8 +68,11 @@ class PartialInterpretationGraph extends Graph{
62 output.add(stateInfo); 68 output.add(stateInfo);
63 } 69 }
64 70
65 private def getElements(PartialInterpretation partial){ 71 private def getTypes(PartialInterpretation partial){
66 return partial.newElements.filter[!(it instanceof BooleanElementImpl)] + partial.problem.elements; 72 //only the complex type interpretations are the ones defined in meta model
73 //do not care about undefined types as it will be included in the class type
74 return partial.partialtypeinterpratation.filter(PartialComplexTypeInterpretationImpl)
75 .filter[!it.interpretationOf.name.toLowerCase.contains(typeToExclude)];
67 } 76 }
68 77
69 override getStatistic() { 78 override getStatistic() {
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend
index fc56e142..8f1feb9d 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend
@@ -17,10 +17,18 @@ import org.eclipse.emf.ecore.resource.Resource
17import org.eclipse.emf.ecore.resource.ResourceSet 17import org.eclipse.emf.ecore.resource.ResourceSet
18import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl 18import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
19import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl 19import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl
20import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeTypeMetric
21import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.EdgeTypeMetric
22import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.TypedOutDegree
23import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.YakindummPackage
20 24
21class GraphReader{ 25class GraphReader{
22 val ResourceSet resSet = new ResourceSetImpl(); 26 val ResourceSet resSet = new ResourceSetImpl();
23 val referenceTypes = new ArrayList<String>(); 27 val referenceTypes = new ArrayList<EReference>();
28
29 def static void main(String[] args){
30 var g = new GraphReader(YakindummPackage.eINSTANCE);
31 }
24 32
25 new(EPackage metaModel) { 33 new(EPackage metaModel) {
26 Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put("*",new XMIResourceFactoryImpl) 34 Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put("*",new XMIResourceFactoryImpl)
@@ -28,7 +36,7 @@ class GraphReader{
28 //find all reference types in the meta model 36 //find all reference types in the meta model
29 metaModel.eAllContents.forEach[ 37 metaModel.eAllContents.forEach[
30 if(it instanceof EReference){ 38 if(it instanceof EReference){
31 referenceTypes.add(it.name); 39 referenceTypes.add(it);
32 } 40 }
33 ] 41 ]
34 } 42 }
@@ -45,7 +53,10 @@ class GraphReader{
45 metrics.add(new OutDegreeMetric()); 53 metrics.add(new OutDegreeMetric());
46 metrics.add(new NodeActivityMetric()); 54 metrics.add(new NodeActivityMetric());
47 metrics.add(new MultiplexParticipationCoefficientMetric()); 55 metrics.add(new MultiplexParticipationCoefficientMetric());
48 56 metrics.add(new TypedOutDegree());
57 metrics.add(new NodeTypeMetric());
58 metrics.add(new EdgeTypeMetric());
59
49 //check all files in the directory with xmi 60 //check all files in the directory with xmi
50 for(String name : dir.list.filter[it| it.endsWith(".xmi")]){ 61 for(String name : dir.list.filter[it| it.endsWith(".xmi")]){
51 val file = new File(name); 62 val file = new File(name);
@@ -71,7 +82,7 @@ class GraphReader{
71 } 82 }
72 } catch(Exception e) { 83 } catch(Exception e) {
73 e.printStackTrace(); 84 e.printStackTrace();
74 throw new FileNotFoundException(getURI(path, name).toString + "reason: " + e.message) 85 throw new Exception(getURI(path, name).toString());
75 } 86 }
76 } 87 }
77 88
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend
index 867ddd1a..2ea12581 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend
@@ -1,79 +1,43 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io 1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io
2 2
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain 3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain
4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric
5import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric
6import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric
7import java.io.File
8import java.util.List
9import java.util.Scanner
10import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup 4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup
5import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.impl.YakindummPackageImpl
11 6
12/** 7/**
13 * Read the sample of the distribution of a metric provided the csv file of the metric 8 * Read the sample of the distribution of a metric provided the csv file of the metric
14 */ 9 */
15class RepMetricsReader { 10class RepMetricsReader {
16 static def read(Domain d){ 11 static def read(Domain d){
17 var domainRepPath = CsvDataName.REP_PATH + d.name + '/'; 12 var reader = new GraphReader(YakindummPackageImpl.eINSTANCE);
13
14
15 var domainRepPath = DataName.REP_PATH + d.name + '/';
18 var rep = new MetricSampleGroup() 16 var rep = new MetricSampleGroup()
19 rep.mpcSamples = readFile(domainRepPath + CsvDataName.MPC_REP, MultiplexParticipationCoefficientMetric.valueName, 17 var out_d = readMetrics(reader, domainRepPath + DataName.OUT_D_REP);
20 MultiplexParticipationCoefficientMetric.countName).map[Double.parseDouble(it)]; 18 rep.mpcSamples = readMetrics(reader, domainRepPath + DataName.MPC_REP).mpcSamples;
21 rep.naSamples = readFile(domainRepPath+CsvDataName.NA_REP, NodeActivityMetric.valueName, NodeActivityMetric.countName 19 rep.outDegreeSamples = out_d.outDegreeSamples;
22 ).map[Double.parseDouble(it)]; 20 rep.naSamples = readMetrics(reader, domainRepPath + DataName.NA_REP).naSamples;
23 rep.outDegreeSamples = readFile(domainRepPath+CsvDataName.OUT_D_REP, OutDegreeMetric.valueName, OutDegreeMetric.countName 21 rep.typedOutDegreeSamples = out_d.typedOutDegreeSamples;
24 ).map[Double.parseDouble(it)]; 22 rep.edgeTypeSamples = out_d.edgeTypeSamples;
23 rep.nodeTypeSamples = out_d.nodeTypeSamples;
25 return rep; 24 return rep;
26 } 25 }
27 26
28 /** 27 /**
29 * read metric data and parse it to samples 28 * Read representative model
30 */ 29 */
31 private static def List<String> readFile(String filename, String valueDataName, String countDataName){ 30 private static def readMetrics(GraphReader r, String path){
32 var s = new Scanner(new File(filename)); 31 var model = r.readModels(path).head;
33 val counts = newArrayList(); 32 return model.evaluateAllMetricsToSamples();
34 val values = newArrayList();
35 //read data from csv
36 while(s.hasNext()){
37 var data = s.nextLine().split(',');
38
39 if(data.size >= 1){
40 if(data.get(0).equals(countDataName)){
41 //add all data with parsing them as integers
42 counts.addAll(data.subList(1, data.size()).map[Integer.parseInt(it)]);
43 }else if(data.get(0).equals(valueDataName)){
44 //add all data without parsing (there can be either double or string, to be parsed later)
45 values.addAll(data.subList(1, data.size()));
46 }
47 }
48 }
49
50 return createSamples(counts, values);
51 } 33 }
52 34
53 // create samples from values and counts
54 private static def List<String> createSamples(List<Integer> counts, List<String> values){
55 val samples = newArrayList();
56
57 if(counts.size() != values.size()){
58 throw new RuntimeException("counts and values should have the same size!");
59 }
60
61 for(var i = 0; i < counts.size(); i++){
62 for(var j = 0; j < counts.get(i); j++){
63 samples.add(values.get(i));
64 }
65 }
66
67 return samples;
68 }
69
70
71} 35}
72 36
73class CsvDataName{ 37class DataName{
74 public static val REP_PATH = 'data/'; 38 public static val REP_PATH = 'data/';
75 public static val MPC_REP = 'mpc_rep.csv'; 39 public static val MPC_REP = 'mpc_rep';
76 public static val NA_REP = 'na_rep.csv'; 40 public static val NA_REP = 'na_rep';
77 public static val OUT_D_REP = 'out_d_rep.csv'; 41 public static val OUT_D_REP = 'out_d_rep';
78} 42}
79 43
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/EdgeTypeMetric.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/EdgeTypeMetric.xtend
new file mode 100644
index 00000000..0c0fe3b8
--- /dev/null
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/EdgeTypeMetric.xtend
@@ -0,0 +1,41 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics
2
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.GraphStatistic
4import java.util.ArrayList
5import java.util.HashMap
6
7class EdgeTypeMetric extends Metric {
8
9 override evaluate(GraphStatistic g) {
10 var map = evaluateSamples(g) as HashMap<String, Double>;
11 var output = new ArrayList<String[]>();
12 output.add(newArrayList('Edge Type'));
13
14 var keys = map.keySet;
15 var values = newArrayList();
16 for(key : keys){
17 values.add(map.get(key)+'');
18 }
19
20 output.add(keys);
21 output.add(values);
22
23 return output;
24 }
25
26 override evaluateSamples(GraphStatistic g) {
27 val map = new HashMap<String, Double>();
28 var outgoingEdges = g.outgoingEdges;
29
30 //get the total number of edges
31 val edgeCount = outgoingEdges.values.fold(0, [r, t| r + t.asMap.values.fold(0, [r1, t1| r1 + t1.size])]) as double;
32 outgoingEdges.forEach[k, v|
33 var value = v.asMap.values.fold(0, [r, t| r + t.size]) / edgeCount;
34 map.put(k, value);
35 ]
36
37
38 return map;
39 }
40
41} \ No newline at end of file
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/Metric.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/Metric.xtend
index 38ef72f2..cb242a5b 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/Metric.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/Metric.xtend
@@ -4,5 +4,5 @@ import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.GraphStatis
4 4
5abstract class Metric { 5abstract class Metric {
6 abstract def String[][] evaluate(GraphStatistic g); 6 abstract def String[][] evaluate(GraphStatistic g);
7 abstract def double[] evaluateSamples(GraphStatistic g); 7 abstract def Object evaluateSamples(GraphStatistic g);
8} \ No newline at end of file 8} \ No newline at end of file
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MetricSampleGroup.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MetricSampleGroup.xtend
index 8cd3daee..4e25bb86 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MetricSampleGroup.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MetricSampleGroup.xtend
@@ -1,9 +1,13 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics 1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics
2 2
3import java.util.HashMap
3import java.util.List 4import java.util.List
4 5
5class MetricSampleGroup{ 6class MetricSampleGroup{
6 public var List<Double> mpcSamples; 7 public var List<Double> mpcSamples;
7 public var List<Double> naSamples; 8 public var List<Double> naSamples;
8 public var List<Double> outDegreeSamples; 9 public var List<Double> outDegreeSamples;
10 public var HashMap<String, List<Integer>> typedOutDegreeSamples;
11 public var HashMap<String, Double> nodeTypeSamples;
12 public var HashMap<String, Double> edgeTypeSamples;
9} \ No newline at end of file 13} \ No newline at end of file
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/NodeTypeMetric.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/NodeTypeMetric.xtend
new file mode 100644
index 00000000..94eaa445
--- /dev/null
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/NodeTypeMetric.xtend
@@ -0,0 +1,44 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics
2
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.GraphStatistic
4import java.util.ArrayList
5import java.util.HashMap
6
7class NodeTypeMetric extends Metric {
8
9
10 override evaluate(GraphStatistic g) {
11 var map = evaluateSamples(g) as HashMap<String, Double>;
12 var output = new ArrayList<String[]>();
13 output.add(newArrayList('Node Type'));
14 var keys = map.keySet;
15 var values = newArrayList();
16
17 for(key : keys){
18 values.add(map.get(key)+'');
19 }
20
21 output.add(keys);
22 output.add(values);
23
24 return output;
25 }
26
27 override evaluateSamples(GraphStatistic g) {
28 var map = new HashMap<String, Double>();
29 var nodes = g.allNodes;
30 var single = 1.0 / nodes.size();
31 for(node : nodes){
32 var classes = new ArrayList(node.eClass.ESuperTypes);
33 classes.add(node.eClass);
34
35 for(cl : classes){
36 var value = map.getOrDefault(cl.name, 0.0);
37 map.put(cl.name, value + single);
38 }
39 }
40
41 return map;
42 }
43
44} \ No newline at end of file
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/TypedOutDegree.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/TypedOutDegree.xtend
new file mode 100644
index 00000000..3b5dbcc5
--- /dev/null
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/TypedOutDegree.xtend
@@ -0,0 +1,60 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics
2
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.GraphStatistic
4import java.util.ArrayList
5import java.util.HashMap
6import java.util.List
7
8class TypedOutDegree extends Metric{
9
10 def private calculateMetric(GraphStatistic g){
11 var outgoingEdges = g.outgoingEdges;
12 //record metric as a list of samples for each node type / edge type pair
13 var metric = new HashMap<String, List<Integer>>();
14 var nodeToTypes = g.nodeToTypesMap;
15
16 for(edgeType : outgoingEdges.keySet){
17 for(node : outgoingEdges.get(edgeType).keySet){
18 //find all classes the node belongs to
19 var classes = nodeToTypes.get(node);
20 for(cl : classes){
21 // get or create entry for node type / edge type pair
22 var key = cl + ' ' + edgeType;
23 var typeCount = metric.get(key);
24 if(typeCount === null){
25 typeCount = new ArrayList<Integer>();
26 metric.put(key, typeCount);
27 }
28
29 // get or create sample list
30 typeCount.add(outgoingEdges.get(edgeType).get(node).size);
31 }
32 }
33 }
34
35 return metric;
36 }
37
38 override evaluate(GraphStatistic g) {
39 var metric = calculateMetric(g);
40 var output = new ArrayList<String[]>();
41
42 output.add(newArrayList('Typed Out Degree'));
43 for(key : metric.keySet){
44 var samples = metric.get(key);
45 var String[] outputForOnePair = newArrayOfSize(samples.size+1);
46 outputForOnePair.set(0, key);
47 for(var i = 0; i < samples.size; i++){
48 outputForOnePair.set(i+1, samples.get(i)+'');
49 }
50 output.add(outputForOnePair);
51 }
52
53 return output;
54 }
55
56 override evaluateSamples(GraphStatistic g) {
57 return calculateMetric(g);
58 }
59
60} \ No newline at end of file