package edu.hawaii.jmotif.bughunt; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Arrays; import edu.hawaii.jmotif.sax.SAXFactory; import edu.hawaii.jmotif.sax.alphabet.NormalAlphabet; import edu.hawaii.jmotif.sax.trie.TrieException; import edu.hawaii.jmotif.timeseries.TSException; import edu.hawaii.jmotif.timeseries.TSUtils; import edu.hawaii.jmotif.timeseries.Timeseries; public class SigmoidDiscordBug { private static int GENERATED_SERIES_LENGTH = 5000; private static final int SLIDING_WINDOW_SIZE = 128; private static final int NUMBER_DISCORDS_TO_GET = 10; private static final int ALPHABET_SIZE = 4; private static final String COMMA = ","; private static final Object SEPARATOR = " | "; private static final Object CR = "\n"; /** * @param args * @throws TSException * @throws TrieException */ public static void main(String[] args) throws TSException, TrieException { Timeseries series = generateTimeseries(3); // for (TPoint tp : series) { // System.out.println(tp.value()); // } NormalAlphabet normalA = new NormalAlphabet(); double[] cuts = normalA.getCuts(ALPHABET_SIZE); // build the trie // int currPosition = 0; while ((currPosition + SLIDING_WINDOW_SIZE) < GENERATED_SERIES_LENGTH) { // get the window SAX representation double[] subSeries = SAXFactory.getSubSeries(series.values(), currPosition, currPosition + SLIDING_WINDOW_SIZE); // ******************** DEBUG ******************** // // // saxVals = TSUtils.ts2String(TSUtils.zNormalize(TSUtils.paa(vals, cuts.length + 1)), cuts); // // // StringBuffer sb = new StringBuffer(); sb.append(currPosition).append(SEPARATOR); sb.append("data: ").append(arrayToString(subSeries)).append(SEPARATOR); double[] paaVals = TSUtils.paa(subSeries, cuts.length + 1); sb.append("paa: ").append(arrayToString(paaVals)).append(SEPARATOR); double[] zNormalValues = TSUtils.zNormalize(paaVals); sb.append("Znormal: ").append(arrayToString(zNormalValues)).append(SEPARATOR); char[] saxVals = SAXFactory.getSaxVals(subSeries, SLIDING_WINDOW_SIZE, normalA.getCuts(ALPHABET_SIZE)); sb.append("sax: ").append(Arrays.toString(saxVals)).append(CR); if ((currPosition > 500 && currPosition < 700) || (currPosition > 2573 && currPosition < 2580)) { System.out.print(sb.toString()); } currPosition++; } // DiscordRecords dr = SAXFactory.series2Discords(series.values(), SLIDING_WINDOW_SIZE, // ALPHABET_SIZE, NUMBER_DISCORDS_TO_GET, new LargeWindowAlgorithm()); } private static String arrayToString(double[] data) { NumberFormat nf = new DecimalFormat("0.00"); StringBuffer sb = new StringBuffer(); for (double d : data) { sb.append(nf.format(d)).append(COMMA); } return sb.delete(sb.length() - 1, sb.length()).toString(); } public static Timeseries generateTimeseries(int id) throws TSException { double[] val = new double[GENERATED_SERIES_LENGTH]; long[] time = new long[GENERATED_SERIES_LENGTH]; double period; double ampl; switch (id) { case 0: // First dimension period = 800.; ampl = 15; // 25.; for (int i = 0; i < GENERATED_SERIES_LENGTH; i++) { time[i] = i; double noise = 2. * Math.random() - 1.; val[i] = ampl * Math.sin(2. * Math.PI * i / period); if (time[i] > 1300 && time[i] < 1500 && val[i] < 0) { val[i] = 0.; } else if (time[i] > 2500 && time[i] < 2600 && val[i] > ampl / 2.) { val[i] = -ampl / 4.; // val[i] = ampl / 5.; } else if (time[i] > 3400 && time[i] < 3500 && val[i] > ampl / 2.) { val[i] = ampl / 5.; // val[i] = -ampl / 5.; } val[i] += noise; } break; case 1: // Second dimension period = 500.; ampl = 15.; for (int i = 0; i < GENERATED_SERIES_LENGTH; i++) { time[i] = i; // double noise = 2 * Math.random() - 1.; val[i] = ampl * Math.sin(2. * Math.PI * i / period); if (val[i] < -ampl * 0.8) { val[i] = -(val[i] + ampl * 0.8); } if (val[i] < -ampl * 0.2) { val[i] = -ampl * 0.2; } if (time[i] > 2800 && time[i] < 2950) { val[i] = -ampl * 0.2; } if (time[i] > 500 && time[i] < 700 && val[i] > ampl / 1.7) { val[i] = ampl / 1.7; } if (time[i] > 3800 && time[i] < 4000 && val[i] > 0) { val[i] = val[i] * 2.5; } // val[i] += noise; } break; case 2: // Third dimension period = 350.; ampl = 10.; for (int i = 0; i < GENERATED_SERIES_LENGTH; i++) { time[i] = i; // double noise = 2 * Math.random() - 1.; val[i] = ampl * Math.sin(2. * Math.PI * i / period); if (val[i] > ampl * 0.8) { val[i] = ampl * 0.8; } else if (val[i] < -1 * ampl / 4.) { val[i] = -1 * ampl / 4.; } if (time[i] > 3100 && time[i] < 3200) { val[i] = 0; } if (time[i] > 2570 && time[i] < 2630) { val[i] = 0; } if (time[i] > 2300 && time[i] < 2350) { val[i] = ampl * .08; } if (time[i] > 4500 && time[i] < 4570) { val[i] = -1 * ampl / 2.; } if (time[i] > 420 && time[i] < 450) { val[i] = ampl * 0.5; } // val[i] += noise; } break; case 3: // Fourth dimension period = 1000.; ampl = 20.; double arg = 0.; double strechFactor = 50.; double boundary = 8.; for (int i = 0; i < GENERATED_SERIES_LENGTH; i++) { time[i] = i; // double noise = 2 * Math.random() - 1.; arg = (i - (Math.floor(i / period)) * period) / strechFactor - boundary; val[i] = ampl / (1 + Math.exp(-(arg))); if (arg < -boundary || arg > boundary) { val[i] = 0.; } else { // val[i] = ampl / (1 + Math.exp(-(arg))); } if (time[i] > 2700 && time[i] < 3000) { val[i] = 0; } else if (time[i] > 4200 && time[i] < 4400 && val[i] < ampl / 3.) { val[i] = ampl / 3.; } // val[i] += noise; } break; default: period = 800.; ampl = 5.; for (int i = 0; i < GENERATED_SERIES_LENGTH; i++) { time[i] = i; double noise = 2 * Math.random() - 1.; val[i] = ampl * Math.sin(2. * Math.PI * i / period) + noise; if (time[i] > 3400 && time[i] < 3500 && val[i] > ampl / 2.) { } else if (time[i] > 2500 && time[i] < 2600 && val[i] > ampl / 2.) { // val[i] = ampl/5. + noise; } val[i] += noise; } break; } return new Timeseries(val, time); } @SuppressWarnings("unused") private static void saveRealSeries(String filename, double[] data, double start, double step) throws IOException { BufferedWriter bw = new BufferedWriter(new FileWriter(new File(filename))); for (int i = 0; i < data.length; i++) { bw.write(String.valueOf(start + i * step) + "," + Double.valueOf(data[i]) + "\n"); } bw.close(); } }