public static GeoTimeSerie bSAX(GeoTimeSerie gts,int alphabetSize,int wordLen,int windowLen,boolean standardizePAA) throws WarpScriptException {
  if (!GTSHelper.isBucketized(gts) || (TYPE.DOUBLE != gts.type && TYPE.LONG != gts.type)) {
    throw new WarpScriptException("Function can only be applied to numeric, bucketized, filled geo time series.");
  }
  if (windowLen % wordLen != 0) {
    throw new WarpScriptException("Wordlen MUST divide windowlen.");
  }
  int levels=0;
  if (0 == alphabetSize) {
    throw new WarpScriptException("Alphabet size MUST be a power of two.");
  }
  while (0 == (alphabetSize & 1)) {
    levels++;
    alphabetSize>>>=1;
  }
  if (1 != alphabetSize) {
    throw new WarpScriptException("Alphabet size MUST be a power of two.");
  }
  if (levels < 1 || levels > SAXUtils.SAX_MAX_LEVELS) {
    throw new WarpScriptException("Alphabet size MUST be a power of two between 2 and 2^" + SAXUtils.SAX_MAX_LEVELS);
  }
  int paaLen=windowLen / wordLen;
  GTSHelper.sort(gts);
  GeoTimeSerie saxGTS=new GeoTimeSerie(gts.lastbucket,gts.bucketcount,gts.bucketspan,gts.values);
  saxGTS.setMetadata(gts.getMetadata());
  int[] symbols=new int[wordLen];
  double paaSum[]=new double[wordLen];
  for (int i=0; i < gts.values - windowLen + 1; i++) {
    double sum=0.0D;
    double sumsq=0.0D;
    for (int w=0; w < wordLen; w++) {
      paaSum[w]=0.0D;
      for (int k=0; k < paaLen; k++) {
        paaSum[w]+=TYPE.LONG == gts.type ? gts.longValues[i + w * paaLen + k] : gts.doubleValues[i + w * paaLen + k];
      }
      if (!standardizePAA) {
        continue;
      }
      double mean=paaSum[w] / paaLen;
      sum+=mean;
      sumsq+=mean * mean;
    }
    double mu=0.0D;
    double variance=0.0D;
    double sigma=0.0D;
    if (standardizePAA) {
      mu=sum / wordLen;
      variance=(sumsq / wordLen) - (sum * sum) / ((double)wordLen * (double)wordLen);
      if (wordLen > 1) {
        variance=variance * wordLen / (wordLen - 1.0D);
      }
      sigma=Math.sqrt(variance);
    }
    for (int w=0; w < wordLen; w++) {
      if (standardizePAA) {
        symbols[w]=SAXUtils.SAX(levels,sigma != 0D ? ((paaSum[w] / paaLen) - mu) / sigma : ((paaSum[w] / paaLen) - mu));
      }
 else {
        symbols[w]=SAXUtils.SAX(levels,paaSum[w] / paaLen);
      }
    }
    String word=new String(OrderPreservingBase64.encode(SAXUtils.bSAX(levels,symbols)),Charsets.US_ASCII);
    GTSHelper.setValue(saxGTS,gts.ticks[i],word);
  }
  return saxGTS;
}

public static GeoTimeSerie bSAX ( GeoTimeSerie gts , int alphabetSize , int wordLen , int windowLen , boolean standardizePAA ) throws WarpScriptException { if ( ! GTSHelper . isBucketized ( gts ) || ( TYPE . DOUBLE != gts . type && TYPE . LONG != gts . type ) ) { throw new WarpScriptException ( "Function can only be applied to numeric, bucketized, filled geo time series." ) ; } if ( windowLen % wordLen != 0 ) { throw new WarpScriptException ( "Wordlen MUST divide windowlen." ) ; } int levels = 0 ; if ( 0 == alphabetSize ) { throw new WarpScriptException ( "Alphabet size MUST be a power of two." ) ; } while ( 0 == ( alphabetSize & 1 ) ) { levels ++ ; alphabetSize >>>= 1 ; } if ( 1 != alphabetSize ) { throw new WarpScriptException ( "Alphabet size MUST be a power of two." ) ; } if ( levels < 1 || levels > SAXUtils . SAX_MAX_LEVELS ) { throw new WarpScriptException ( "Alphabet size MUST be a power of two between 2 and 2^" + SAXUtils . SAX_MAX_LEVELS ) ; } int paaLen = windowLen / wordLen ; GTSHelper . sort ( gts ) ; GeoTimeSerie saxGTS = new GeoTimeSerie ( gts . lastbucket , gts . bucketcount , gts . bucketspan , gts . values ) ; saxGTS . setMetadata ( gts . getMetadata ( ) ) ; int [ ] symbols = new int [ wordLen ] ; double paaSum [ ] = new double [ wordLen ] ; for ( int i = 0 ; i < gts . values - windowLen + 1 ; i ++ ) { double sum = 0.0D ; double sumsq = 0.0D ; for ( int w = 0 ; w < wordLen ; w ++ ) { paaSum [ w ] = 0.0D ; for ( int k = 0 ; k < paaLen ; k ++ ) { paaSum [ w ] += TYPE . LONG == gts . type ? gts . longValues [ i + w * paaLen + k ] : gts . doubleValues [ i + w * paaLen + k ] ; } if ( ! standardizePAA ) { continue ; } double mean = paaSum [ w ] / paaLen ; sum += mean ; sumsq += mean * mean ; } double mu = 0.0D ; double variance = 0.0D ; double sigma = 0.0D ; if ( standardizePAA ) { mu = sum / wordLen ; variance = ( sumsq / wordLen ) - ( sum * sum ) / ( ( double ) wordLen * ( double ) wordLen ) ; if ( wordLen > 1 ) { variance = variance * wordLen / ( wordLen - 1.0D ) ; } sigma = Math . sqrt ( variance ) ; } for ( int w = 0 ; w < wordLen ; w ++ ) { if ( standardizePAA ) { symbols [ w ] = SAXUtils . SAX ( levels , sigma != 0D ? ( ( paaSum [ w ] / paaLen ) - mu ) / sigma : ( ( paaSum [ w ] / paaLen ) - mu ) ) ; } else { symbols [ w ] = SAXUtils . SAX ( levels , paaSum [ w ] / paaLen ) ; } } String word = new String ( OrderPreservingBase64 . encode ( SAXUtils . bSAX ( levels , symbols ) ) , Charsets . US_ASCII ) ; GTSHelper . setValue ( saxGTS , gts . ticks [ i ] , word ) ; } return saxGTS ; }
produces a string gts whose values are the encoded bsax words of the sequence starting at each tick . it only works on numeric bucketized gts instances .
