package org.aksw.limes.core.util;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import org.aksw.limes.core.io.mapping.AMapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;


/**
 * @author Axel-C. Ngonga Ngomo (ngonga@informatik.uni-leipzig.de)
 */
public class Utils {

    /**
     * Computes the precision of the mapping computed with respect to the
     * mapping reference.
     *
     * @param reference
     * @param computed
     * @return Precision
     */
    static Logger logger = LoggerFactory.getLogger(Utils.class.getName());

    public static double getPrecision(AMapping reference, AMapping computed) {
        double size = (double) computed.size();
        double count = 0;
        for (String key : computed.getMap().keySet()) {
            for (String value : computed.getMap().get(key).keySet()) {
                if (reference.contains(key, value) || reference.contains(value, key)) {
                    count++;
                }
            }
        }
        return count / size;
    }

    /**
     * Computes the recall of the mapping computed with respect to the mapping
     * reference.
     *
     * @param reference
     * @param computed
     * @return Recall
     */
    public static double getRecall(AMapping reference, AMapping computed) {
        double size = (double) reference.size();
        double count = 0;
        for (String key : computed.getMap().keySet()) {
            for (String value : computed.getMap().get(key).keySet()) {
                if (reference.contains(key, value) || reference.contains(value, key)) {
                    count++;
                }
            }
        }
        return count / size;
    }

    /**
     * Computes the recall of the mapping computed with respect to the mapping
     * reference.
     *
     * @param reference
     * @param computed
     * @return Recall
     */
    public static double getFscore(AMapping reference, AMapping computed) {
        double sizeC = (double) computed.size();
        double sizeR = (double) reference.size();
        double count = 0;
        for (String key : computed.getMap().keySet()) {
            for (String value : computed.getMap().get(key).keySet()) {
                if (reference.contains(key, value) || reference.contains(value, key)) {
                    count++;
                }
            }
        }
        double p = count / sizeC;
        double r = count / sizeR;
        return 2 * p * r / (p + r);
    }

    /**
     * Computes all stats (i.e. precision, recall, f-score) of the mapping
     * computed with respect to the mapping reference.
     *
     * @param reference
     * @param computed
     * @return Precision, Recall and F-Score. The entries for the Hashmap are
     * "precision", "recall" and "fscore".
     */
    public static HashMap<String, Double> getPRF(AMapping reference, AMapping computed) {
        HashMap<String, Double> result = new HashMap<String, Double>();
        double sizeC = (double) computed.size();
        double sizeR = (double) reference.size();
        double count = 0;
        for (String key : computed.getMap().keySet()) {
            for (String value : computed.getMap().get(key).keySet()) {
                if (reference.contains(key, value) || reference.contains(value, key)) {
                    count++;
                }
            }
        }

        double p = count / sizeC;
        result.put("precision", p);
        double r = count / sizeR;
        result.put("recall", r);
        result.put("fscore", 2 * p * r / (p + r));

        return result;
    }

    /**
     * Splits camel case strings into lower case string separated with a " "
     *
     * @param s
     *         Input string in camel case
     * @return Split string
     */
    @SuppressWarnings("unused")
    private static String splitAtCamelCase(String s) {
        String regex = "([a-z])([A-Z])";
        String replacement = "$1 $2";
        return s.replaceAll(regex, replacement).toLowerCase();
    }

    public static double getStandardDeviation(List<Double> data) {
// sd is sqrt of sum of (values-mean) squared divided by n - 1 
// Calculate the mean 
        double mean = 0;
        final int n = data.size();
        if (n < 2) {
            return Double.NaN;
        }
        for (int i = 0; i < n; i++) {
            mean += data.get(i);
        }
        mean /= n;
        // calculate the sum of squares
        double sum = 0;
        for (int i = 0; i < n; i++) {
            final double v = data.get(i) - mean;
            sum += v * v;
        }
        // Change to ( n - 1 ) to n if you have complete data instead of a sample.
        return Math.sqrt(sum / (n - 1));
    }


    public static double getMean(List<Double> data) {
// sd is sqrt of sum of (values-mean) squared divided by n - 1 
// Calculate the mean 
        double mean = 0;
        final int n = data.size();
        if (n < 2) {
            return Double.NaN;
        }
        for (int i = 0; i < n; i++) {
            mean += data.get(i);
        }
        mean /= n;
        return mean;
    }
}

@@ -296,113 +296,8 @@
 *%0A *
- @author Axel-C. Ngonga Ngomo (ngonga@informatik.uni-leipzig.de)%0A */%0Apublic class Utils %7B%0A%0A    /**%0A     *
  Com
@@ -360,20 +360,16 @@
  to the%0A
-    
  * mappi
@@ -387,93 +387,189 @@
 e.%0A 
-    *%0A     * @param reference%0A     * @param computed%0A     * @return Precision%0A     */
+* %0A * @author Axel-C. Ngonga Ngomo (ngonga@informatik.uni-leipzig.de)%0A * @author Mohamed Sherif %3Csherif@informatik.uni-leipzig.de%3E%0A * @version Jul 18, 2016%0A */%0Apublic class Utils %7B%0A
 %0A   
@@ -1243,32 +1243,40 @@
 @param reference
+ Mapping
 %0A     * @param c
@@ -1274,32 +1274,40 @@
  @param computed
+ Mapping
 %0A     * @return 
@@ -2741,32 +2741,40 @@
 @param reference
+ Mapping
 %0A     * @param c
@@ -2772,32 +2772,40 @@
  @param computed
+ Mapping
 %0A     * @return 
@@ -3822,23 +3822,8 @@
 am s
-%0A     *        
  Inp
@@ -4177,32 +4177,40 @@
 Double%3E data) %7B%0A
+        
 // sd is sqrt of
@@ -4249,32 +4249,40 @@
 vided by n - 1 %0A
+        
 // Calculate the
@@ -4883,16 +4883,24 @@
 data) %7B%0A
+        
 // sd is
@@ -4955,16 +4955,24 @@
  n - 1 %0A
+        
 // Calcu

fix Utils