protected ArrayList<SameLengthMotifs> refinePatternsByClustering(GrammarRules grammarRules,
      double[] ts, ArrayList<SameLengthMotifs> allClassifiedMotifs, double fractionTopDist) {
    DistanceComputation dc = new DistanceComputation();
    double[] origTS = ts;
    ArrayList<SameLengthMotifs> newAllClassifiedMotifs = new ArrayList<SameLengthMotifs>();
    for (SameLengthMotifs sameLenMotifs : allClassifiedMotifs) {
      ArrayList<RuleInterval> arrPos = new ArrayList<RuleInterval>();
      ArrayList<SAXMotif> subsequences = sameLenMotifs.getSameLenMotifs();
      for (SAXMotif ss : subsequences) {
        arrPos.add(ss.getPos());
      }

      int patternNum = arrPos.size();
      if (patternNum < 2) {
        continue;
      }
      double dt[][] = new double[patternNum][patternNum];
      // Build distance matrix.
      for (int i = 0; i < patternNum; i++) {
        RuleInterval saxPos = arrPos.get(i);

        int start1 = saxPos.getStart();
        int end1 = saxPos.getEnd();
        double[] ts1 = Arrays.copyOfRange(origTS, start1, end1);

        for (int j = 0; j < arrPos.size(); j++) {
          RuleInterval saxPos2 = arrPos.get(j);
          if (dt[i][j] > 0) {
            continue;
          }
          double d = 0;
          dt[i][j] = d;
          if (i == j) {
            continue;
          }
          int start2 = saxPos2.getStart();
          int end2 = saxPos2.getEnd();
          double[] ts2 = Arrays.copyOfRange(origTS, start2, end2);

          if (ts1.length > ts2.length)
            d = dc.calcDistTSAndPattern(ts1, ts2);
          else
            d = dc.calcDistTSAndPattern(ts2, ts1);

          // DTW dtw = new DTW(ts1, ts2);
          // d = dtw.warpingDistance;

          dt[i][j] = d;
        }
      }

      String[] patternsName = new String[patternNum];
      for (int i = 0; i < patternNum; i++) {
        patternsName[i] = String.valueOf(i);
      }

      ClusteringAlgorithm alg = new DefaultClusteringAlgorithm();
      Cluster cluster = alg.performClustering(dt, patternsName, new AverageLinkageStrategy());

      // int minPatternPerCls = (int) (0.3 * patternNum);
      // minPatternPerCls = minPatternPerCls > 0 ? minPatternPerCls : 1;
      int minPatternPerCls = 1;

      if (cluster.getDistance() == null) {
        // System.out.print(false);
        continue;
      }

      // TODO: refine hard coded threshold
      // double cutDist = cluster.getDistance() * 0.67;
      double cutDist = cluster.getDistanceValue() * fractionTopDist;

      ArrayList<String[]> clusterTSIdx = findCluster(cluster, cutDist, minPatternPerCls);
      while (clusterTSIdx.size() <= 0) {
        cutDist += cutDist / 2;
        clusterTSIdx = findCluster(cluster, cutDist, minPatternPerCls);
      }

      newAllClassifiedMotifs.addAll(SeparateMotifsByClustering(clusterTSIdx, sameLenMotifs));
    }
    return newAllClassifiedMotifs;
  }
protected ArrayList < SameLengthMotifs > refinePatternsByClustering ( GrammarRules grammarRules , double [ ] ts , ArrayList < SameLengthMotifs > allClassifiedMotifs , double fractionTopDist ) { DistanceComputation dc = new DistanceComputation ( ) ; double [ ] origTS = ts ; ArrayList < SameLengthMotifs > newAllClassifiedMotifs = new ArrayList < SameLengthMotifs > ( ) ; for ( SameLengthMotifs sameLenMotifs : allClassifiedMotifs ) { ArrayList < RuleInterval > arrPos = new ArrayList < RuleInterval > ( ) ; ArrayList < SAXMotif > subsequences = sameLenMotifs . getSameLenMotifs ( ) ; for ( SAXMotif ss : subsequences ) { arrPos . add ( ss . getPos ( ) ) ; } int patternNum = arrPos . size ( ) ; if ( patternNum < 2 ) { continue ; } double dt [ ] [ ] = new double [ patternNum ] [ patternNum ] ; for ( int i = 0 ; i < patternNum ; i ++ ) { RuleInterval saxPos = arrPos . get ( i ) ; int start1 = saxPos . getStart ( ) ; int end1 = saxPos . getEnd ( ) ; double [ ] ts1 = Arrays . copyOfRange ( origTS , start1 , end1 ) ; for ( int j = 0 ; j < arrPos . size ( ) ; j ++ ) { RuleInterval saxPos2 = arrPos . get ( j ) ; if ( dt [ i ] [ j ] > 0 ) { continue ; } double d = 0 ; dt [ i ] [ j ] = d ; if ( i == j ) { continue ; } int start2 = saxPos2 . getStart ( ) ; int end2 = saxPos2 . getEnd ( ) ; double [ ] ts2 = Arrays . copyOfRange ( origTS , start2 , end2 ) ; if ( ts1 . length > ts2 . length ) d = dc . calcDistTSAndPattern ( ts1 , ts2 ) ; else d = dc . calcDistTSAndPattern ( ts2 , ts1 ) ; dt [ i ] [ j ] = d ; } } String [ ] patternsName = new String [ patternNum ] ; for ( int i = 0 ; i < patternNum ; i ++ ) { patternsName [ i ] = String . valueOf ( i ) ; } ClusteringAlgorithm alg = new DefaultClusteringAlgorithm ( ) ; Cluster cluster = alg . performClustering ( dt , patternsName , new AverageLinkageStrategy ( ) ) ; int minPatternPerCls = 1 ; if ( cluster . getDistance ( ) == null ) { continue ; } double cutDist = cluster . getDistanceValue ( ) * fractionTopDist ; ArrayList < String [ ] > clusterTSIdx = findCluster ( cluster , cutDist , minPatternPerCls ) ; while ( clusterTSIdx . size ( ) <= 0 ) { cutDist += cutDist / 2 ; clusterTSIdx = findCluster ( cluster , cutDist , minPatternPerCls ) ; } newAllClassifiedMotifs . addAll ( SeparateMotifsByClustering ( clusterTSIdx , sameLenMotifs ) ) ; } return newAllClassifiedMotifs ; }
Refines patterns by clustering.

@param grammarRules the set of grammar rules.
@param ts the input time series.
@param allClassifiedMotifs all the motifs in groups.
@param fractionTopDist the fraction threshold.
@return refined set of patterns.