aboutsummaryrefslogtreecommitdiffstats
path: root/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/EuclideanDistance.xtend
blob: d6adcc9ae99040bd9e2ed2cdb181b081e0a0aec6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance

import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain
import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.RepMetricsReader
import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup
import com.google.common.collect.Sets
import java.text.DecimalFormat
import java.util.ArrayList
import java.util.HashMap
import java.util.List
import java.util.Map
import java.util.Set

class EuclideanDistance extends CostDistance{
	var MetricSampleGroup g;
	var HashMap<String, Double> mpcPMF;
	var HashMap<String, Double> naPMF;
	var HashMap<String, Double> outDegreePMF;
	var DecimalFormat formatter;
	
	new(MetricSampleGroup g){
		this.g = g;
		
		var mpcSamples = g.mpcSamples;
		var naSamples = g.naSamples.stream.mapToDouble([it]).toArray();
		var outDegreeSamples = g.outDegreeSamples.stream.mapToDouble([it]).toArray();
		
		//needs to format the number to string avoid precision issue
		formatter = new DecimalFormat("#0.00000");  
		
		mpcPMF = pmfFromSamples(mpcSamples, formatter);
   		naPMF = pmfFromSamples(naSamples, formatter);
   		outDegreePMF = pmfFromSamples(outDegreeSamples, formatter);	
	}
	
	override naDistance(List<Double> samples) {
		var pmfMap = pmfFromSamples(samples, formatter);
		return euclideanDistance(pmfMap, naPMF);
	}
	
	override mpcDistance(List<Double> samples) {
		var pmfMap = pmfFromSamples(samples, formatter);
		return euclideanDistance(pmfMap, mpcPMF);
	}
	
	override outDegreeDistance(List<Double> samples) {
		var pmfMap = pmfFromSamples(samples, formatter);
		return euclideanDistance(pmfMap, outDegreePMF);
	}
	
	
	def private euclideanDistance(HashMap<String, Double> pmf1, HashMap<String, Double> pmf2){
		var keys = Sets.union(pmf1.keySet(), pmf2.keySet());
		var pmfList1 = pmfMapToList(pmf1, keys);
		var pmfList2 = pmfMapToList(pmf2, keys);
		var distance = 0.0;
		for(var i = 0; i < pmfList1.size(); i++){
			distance += Math.pow(pmfList1.get(i) + pmfList2.get(i), 2);
		}
		
		return Math.sqrt(distance);
	}	
	
	def private pmfMapToList(Map<String, Double> map, Set<String> keys){
		var list = new ArrayList<Double>();
		for(key : keys){
			var value = map.getOrDefault(key, 0.0);
			list.add(value);
		}
		return list;
	}
}