diff options
Diffstat (limited to 'Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src')
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 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app | 1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app |
2 | 2 | ||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.EuclideanDistance | ||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.JSDistance | 4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.JSDistance |
4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.KSDistance | 5 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.KSDistance |
5 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.StateData | 6 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.StateData |
@@ -8,6 +9,7 @@ import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric | |||
8 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric | 9 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric |
9 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric | 10 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric |
10 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric | 11 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric |
12 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.TypedOutDegree | ||
11 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.predictor.LinearModel | 13 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.predictor.LinearModel |
12 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | 14 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation |
13 | import java.util.ArrayList | 15 | import 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 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance | 1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance |
2 | 2 | ||
3 | import java.text.DecimalFormat | ||
4 | import java.util.HashMap | ||
5 | import java.util.List | ||
3 | import org.eclipse.xtend.lib.annotations.Accessors | 6 | import org.eclipse.xtend.lib.annotations.Accessors |
4 | 7 | ||
5 | class CostDistance { | 8 | abstract 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 | ||
9 | class StateData{ | 25 | class 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 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance | ||
2 | |||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain | ||
4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.RepMetricsReader | ||
5 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup | ||
6 | import com.google.common.collect.Sets | ||
7 | import java.text.DecimalFormat | ||
8 | import java.util.ArrayList | ||
9 | import java.util.HashMap | ||
10 | import java.util.List | ||
11 | import java.util.Map | ||
12 | import java.util.Set | ||
13 | |||
14 | class 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 | |||
7 | import java.util.HashMap | 7 | import java.util.HashMap |
8 | import java.util.List | 8 | import java.util.List |
9 | 9 | ||
10 | class JSDistance { | 10 | class 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 | ||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain | 3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain |
4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.RepMetricsReader | 4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.RepMetricsReader |
5 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup | ||
6 | import java.util.HashMap | ||
7 | import java.util.HashSet | ||
5 | import java.util.List | 8 | import java.util.List |
9 | import java.util.Set | ||
6 | import org.apache.commons.math3.stat.inference.KolmogorovSmirnovTest | 10 | import org.apache.commons.math3.stat.inference.KolmogorovSmirnovTest |
7 | 11 | ||
8 | class KSDistance { | 12 | class 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 | ||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric | 3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric |
4 | import java.util.ArrayList | 4 | import java.util.ArrayList |
5 | import java.util.HashSet | ||
5 | import java.util.List | 6 | import java.util.List |
6 | import org.eclipse.emf.common.util.EList | 7 | import org.eclipse.emf.common.util.EList |
7 | import org.eclipse.emf.ecore.EObject | 8 | import org.eclipse.emf.ecore.EObject |
8 | import org.eclipse.emf.ecore.EReference | 9 | import org.eclipse.emf.ecore.EReference |
9 | 10 | ||
10 | class EMFGraph extends Graph{ | 11 | class 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 | ||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric | 3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric |
4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup | 4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup |
5 | import java.util.ArrayList | ||
6 | import java.util.List | ||
7 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric | 5 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric |
8 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric | 6 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric |
9 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric | 7 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric |
8 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.TypedOutDegree | ||
9 | import java.util.ArrayList | ||
10 | import java.util.HashMap | ||
11 | import java.util.List | ||
12 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeTypeMetric | ||
13 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.EdgeTypeMetric | ||
10 | 14 | ||
11 | abstract class Graph { | 15 | abstract 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 | |||
5 | import java.util.HashMap | 5 | import java.util.HashMap |
6 | import java.util.HashSet | 6 | import java.util.HashSet |
7 | import java.util.List | 7 | import java.util.List |
8 | import java.util.Map | ||
9 | import java.util.Set | ||
8 | import org.eclipse.emf.ecore.EObject | 10 | import org.eclipse.emf.ecore.EObject |
9 | 11 | ||
10 | class GraphStatistic { | 12 | class 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 | |||
4 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration | 4 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration |
5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink | 5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink |
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | 6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation |
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.BooleanElementImpl | 7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialComplexTypeInterpretationImpl |
8 | import java.util.ArrayList | 8 | import java.util.ArrayList |
9 | import java.util.List | 9 | import java.util.List |
10 | 10 | ||
11 | class PartialInterpretationGraph extends Graph{ | 11 | class 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 | |||
17 | import org.eclipse.emf.ecore.resource.ResourceSet | 17 | import org.eclipse.emf.ecore.resource.ResourceSet |
18 | import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl | 18 | import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl |
19 | import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl | 19 | import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl |
20 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeTypeMetric | ||
21 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.EdgeTypeMetric | ||
22 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.TypedOutDegree | ||
23 | import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.YakindummPackage | ||
20 | 24 | ||
21 | class GraphReader{ | 25 | class 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 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io | 1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io |
2 | 2 | ||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain | 3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain |
4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric | ||
5 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric | ||
6 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric | ||
7 | import java.io.File | ||
8 | import java.util.List | ||
9 | import java.util.Scanner | ||
10 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup | 4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup |
5 | import 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 | */ |
15 | class RepMetricsReader { | 10 | class 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 | ||
73 | class CsvDataName{ | 37 | class 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 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics | ||
2 | |||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.GraphStatistic | ||
4 | import java.util.ArrayList | ||
5 | import java.util.HashMap | ||
6 | |||
7 | class 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 | ||
5 | abstract class Metric { | 5 | abstract 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 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics | 1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics |
2 | 2 | ||
3 | import java.util.HashMap | ||
3 | import java.util.List | 4 | import java.util.List |
4 | 5 | ||
5 | class MetricSampleGroup{ | 6 | class 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 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics | ||
2 | |||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.GraphStatistic | ||
4 | import java.util.ArrayList | ||
5 | import java.util.HashMap | ||
6 | |||
7 | class 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 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics | ||
2 | |||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.GraphStatistic | ||
4 | import java.util.ArrayList | ||
5 | import java.util.HashMap | ||
6 | import java.util.List | ||
7 | |||
8 | class 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 | ||