code: package dotnet54.classifiers.tschief.splitters.st;
  
  import java.util.Arrays;
  
  public class Shapelet {
      public static final double ROUNDING_ERROR_CORRECTION = 0.000000000000001;
  
  	public int series_index;
  	public int label;
  	public int start = 0;
  	public int length = 0;
  	public double[] shapelet;
  	public boolean is_normalized;
  	
  	public Shapelet(double[] series, int start, int length, int label, int index, boolean normalize) {
  		this.series_index = index;
  		this.label = label;
  		this.start = start;
  		this.length = length;
  		this.is_normalized = normalize;
  		
  		//TODO throw 
  		shapelet = Arrays.copyOfRange(series, start, start + length);
  		
  		if (normalize) {
  			shapelet = Shapelet.zNormalise(shapelet, false);
  		}
  		
  	}
  	
  	public double[] get_shapelet(double[] series) {
  		return Arrays.copyOfRange(series, start, start + length);
  	}
  	
  	public static long getNumShapelets(int n, int m, int min_length,int max_length, int step) {
  		long sum = 0;
  		int length;
  		long temp = 0;
  		
  		for (length = min_length; length <= max_length; length += step) {
  			temp = 0;
  			for (int i = 0; i < m - length; i++) {
  				temp++;
  			}
  			temp++;
  			sum += temp;
  //			System.out.println("length: " + length + " = " + temp);
  		}
  		return sum * n;
  	}
  	
      /**
      * Z-Normalise a time series
      *
      * @param input the input time series to be z-normalised
      * @param classValOn specify whether the time series includes a class value
      * (e.g. an full instance might, a candidate shapelet wouldn't)
      * @return a z-normalised version of input
      */
  	//@reference
  	//code based on/copied from timeseriesweka code, bakeoff paper
     public static double[] zNormalise(double[] input, boolean classValOn)
     {
         double mean;
         double stdv;
  
         int classValPenalty = classValOn ? 1 : 0;
         int inputLength = input.length - classValPenalty;
  
         double[] output = new double[input.length];
         double seriesTotal = 0;
         for (int i = 0; i < inputLength; i++)
         {
             seriesTotal += input[i];
         }
  
         mean = seriesTotal / (double) inputLength;
         stdv = 0;
         double temp;
         for (int i = 0; i < inputLength; i++)
         {
             temp = (input[i] - mean);
             stdv += temp * temp;
         }
  
         stdv /= (double) inputLength;
  
         // if the variance is less than the error correction, just set it to 0, else calc stdv.
         stdv = (stdv < ROUNDING_ERROR_CORRECTION) ? 0.0 : Math.sqrt(stdv);
         
         //System.out.println("mean "+ mean);
         //System.out.println("stdv "+stdv);
         
         for (int i = 0; i < inputLength; i++)
         {
             //if the stdv is 0 then set to 0, else normalise.
             output[i] = (stdv == 0.0) ? 0.0 : ((input[i] - mean) / stdv);
         }
  
         if (classValOn)
         {
             output[output.length - 1] = input[input.length - 1];
         }
  
         return output;
     }		
  }
  