package net.seninp.jmotif.sax;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import net.seninp.jmotif.sax.alphabet.Alphabet;
import net.seninp.jmotif.sax.alphabet.NormalAlphabet;
/**
* Test the tsp.
*
* @author Pavel Senin.
*
*
*
*
*/
public class TestTSProcessor {
private static final String ts1File = "src/resources/test-data/timeseries01.csv";
private static final String ts2File = "src/resources/test-data/timeseries02.csv";
private static final String ts1NormFile = "src/resources/test-data/timeseries01.norm.csv";
private static final String ts2NormFile = "src/resources/test-data/timeseries02.norm.csv";
private static final String ts1PAAFile = "src/resources/test-data/timeseries01.PAA10.csv";
private static final String ts2PAAFile = "src/resources/test-data/timeseries02.PAA10.csv";
private static final int length = 15;
private static final int PAAlength = 10;
private static final double delta = 0.000001;
private static final double ts1Max = 9.2;
private static final double ts1Min = 1.34;
private static final double ts2Max = 8.83;
private static final double ts2Min = 0.5;
private static final Alphabet normalA = new NormalAlphabet();
TSProcessor tsp;
private double[] ts1;
private double[] ts2;
/**
* Test set-up.
*
* @throws Exception if error occurs.
*/
@Before
public void setUp() throws Exception {
tsp = new TSProcessor();
ts1 = tsp.readTS(ts1File, length);
ts2 = tsp.readTS(ts2File, length);
}
/**
* Test the extremum calculations.
*/
@Test
public void testExtremum() {
assertEquals("max", ts1Max, tsp.max(ts1), delta);
assertEquals("max", ts2Max, tsp.max(ts2), delta);
assertEquals("min", ts1Min, tsp.min(ts1), delta);
assertEquals("min", ts2Min, tsp.min(ts2), delta);
//
// now set the value of the second element as NaN
ts1[1] = Double.NaN;
ts2[2] = Double.NaN;
assertEquals("max", ts1Max, tsp.max(ts1), delta);
assertEquals("max", ts2Max, tsp.max(ts2), delta);
assertEquals("min", ts1Min, tsp.min(ts1), delta);
assertEquals("min", ts2Min, tsp.min(ts2), delta);
}
/**
* Test the median calculation.
*/
@Test
public void testMedian() {
assertEquals("testing the mean", 3.85, tsp.median(ts1), delta);
assertEquals("testing the mean", 3.83, tsp.median(ts2), delta);
assertEquals("testing the mean", 4.85, tsp.median(Arrays.copyOfRange(ts1, 0, 13)), delta);
}
/**
* Test the mean calculation.
*/
@Test
public void testMean() {
assertEquals("testing the mean", 4.606667, tsp.mean(ts1), delta);
assertEquals("testing the mean", 4.01, tsp.mean(ts2), delta);
final double[] badArrayDouble = {};
assertTrue("testing the mean", Double.isNaN(tsp.mean(badArrayDouble)));
int[] arr = { 1, 5, 8, 7, 6 };
assertEquals("testing the mean", 5.4, tsp.mean(arr), delta);
final int[] badArrayInt = {};
assertTrue("testing the mean", Double.isNaN(tsp.mean(badArrayInt)));
}
/**
* Test the variance calculation.
*/
@Test
public void testVar() {
assertEquals("variance", 6.971267, tsp.var(ts1), delta);
assertEquals("variance", 7.409971, tsp.var(ts2), delta);
final double[] badArray = {};
assertTrue("testing the mean", Double.isNaN(tsp.var(badArray)));
}
/**
* Test the standard deviation calculation.
*/
@Test
public void testStdev() {
assertEquals("stdev", 2.640316, tsp.stDev(ts1), delta);
}
/**
* Test the normalize routine.
*
* @throws Exception if error occurs.
*/
@Test
public void testZNormalize() throws Exception {
// read the normalized data
double[] ts1Norm = tsp.readTS(ts1NormFile, length);
double[] ts2Norm = tsp.readTS(ts2NormFile, length);
// get the normal data through the code
double[] ts1NormTest = tsp.znorm(ts1, 0.001);
double[] ts2NormTest = tsp.znorm(ts2, 0.001);
for (int i = 0; i < ts1Norm.length; i++) {
assertEquals("normalization", ts1Norm[i], ts1NormTest[i], delta);
}
for (int i = 0; i < ts2Norm.length; i++) {
assertEquals("normalization", ts2Norm[i], ts2NormTest[i], delta);
}
// get the norm 1 data
double[] ts1normOne = tsp.normOne(ts1);
double[] ts2normOne = tsp.normOne(ts2);
boolean seenOne = false;
for (int i = 0; i < ts1normOne.length; i++) {
assertTrue(ts1normOne[i] <= 1);
if (ts1normOne[i] == 1.0) {
seenOne = true;
}
}
assertTrue(seenOne);
seenOne = false;
for (int i = 0; i < ts2normOne.length; i++) {
assertTrue(ts2normOne[i] <= 1);
if (ts2normOne[i] == 1.0) {
seenOne = true;
}
}
assertTrue(seenOne);
// test the zeros yield
//
// get the normal data through the code
double[] zeros = tsp.znorm(ts1, tsp.stDev(ts1) + 0.1);
for (int i = 0; i < zeros.length; i++) {
assertEquals(0, zeros[i], 0.00001);
}
}
/**
* Test the PAA routine.
*
* @throws Exception if error occurs.
*/
@Test
public void testPAA() throws Exception {
// read the normalized data
double[] ts1Norm = tsp.readTS(ts1NormFile, length);
double[] ts2Norm = tsp.readTS(ts2NormFile, length);
// read the PAA data
double[] ts1PAA10 = tsp.readTS(ts1PAAFile, PAAlength);
double[] ts2PAA10 = tsp.readTS(ts2PAAFile, PAAlength);
// get the normal data through the code
double[] ts1PAATest = tsp.paa(ts1Norm, PAAlength);
double[] ts2PAATest = tsp.paa(ts2Norm, PAAlength);
for (int i = 0; i < ts1PAA10.length; i++) {
assertEquals("PAA", ts1PAA10[i], ts1PAATest[i], delta);
}
for (int i = 0; i < ts2PAA10.length; i++) {
assertEquals("PAA", ts2PAA10[i], ts2PAATest[i], delta);
}
// test the exception
try {
@SuppressWarnings("unused")
double[] failedPAA = tsp.paa(ts1Norm, ts1Norm.length + 1);
fail("exception should be thrown!");
}
catch (Exception e) {
assert true;
}
}
/**
* Test the SAX conversion.
*
* @throws SAXException if error occurs.
*
*/
@Test
public void testNum2Char() throws SAXException {
// private static final double[] case2 = { 0 };
assertEquals("test num2char", 'a', tsp.num2char(-0.5, normalA.getCuts(2)));
assertEquals("test num2char", 'b', tsp.num2char(0.5, normalA.getCuts(2)));
assertEquals("test num2char", 'b', tsp.num2char(0.0, normalA.getCuts(2)));
double[] ts0 = { -0.5, 0.5, 0.0 };
assertTrue("test num2char",
"abb".equalsIgnoreCase(new String(tsp.ts2String(ts0, normalA.getCuts(2)))));
// private static final double[] case7 = { -1.07, -0.57, -0.18, 0.18, 0.57, 1.07 };
assertEquals("test num2char", 'd', tsp.num2char(-0.179, normalA.getCuts(7)));
assertEquals("test num2char", 'd', tsp.num2char(-0.18, normalA.getCuts(7)));
assertEquals("test num2char", 'c', tsp.num2char(-0.1801, normalA.getCuts(7)));
double[] ts1 = { -0.179, -0.18, -0.1801 };
assertTrue("test num2char",
"ddc".equalsIgnoreCase(new String(tsp.ts2String(ts1, normalA.getCuts(7)))));
assertEquals("test num2char", 'a', tsp.num2char(0));
}
/**
* Test the SAX conversion.
*
* @throws Exception if error occurs.
*/
@Test
public void testTS2Index() throws Exception {
// read the PAA data
double[] ts1PAA10 = tsp.readTS(ts1PAAFile, PAAlength);
int[] idx1 = tsp.ts2Index(ts1PAA10, normalA, 10);
assertEquals("Testing ts2index", Integer.valueOf(idx1[1]), Integer.valueOf(2));
assertEquals("Testing ts2index", Integer.valueOf(idx1[3]), Integer.valueOf(9));
assertEquals("Testing ts2index", Integer.valueOf(idx1[7]), Integer.valueOf(4));
}
/**
* Test series2string.
*
*/
@Test
public void testSeries2String() {
final NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
final DecimalFormat df = (DecimalFormat) nf;
df.applyPattern("#.0");
final double[] formattedTs = { -1.07, -0.57, -0.18, 0.18, 0.57, 1.07 };
String seriesAsString = tsp.seriesToString(formattedTs, df);
assertTrue(seriesAsString.contains("-1.1"));
assertTrue(seriesAsString.contains(".6"));
assertTrue(seriesAsString.contains("-.6"));
}
/**
* Test series copy.
*
* @throws IOException if error occurs.
* @throws SAXException if error occurs.
*
*/
@Test
public void series2String() throws SAXException, IOException {
// read the normalized data
//
final double[] ts1Norm = tsp.readTS(ts1NormFile, length);
final double[] ts2Norm = tsp.readTS(ts2NormFile, length);
// test copy
//
double[] cp1 = tsp.subseriesByCopy(ts1Norm, 3, 7);
for (int i = 3; i < 7; i++) {
assertEquals("testing copy routines", cp1[i - 3], ts1Norm[i], delta);
}
try {
double[] cp2 = tsp.subseriesByCopy(ts2Norm, 3, 755);
assertEquals("testing copy routines", cp2[1], ts1Norm[3], delta);
fail("Exception is not thrown");
}
catch (IndexOutOfBoundsException e) {
assert true;
}
}
@Test
public void testFileLoadExceptions() {
try {
@SuppressWarnings("unused")
double[] dat = tsp.readTS("non-existent-file", 0);
fail("exception should be thrown!");
}
catch (Exception e) {
assert true;
}
try {
@SuppressWarnings("unused")
double[] dat = TSProcessor.readFileColumn("non-existent-file", 0, 0);
fail("exception should be thrown!");
}
catch (Exception e) {
assert true;
}
try {
@SuppressWarnings("unused")
double[] dat = TSProcessor.readFileColumn("src//resources//dataset//asys40.txt", 3, 0);
fail("exception should be thrown!");
}
catch (Exception e) {
assert true;
}
try {
double[] dat = TSProcessor.readFileColumn("src//resources//dataset//asys40.txt", 0, 0);
assertEquals(7500, dat.length);
}
catch (Exception e) {
fail("exception should not be thrown!");
}
}
}