@Test
/**
 * Tests Gaussian Mixture Model on a three not so well separated clusters.
 */
public void bivariateOkSeparatedNormalTest() throws Exception {

    MacroBaseConf conf = new MacroBaseConf()
            .set(MacroBaseConf.RANDOM_SEED, 4)
            .set(MacroBaseConf.TRANSFORM_TYPE, "MEAN_FIELD_GMM")
            .set(GMMConf.NUM_MIXTURES, 3)
            .set(MacroBaseConf.DATA_LOADER_TYPE, "CSV_LOADER")
            .set(MacroBaseConf.CSV_COMPRESSION, CSVIngester.Compression.GZIP)
            .set(MacroBaseConf.CSV_INPUT_FILE, "src/test/resources/data/3gaussians-7000points.csv.gz")
            .set(MacroBaseConf.METRICS, "XX, YY")
            .set(MacroBaseConf.ATTRIBUTES, "");
    List<Datum> data = Drainer.drainIngest(conf);
    assertEquals(7000, data.size());
    double[][] clusterMeans = {
            {1.5, 2},
            {2, 0},
            {4.5, 1},
    };
    List<RealVector> vectorClusterMeans = new ArrayList<>(3);
    for (int k = 0; k < 3; k++) {
        vectorClusterMeans.add(new ArrayRealVector(clusterMeans[k]));
    }
    double[][][] clusterCovariances = {
            {{0.5, 0.4}, {0.4, 0.5}},
            {{0.3, 0}, {0, 0.6}},
            {{0.9, 0.2}, {0.2, 0.3}},
    };
    FiniteGMM finiteGMM = new FiniteGMM(conf);
    finiteGMM.train(data);
    List<RealVector> calculatedMeans = finiteGMM.getClusterCenters();
    List<RealMatrix> calculatedCovariances = finiteGMM.getClusterCovariances();
    for (int i = 0; i < 3; i++) {
        boolean identified = false;
        for (int j = 0; j < 3; j++) {
            if (calculatedMeans.get(i).getDistance(vectorClusterMeans.get(j)) < 0.1) {
                for (int p = 0; p < 2; p++) {
                    for (int q = 0; q < 2; q++) {
                        assertEquals(clusterCovariances[j][p][q], calculatedCovariances.get(i).getEntry(p, q), 0.1);
                    }
                }
                identified = true;
                break;
            }
        }
        assertEquals("a cluster was not identified", true, identified);
    }
    double[][] boundaries = {
            {0, 6.01},
            {-2, 4.01},
    };
    List<Datum> scoredData = DiagnosticsUtils.createGridFixedIncrement(boundaries, 0.05);
    JsonUtils.dumpAsJson(finiteGMM.getClusterCovariances(), "FiniteGMMTest-bivariateOkSeparatedNormalTest-covariances.json");
    JsonUtils.dumpAsJson(finiteGMM.getClusterCenters(), "FiniteGMMTest-bivariateOkSeparatedNormalTest-means.json");
    JsonUtils.dumpAsJson(finiteGMM.getPriorAdjustedClusterProportions(), "FiniteGMMTest-bivariateOkSeparatedNormalTest-weights.json");
    conf.set(GMMConf.SCORE_DUMP_FILE_CONFIG_PARAM, "3gaussians-7k-grid.json");
    ScoreDumper dumper = new ScoreDumper(conf);
    dumper.dumpScores(finiteGMM, scoredData);
    conf.set(GMMConf.SCORE_DUMP_FILE_CONFIG_PARAM, "3gaussians-7k-data.json");
    dumper = new ScoreDumper(conf);
    dumper.dumpScores(finiteGMM, data);
}