All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.seninp.jmotif.sax.parallel.SAXWorker Maven / Gradle / Ivy

Go to download

An implementation of time series Symbolic Aggregate approXimation and HOTSAX algorithms.

The newest version!
package net.seninp.jmotif.sax.parallel;

import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.Callable;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import net.seninp.jmotif.sax.NumerosityReductionStrategy;
import net.seninp.jmotif.sax.TSProcessor;
import net.seninp.jmotif.sax.alphabet.NormalAlphabet;

/**
 * A callable worker class that will translate a given interval of the timeseries into SAX.
 *
 * @author psenin
 */
public class SAXWorker implements Callable> {

  /**
   * The worker ID.
   */
  private final long id;

  /**
   * The input timeseries.
   */
  private final double[] ts;

  /**
   * The conversion start index.
   */
  private final int intervalStart;

  /**
   * The conversion end index.
   */
  private final int intervalEnd;

  /**
   * The SAX discretization sliding window parameter size.
   */
  private final int saxWindowSize;

  /**
   * The SAX discretization PAA size.
   */
  private final int saxPAASize;

  /**
   * The SAX discretization alphabet size.
   */
  private final int saxAlphabetSize;

  /**
   * The SAX discretization sliding window parameter size.
   */
  private final NumerosityReductionStrategy numerosityReductionStrategy;

  /**
   * The SAX discretization normalization threshold.
   */
  private final double normalizationThreshold;

  // logging stuff
  //
  private static final Logger LOGGER;
  private static final Level LOGGING_LEVEL = Level.INFO;

  static {
    LOGGER = (Logger) LoggerFactory.getLogger(SAXWorker.class);
    LOGGER.setLevel(LOGGING_LEVEL);
  }

  /**
   * Performs SAX discretization.
   *
   * @param id the job id.
   * @param data the data array.
   * @param intervalStart from which coordinate to start the conversion.
   * @param intervalEnd where to end conversion (non-ionclusive).
   * @param windowSize SAX window size.
   * @param paaSize SAX paa size.
   * @param alphabetSize SAX alphabet size.
   * @param nrs The numerosity reduction strategy.
   * @param normalizationThreshold The normalization strategy.
   */
  public SAXWorker(long id, double[] data, int intervalStart, int intervalEnd, int windowSize,
      int paaSize, int alphabetSize, NumerosityReductionStrategy nrs,
      double normalizationThreshold) {
    super();
    this.id = id;
    this.ts = data;
    this.intervalStart = intervalStart;
    this.intervalEnd = intervalEnd;
    this.saxWindowSize = windowSize;
    this.saxPAASize = paaSize;
    this.saxAlphabetSize = alphabetSize;
    this.numerosityReductionStrategy = nrs;
    this.normalizationThreshold = normalizationThreshold;
    LOGGER.debug(
        "sax worker instance id {}, data {}, window {}, paa  {}, alphabet {}, nr {}, threshold: {}, start: {}, end: {}",
        this.id, this.ts.length, this.saxWindowSize, this.saxPAASize, this.saxAlphabetSize,
        this.numerosityReductionStrategy, normalizationThreshold, this.intervalStart,
        this.intervalEnd);

  }

  @Override
  public HashMap call() throws Exception {

    NormalAlphabet na = new NormalAlphabet();
    TSProcessor tsp = new TSProcessor();
    // SAXProcessor sp = new SAXProcessor();

    HashMap res = new HashMap();
    res.put(-1, String.valueOf(this.id).toCharArray());

    // scan across the time series extract sub sequences, and convert
    // them to strings
    char[] previousString = null;
    for (int i = this.intervalStart; i < this.intervalEnd - (this.saxWindowSize - 1); i++) {

      // fix the current subsection
      double[] subSection = Arrays.copyOfRange(this.ts, i, i + this.saxWindowSize);

      // Z normalize it
      subSection = tsp.znorm(subSection, normalizationThreshold);

      // perform PAA conversion if needed
      double[] paa = tsp.paa(subSection, this.saxPAASize);

      // Convert the PAA to a string.
      char[] currentString = tsp.ts2String(paa, na.getCuts(this.saxAlphabetSize));

      if (null != previousString) {

        if (NumerosityReductionStrategy.EXACT.equals(this.numerosityReductionStrategy)
            && Arrays.equals(previousString, currentString)) {
          // NumerosityReduction
          continue;
        }
        // there is no MINDIST at the moment
        // else if (NumerosityReductionStrategy.MINDIST.equals(this.numerosityReductionStrategy)
        // && sp.checkMinDistIsZero(previousString, currentString)) {
        // continue;
        // }

      }

      previousString = currentString;

      res.put(i, currentString);

      LOGGER.trace(this.id + ", " + String.valueOf(currentString) + ", " + i);

      if (Thread.currentThread().isInterrupted()) {
        LOGGER.info("SAXWorker was interrupted... returning NULL");
        return null;
      }

    }

    // System.out.println(this.id + "@" + res.getSAXString(" "));
    return res;

  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy