import tschief.util.math.doubles.StatisticsDbl;
import org.junit.jupiter.api.*;

import java.util.Arrays;

import static org.junit.Assert.assertEquals;


public class NormalizationTest {
    double FLOAT_DELTA = 1e-8;

    @BeforeAll
    static void beforeAll() {

    }

    @AfterAll
    static void afterAll() {

    }

    @BeforeEach
    void setUp() {
    }

    @AfterEach
    void tearDown() {
    }

    @Test
    void testZNormalization() {
        String[] seriesValues = ("-1.59487819,-1.32613625,-1.21227197,-1.21227197,-1.21227197,-1.21227197,-1.21227197,-1.21227197,-1.0890686," +
                "-1.02096886,-1.02096886,-1.02096886,-1.02096886,-1.02096886,-0.971008,-0.42281112,-0.16010486,-0.16010486," +
                "-0.16010486,-0.16010486,-0.16010486,-0.16010486,-0.31212251,-0.54271108,-0.54271108,-0.54271108,-0.54271108," +
                "-0.54271108,-0.54271108,-0.54271108,-0.54271108,-0.54271108,-0.54271108,-0.54271108,-0.54271108,-0.54271108," +
                "-0.23782175,0.12684981,0.12684981,0.12684981,0.12684981,0.12684981,0.12684981,0.29292848,0.96294688,1.17901691," +
                "1.17901691,1.17901691,1.17901691,1.17901691,1.36232589,1.98701535,2.03988091,2.03988091,2.03988091,2.03988091," +
                "2.03988091,1.76604512,0.6385192,0.41380447,0.41380447,0.41380447,0.41380447,0.41380447,0.41380447").split(",");

        String[] zScoreValues = ("-1.6072898796453923,-1.3364565311970473,-1.221706134511439,-1.221706134511439,-1.221706134511439," +
                "-1.221706134511439,-1.221706134511439,-1.221706134511439,-1.097543968988557,-1.0289142619444622,-1.0289142619444622," +
                "-1.0289142619444622,-1.0289142619444622,-1.0289142619444622,-0.9785645956245758,-0.42610152782304234,-0.1613508303541562," +
                "-0.1613508303541562,-0.1613508303541562,-0.1613508303541562,-0.1613508303541562,-0.1613508303541562,-0.31455151489468075," +
                "-0.5469345754881095,-0.5469345754881095,-0.5469345754881095,-0.5469345754881095,-0.5469345754881095,-0.5469345754881095," +
                "-0.5469345754881095,-0.5469345754881095,-0.5469345754881095,-0.5469345754881095,-0.5469345754881095,-0.5469345754881095," +
                "-0.5469345754881095,-0.23967253015915022,0.12783698353521988,0.12783698353521988,0.12783698353521988,0.12783698353521988," +
                "0.12783698353521988,0.12783698353521988,0.29520811400316144,0.9704407434691936,1.1881922776146805,1.1881922776146805," +
                "1.1881922776146805,1.1881922776146805,1.1881922776146805,1.3729278081167329,2.0024787378755513,2.0557557092049867," +
                "2.0557557092049867,2.0557557092049867,2.0557557092049867,2.0557557092049867,1.7797888693038613,0.6434882964349562," +
                "0.4170247873467738,0.4170247873467738,0.4170247873467738,0.4170247873467738,0.4170247873467738,0.4170247873467738").split(",");

        double[] series = Arrays.stream(seriesValues).mapToDouble(Double::parseDouble).toArray();
        double mean = StatisticsDbl.mean(series);
        double stdp = StatisticsDbl.stdP(series);

        double[] znorm = Arrays.stream(zScoreValues).mapToDouble(Double::parseDouble).toArray();
        double zmean = StatisticsDbl.mean(znorm);
        double zstdp = StatisticsDbl.stdP(znorm);

        assertEquals(series.length, znorm.length);

        // actual values are from numpy
        assertEquals(-6.153844937901891e-10, mean, FLOAT_DELTA);
        assertEquals(0.9922778769293843, stdp, FLOAT_DELTA);

        // actual values are from numpy and scipy
        assertEquals(4.355490327375614e-17, zmean, FLOAT_DELTA);
        assertEquals(0.9999999999999998, zstdp, FLOAT_DELTA);

    }
}
