/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package weka.core.elastic_distance_measures; import weka.core.EuclideanDistance; import weka.core.Instance; import weka.core.Instances; import weka.core.neighboursearch.PerformanceStats; /** * * @author sjx07ngu */ public class LCSSDistance extends EuclideanDistance{ private double epsilon; private int delta; public LCSSDistance(int delta, double epsilon){ this.m_DontNormalize = true; this.delta = delta; this.epsilon = epsilon; } public double distance(Instance first, Instance second, double cutOffValue, PerformanceStats stats){ return distance(first,second); } /** * distance method that converts instances to arrays of doubles * * @param first instance 1 * @param second instance 2 * @param cutOffValue used for early abandon * @return distance between instances */ @Override public double distance(Instance first, Instance second, double cutOffValue){ // if(this.distanceCount % 10000000 == 0){ // System.out.println("New Instance: "+this.distanceCount); // } // this.distanceCount++; //remove class index from first instance if there is one int firtClassIndex = first.classIndex(); double[] arr1; if(firtClassIndex > 0){ arr1 = new double[first.numAttributes()-1]; for(int i = 0,j = 0; i < first.numAttributes(); i++){ if(i != firtClassIndex){ arr1[j]= first.value(i); j++; } } }else{ arr1 = first.toDoubleArray(); } //remove class index from second instance if there is one int secondClassIndex = second.classIndex(); double[] arr2; if(secondClassIndex > 0){ arr2 = new double[second.numAttributes()-1]; for(int i = 0,j = 0; i < second.numAttributes(); i++){ if(i != secondClassIndex){ arr2[j]= second.value(i); j++; } } }else{ arr2 = second.toDoubleArray(); } return distance(arr1,arr2,cutOffValue); } /** * calculates the distance between two instances (been converted to arrays) * * @param first instance 1 as array * @param second instance 2 as array * @param cutOffValue used for early abandon * @return distance between instances */ public double distance(double[] first, double[] second, double cutOffValue){ return distance(first, second); } public double distance(double[] first, double[] second){ double[] a = first; double[] b = second; int m = first.length; int n = second.length; int[][] lcss = new int[m+1][n+1]; int[][] lastX = new int[m+1][n+1]; int[][] lastY = new int[m+1][n+1]; for(int i = 0; i < m; i++){ for(int j = i-delta; j <= i+delta; j++){ // System.out.println("here"); if(j < 0 || j >= n){ //do nothing }else if(b[j]+this.epsilon >= a[i] && b[j]-epsilon <=a[i]){ lcss[i+1][j+1] = lcss[i][j]+1; lastX[i+1][j+1] = i; lastY[i+1][j+1] = j; }else if(lcss[i][j+1] > lcss[i+1][j]){ lcss[i+1][j+1] = lcss[i][j+1]; lastX[i+1][j+1] = i; lastY[i+1][j+1] = j+1; }else{ lcss[i+1][j+1] = lcss[i+1][j]; lastX[i+1][j+1] = i+1; lastY[i+1][j+1] = j; } } } int max = -1; for(int i = 1; i < lcss[lcss.length-1].length; i++){ if(lcss[lcss.length-1][i] > max){ max = lcss[lcss.length-1][i]; } } return 1-((double)max/m); } public static double stdv_s(double[] input){ double sumx = 0; double sumx2 = 0; for(int j = 0; j < input.length; j++){ sumx+=input[j]; sumx2+=input[j]*input[j]; } int n = input.length; double mean = sumx/n; double standardDev = Math.sqrt(sumx2/(n-1) - mean*mean); return standardDev; } public static double stdv_p(Instances input){ double sumx = 0; double sumx2 = 0; double[] ins2array; for(int i = 0; i < input.numInstances(); i++){ ins2array = input.instance(i).toDoubleArray(); for(int j = 0; j < ins2array.length-1; j++){//-1 to avoid classVal sumx+=ins2array[j]; sumx2+=ins2array[j]*ins2array[j]; } } int n = input.numInstances()*(input.numAttributes()-1); double mean = sumx/n; return Math.sqrt(sumx2/(n)-mean*mean); } public static int[] getInclusive10(int min, int max){ int[] output = new int[10]; double diff = (double)(max-min)/9; double[] doubleOut = new double[10]; doubleOut[0] = min; output[0] = min; for(int i = 1; i < 9; i++){ doubleOut[i] = doubleOut[i-1]+diff; output[i] = (int)Math.round(doubleOut[i]); } output[9] = max; // to make sure max isn't omitted due to double imprecision return output; } public static double[] getInclusive10(double min, double max){ double[] output = new double[10]; double diff = (double)(max-min)/9; output[0] = min; for(int i = 1; i < 9; i++){ output[i] = output[i-1]+diff; } output[9] = max; return output; } }