예제 #1
0
        public void yinyang_test()
        {
            // https://github.com/accord-net/framework/issues/451

            double[][] observations = LeastSquaresLearningTest.yinyang.GetColumns(0, 1).ToJagged();

            Accord.Math.Random.Generator.Seed = 0;

            var kmeans = new BalancedKMeans(2)
            {
                // If a limit is not set, the following Learn call does not return....
                MaxIterations = 1000
            };

            var clusters = kmeans.Learn(observations);

            int[] labels   = kmeans.Labels;
            int[] expected = new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 };

            string str = labels.ToCSharp();

            Assert.IsTrue(labels.IsEqual(expected));

            int[] hist = Accord.Math.Vector.Histogram(labels);

            for (int i = 0; i < hist.Length; i++)
            {
                Assert.AreEqual(hist[i], 50);
            }
        }
예제 #2
0
        public void KMeansMoreClustersThanSamples()
        {
            Accord.Math.Tools.SetupGenerator(0);


            // Declare some observations
            double[][] observations =
            {
                new double[] { -5, -2, -1 },
                new double[] { -5, -5, -6 },
                new double[] {  2,  1,  1 },
                new double[] {  1,  1,  2 },
                new double[] {  1,  2,  2 },
                new double[] {  3,  1,  2 },
                new double[] { 11,  5,  4 },
                new double[] { 15,  5,  6 },
                new double[] { 10,  5,  6 },
            };

            double[][] orig = observations.MemberwiseClone();

            BalancedKMeans kmeans = new BalancedKMeans(15)
            {
                MaxIterations = 10
            };

            Assert.Throws <ArgumentException>(() => kmeans.Compute(observations),
                                              "Not enough points. There should be more points than the number K of clusters.");
        }
예제 #3
0
        public void KMeansMoreClustersThanSamples()
        {
            Accord.Math.Tools.SetupGenerator(0);


            // Declare some observations
            double[][] observations =
            {
                new double[] { -5, -2, -1 },
                new double[] { -5, -5, -6 },
                new double[] {  2,  1,  1 },
                new double[] {  1,  1,  2 },
                new double[] {  1,  2,  2 },
                new double[] {  3,  1,  2 },
                new double[] { 11,  5,  4 },
                new double[] { 15,  5,  6 },
                new double[] { 10,  5,  6 },
            };

            double[][] orig = observations.MemberwiseClone();

            BalancedKMeans kmeans = new BalancedKMeans(15)
            {
                MaxIterations = 10
            };

            int[] labels = kmeans.Compute(observations);
        }
예제 #4
0
        public void KMeansConstructorTest_Distance()
        {
            // Create a new algorithm
            BalancedKMeans kmeans = new BalancedKMeans(3, new Manhattan());

            Assert.IsNotNull(kmeans.Distance);
            Assert.IsTrue(kmeans.Distance is Accord.Math.Distances.Manhattan);
        }
예제 #5
0
        public void KMeansConstructorTest3()
        {
            // Create a new algorithm
            BalancedKMeans kmeans = new BalancedKMeans(3);

            Assert.IsNotNull(kmeans.Clusters);
            Assert.IsNotNull(kmeans.Distance);
            Assert.IsNotNull(kmeans.Clusters.Centroids);
            Assert.IsNotNull(kmeans.Clusters.Count);
            Assert.IsNotNull(kmeans.Clusters.Covariances);
            Assert.IsNotNull(kmeans.Clusters.Proportions);
        }
예제 #6
0
        public void uniform_test()
        {
            // https://github.com/accord-net/framework/issues/451

            int numClusters = 6;

            double[][] observations =
            {
                new double[] {  10.8,  18.706148721743876 },
                new double[] { -10.8,  18.706148721743876 },
                new double[] { -21.6,                 0.0 },
                new double[] { -10.8, -18.706148721743876 },
                new double[] {  10.8, -18.706148721743876 },
                new double[] {  21.6,                 0.0 },
                new double[] {  32.4,  18.706148721743876 },
                new double[] {  21.6,  37.412297443487752 },
                new double[] {   0.0,  37.412297443487752 },
                new double[] { -21.6,  37.412297443487752 },
                new double[] { -32.4,  18.706148721743876 },
                new double[] { -43.2,                 0.0 },
                new double[] { -32.4, -18.706148721743876 },
                new double[] { -21.6, -37.412297443487752 },
                new double[] {   0.0, -37.412297443487752 },
                new double[] {  21.6, -37.412297443487752 },
                new double[] {  32.4, -18.706148721743876 },
                new double[] {  43.2,                 0.0 }
            };

            Accord.Math.Random.Generator.Seed = 0;
            var kmeans = new BalancedKMeans(numClusters)
            {
                // If a limit is not set, the following Learn call does not return....
                MaxIterations = 1000
            };

            var clusters = kmeans.Learn(observations);

            int[] labels   = kmeans.Labels;
            int[] expected = new[] { 2, 4, 4, 4, 0, 3, 3, 3, 2, 2, 5, 5, 5, 0, 0, 1, 1, 1 };

            string str = labels.ToCSharp();

            Assert.IsTrue(labels.IsEqual(expected));

            int[] hist = Accord.Math.Vector.Histogram(labels);

            for (int i = 0; i < hist.Length; i++)
            {
                Assert.AreEqual(hist[i], 3);
            }
        }
예제 #7
0
        public void getlabels()
        {
            // https://github.com/accord-net/framework/issues/451

            int numClusters = 6;

            double[][] observations =
            {
                new double[] {  10.8,  18.706148721743876 },
                new double[] { -10.8,  18.706148721743876 },
                new double[] { -21.6,                 0.0 },
                new double[] { -10.8, -18.706148721743876 },
                new double[] {  10.8, -18.706148721743876 },
                new double[] {  21.6,                 0.0 },
                new double[] {  32.4,  18.706148721743876 },
                new double[] {  21.6,  37.412297443487752 },
                new double[] {   0.0,  37.412297443487752 },
                new double[] { -21.6,  37.412297443487752 },
                new double[] { -32.4,  18.706148721743876 },
                new double[] { -43.2,                 0.0 },
                new double[] { -32.4, -18.706148721743876 },
                new double[] { -21.6, -37.412297443487752 },
                new double[] {   0.0, -37.412297443487752 },
                new double[] {  21.6, -37.412297443487752 },
                new double[] {  32.4, -18.706148721743876 },
                new double[] {  43.2,                 0.0 }
            };

            double[] solution = (new double[] { 3, 18, 2, 4, 17, 8, 12, 6, 10, 14, 15, 9, 13, 7, 11, 5, 16, 1 }).Subtract(1);

            int[] actualLabels = new int[observations.Length];
            BalancedKMeans.GetLabels(observations, numClusters, solution, actualLabels);

            int[] expectedLabels = (new int[] { 1, 4, 2, 5, 5, 3, 3, 1, 1, 4, 4, 2, 2, 5, 6, 6, 6, 3 }).Subtract(1);
            for (int j = 0; j < actualLabels.Length; j++)
            {
                double a = actualLabels[j];
                double e = expectedLabels[j];
                Assert.AreEqual(e, a, 0.1);
            }
        }
예제 #8
0
        public void MaxIterationsZero()
        {
            Accord.Math.Tools.SetupGenerator(0);

            // Declare some observations
            double[][] observations =
            {
                new double[] { -5, -2, -1 },
                new double[] { -5, -5, -6 },
                new double[] {  2,  1,  1 },
                new double[] {  1,  1,  2 },
                new double[] {  1,  2,  2 },
                new double[] {  3,  1,  2 },
                new double[] { 11,  5,  4 },
                new double[] { 15,  5,  6 },
                new double[] { 10,  5,  6 },
            };

            double[][] orig = observations.MemberwiseClone();

            var kmeans = new BalancedKMeans(2);

            Assert.Throws <InvalidOperationException>(() => kmeans.Compute(observations), "");
        }
예제 #9
0
        public void MaxIterationsZero()
        {
            Accord.Math.Tools.SetupGenerator(0);

            // Declare some observations
            double[][] observations =
            {
                new double[] { -5, -2, -1 },
                new double[] { -5, -5, -6 },
                new double[] {  2,  1,  1 },
                new double[] {  1,  1,  2 },
                new double[] {  1,  2,  2 },
                new double[] {  3,  1,  2 },
                new double[] { 11,  5,  4 },
                new double[] { 15,  5,  6 },
                new double[] { 10,  5,  6 },
            };

            double[][] orig = observations.MemberwiseClone();

            var kmeans = new BalancedKMeans(2);

            int[] labels = kmeans.Compute(observations);
        }
예제 #10
0
        public void uniform_test_min_variance()
        {
            // https://github.com/accord-net/framework/issues/451

            int numClusters = 6;

            double[][] observations =
            {
                new double[] {  10.8,  18.706148721743876 },
                new double[] { -10.8,  18.706148721743876 },
                new double[] { -21.6,                 0.0 },
                new double[] { -10.8, -18.706148721743876 },
                new double[] {  10.8, -18.706148721743876 },
                new double[] {  21.6,                 0.0 },
                new double[] {  32.4,  18.706148721743876 },
                new double[] {  21.6,  37.412297443487752 },
                new double[] {   0.0,  37.412297443487752 },
                new double[] { -21.6,  37.412297443487752 },
                new double[] { -32.4,  18.706148721743876 },
                new double[] { -43.2,                 0.0 },
                new double[] { -32.4, -18.706148721743876 },
                new double[] { -21.6, -37.412297443487752 },
                new double[] {   0.0, -37.412297443487752 },
                new double[] {  21.6, -37.412297443487752 },
                new double[] {  32.4, -18.706148721743876 },
                new double[] {  43.2,                 0.0 }
            };

            Accord.Math.Random.Generator.Seed = 0;
            var kmeans = new BalancedKMeans(numClusters)
            {
                Distance  = new SquareEuclidean(),
                Centroids = new[]
                {
                    // C = [ 0.00000   37.41230 ; -32.40000,  -18.70615 ; 10.80000,   18.70615; -21.60000,   37.41230; -10.80000,  -18.70615; 21.60000,  -37.41230 ]
                    new[] { 0.00000, 37.41230 },
                    new[] { -32.40000, -18.70615 },
                    new[] { 10.80000, 18.70615 },
                    new[] { -21.60000, 37.41230 },
                    new[] { -10.80000, -18.70615 },
                    new[] { 21.60000, -37.41230 },
                }
            };

            // If a limit is not set, the following Learn call does not return....
            kmeans.MaxIterations = 1;

            double[,] expectedCost =
            {
                { 3.2659e+003, 1.8662e+003, 4.6656e+002, 4.6656e+002, 1.8662e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 4.1990e+003, 3.2659e+003, 1.3997e+003, 4.6656e+002, 1.6339e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 6.0653e+003 },
                { 1.6339e-012, 4.6656e+002, 1.3997e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 4.6656e+002, 4.6656e+002, 4.6656e+002, 1.3997e+003, 1.8662e+003, 3.2659e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003 },
                { 1.3997e+003, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.8662e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 7.4650e+003, 6.0653e+003, 5.5987e+003 },
                { 1.8662e+003, 1.3997e+003, 4.6656e+002, 1.6339e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 4.6656e+002, 4.6656e+002, 1.3997e+003, 1.8662e+003, 3.2659e+003 },
                { 3.2659e+003, 4.1990e+003, 3.2659e+003, 1.3997e+003, 4.6656e+002, 1.3997e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 7.4650e+003, 6.0653e+003, 5.5987e+003, 3.2659e+003, 1.8662e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.8662e+003 },
                { 4.6656e+002, 4.6656e+002, 1.8662e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 6.0653e+003, 5.5987e+003, 6.0653e+003, 4.1990e+003, 3.2659e+003 },
                { 3.2659e+003, 1.8662e+003, 4.6656e+002, 4.6656e+002, 1.8662e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 4.1990e+003, 3.2659e+003, 1.3997e+003, 4.6656e+002, 1.6339e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 6.0653e+003 },
                { 1.6339e-012, 4.6656e+002, 1.3997e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 4.6656e+002, 4.6656e+002, 4.6656e+002, 1.3997e+003, 1.8662e+003, 3.2659e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003 },
                { 1.3997e+003, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.8662e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 7.4650e+003, 6.0653e+003, 5.5987e+003 },
                { 1.8662e+003, 1.3997e+003, 4.6656e+002, 1.6339e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 4.6656e+002, 4.6656e+002, 1.3997e+003, 1.8662e+003, 3.2659e+003 },
                { 3.2659e+003, 4.1990e+003, 3.2659e+003, 1.3997e+003, 4.6656e+002, 1.3997e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 7.4650e+003, 6.0653e+003, 5.5987e+003, 3.2659e+003, 1.8662e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.8662e+003 },
                { 4.6656e+002, 4.6656e+002, 1.8662e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 6.0653e+003, 5.5987e+003, 6.0653e+003, 4.1990e+003, 3.2659e+003 },
                { 3.2659e+003, 1.8662e+003, 4.6656e+002, 4.6656e+002, 1.8662e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 4.1990e+003, 3.2659e+003, 1.3997e+003, 4.6656e+002, 1.6339e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 6.0653e+003 },
                { 1.6339e-012, 4.6656e+002, 1.3997e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 4.6656e+002, 4.6656e+002, 4.6656e+002, 1.3997e+003, 1.8662e+003, 3.2659e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003 },
                { 1.3997e+003, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.8662e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 7.4650e+003, 6.0653e+003, 5.5987e+003 },
                { 1.8662e+003, 1.3997e+003, 4.6656e+002, 1.6339e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 4.6656e+002, 4.6656e+002, 1.3997e+003, 1.8662e+003, 3.2659e+003 },
                { 3.2659e+003, 4.1990e+003, 3.2659e+003, 1.3997e+003, 4.6656e+002, 1.3997e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 7.4650e+003, 6.0653e+003, 5.5987e+003, 3.2659e+003, 1.8662e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.8662e+003 },
                { 4.6656e+002, 4.6656e+002, 1.8662e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 6.0653e+003, 5.5987e+003, 6.0653e+003, 4.1990e+003, 3.2659e+003 }
            };

            Assert.AreEqual(0, kmeans.Iterations);
            var clusters = kmeans.Learn(observations);

            Assert.AreEqual(1, kmeans.Iterations);

            double[][] actualCost = kmeans.munkres.CostMatrix;
            for (int i = 0; i < actualCost.Length; i++)
            {
                for (int j = 0; j < actualCost[i].Length; j++)
                {
                    double a = actualCost[i][j];
                    double e = expectedCost[i, j];
                    Assert.AreEqual(e, a, 0.1);
                }
            }

            int[] labels = kmeans.Labels;
            int[] hist   = Accord.Math.Vector.Histogram(labels);
            for (int i = 0; i < hist.Length; i++)
            {
                Assert.AreEqual(hist[i], 3);
            }
        }
예제 #11
0
        public void learn_test()
        {
            #region doc_learn
            Accord.Math.Random.Generator.Seed = 0;

            // Declare some observations
            double[][] observations =
            {
                new double[] { -5, -2, -1 },
                new double[] { -5, -5, -6 },
                new double[] {  2,  1,  1 },
                new double[] {  1,  1,  2 },
                new double[] {  1,  2,  2 },
                new double[] {  3,  1,  2 },
                new double[] { 11,  5,  4 },
                new double[] { 15,  5,  6 },
                new double[] { 10,  5,  6 },
            };

            double[][] orig = observations.MemberwiseClone();

            // Create a new K-Means algorithm with 3 clusters
            BalancedKMeans kmeans = new BalancedKMeans(3)
            {
                // Note: in balanced k-means the chances of the algorithm oscillating
                // between two solutions increases considerably. For this reason, we
                // set a max-iterations limit to avoid iterating indefinitely.
                MaxIterations = 100
            };

            // Compute the algorithm, retrieving an integer array
            //  containing the labels for each of the observations
            KMeansClusterCollection clusters = kmeans.Learn(observations);

            // As a result, the first two observations should belong to the
            //  same cluster (thus having the same label). The same should
            //  happen to the next four observations and to the last three.
            int[] labels = clusters.Decide(observations);

            #endregion

            Assert.AreEqual(labels[0], labels[1]);

            Assert.AreEqual(labels[2], labels[3]);
            Assert.AreEqual(labels[2], labels[4]);
            Assert.AreEqual(labels[2], labels[5]);

            Assert.AreEqual(labels[6], labels[7]);
            Assert.AreEqual(labels[6], labels[8]);

            Assert.AreNotEqual(labels[0], labels[2]);
            Assert.AreNotEqual(labels[2], labels[6]);
            Assert.AreNotEqual(labels[0], labels[6]);

            int[] labels2 = kmeans.Clusters.Decide(observations);
            Assert.IsTrue(labels.IsEqual(labels2));

            // the data must not have changed!
            Assert.IsTrue(orig.IsEqual(observations));

            var c = new KMeansClusterCollection.KMeansCluster[clusters.Count];
            int i = 0;
            foreach (var cluster in clusters)
            {
                c[i++] = cluster;
            }

            for (i = 0; i < c.Length; i++)
            {
                Assert.AreSame(c[i], clusters[i]);
            }
        }
예제 #12
0
        public void distances_test()
        {
            int numClusters = 6;

            double[][] observations =
            {
                new double[] {  10.8,  18.706148721743876 },
                new double[] { -10.8,  18.706148721743876 },
                new double[] { -21.6,                 0.0 },
                new double[] { -10.8, -18.706148721743876 },
                new double[] {  10.8, -18.706148721743876 },
                new double[] {  21.6,                 0.0 },
                new double[] {  32.4,  18.706148721743876 },
                new double[] {  21.6,  37.412297443487752 },
                new double[] {   0.0,  37.412297443487752 },
                new double[] { -21.6,  37.412297443487752 },
                new double[] { -32.4,  18.706148721743876 },
                new double[] { -43.2,                 0.0 },
                new double[] { -32.4, -18.706148721743876 },
                new double[] { -21.6, -37.412297443487752 },
                new double[] {   0.0, -37.412297443487752 },
                new double[] {  21.6, -37.412297443487752 },
                new double[] {  32.4, -18.706148721743876 },
                new double[] {  43.2,                 0.0 }
            };

            var distance  = new SquareEuclidean();
            var centroids = new[]
            {
                new[] { 0.00000, 37.41230 },
                new[] { -32.40000, -18.70615 },
                new[] { 10.80000, 18.70615 },
                new[] { -21.60000, 37.41230 },
                new[] { -10.80000, -18.70615 },
                new[] { 21.60000, -37.41230 },
            };

            double[,] expectedDistances =
            {
                { 3.2659e+003, 1.8662e+003, 4.6656e+002, 4.6656e+002, 1.8662e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 4.1990e+003, 3.2659e+003, 1.3997e+003, 4.6656e+002, 1.6339e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 6.0653e+003 },
                { 1.6339e-012, 4.6656e+002, 1.3997e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 4.6656e+002, 4.6656e+002, 4.6656e+002, 1.3997e+003, 1.8662e+003, 3.2659e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003 },
                { 1.3997e+003, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.8662e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 7.4650e+003, 6.0653e+003, 5.5987e+003 },
                { 1.8662e+003, 1.3997e+003, 4.6656e+002, 1.6339e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 4.6656e+002, 4.6656e+002, 1.3997e+003, 1.8662e+003, 3.2659e+003 },
                { 3.2659e+003, 4.1990e+003, 3.2659e+003, 1.3997e+003, 4.6656e+002, 1.3997e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 7.4650e+003, 6.0653e+003, 5.5987e+003, 3.2659e+003, 1.8662e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.8662e+003 },
                { 4.6656e+002, 4.6656e+002, 1.8662e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 6.0653e+003, 5.5987e+003, 6.0653e+003, 4.1990e+003, 3.2659e+003 },
                { 3.2659e+003, 1.8662e+003, 4.6656e+002, 4.6656e+002, 1.8662e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 4.1990e+003, 3.2659e+003, 1.3997e+003, 4.6656e+002, 1.6339e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 6.0653e+003 },
                { 1.6339e-012, 4.6656e+002, 1.3997e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 4.6656e+002, 4.6656e+002, 4.6656e+002, 1.3997e+003, 1.8662e+003, 3.2659e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003 },
                { 1.3997e+003, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.8662e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 7.4650e+003, 6.0653e+003, 5.5987e+003 },
                { 1.8662e+003, 1.3997e+003, 4.6656e+002, 1.6339e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 4.6656e+002, 4.6656e+002, 1.3997e+003, 1.8662e+003, 3.2659e+003 },
                { 3.2659e+003, 4.1990e+003, 3.2659e+003, 1.3997e+003, 4.6656e+002, 1.3997e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 7.4650e+003, 6.0653e+003, 5.5987e+003, 3.2659e+003, 1.8662e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.8662e+003 },
                { 4.6656e+002, 4.6656e+002, 1.8662e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 6.0653e+003, 5.5987e+003, 6.0653e+003, 4.1990e+003, 3.2659e+003 },
                { 3.2659e+003, 1.8662e+003, 4.6656e+002, 4.6656e+002, 1.8662e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 4.1990e+003, 3.2659e+003, 1.3997e+003, 4.6656e+002, 1.6339e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 6.0653e+003 },
                { 1.6339e-012, 4.6656e+002, 1.3997e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 4.6656e+002, 4.6656e+002, 4.6656e+002, 1.3997e+003, 1.8662e+003, 3.2659e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003 },
                { 1.3997e+003, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.8662e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 7.4650e+003, 6.0653e+003, 5.5987e+003 },
                { 1.8662e+003, 1.3997e+003, 4.6656e+002, 1.6339e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 4.6656e+002, 4.6656e+002, 1.3997e+003, 1.8662e+003, 3.2659e+003 },
                { 3.2659e+003, 4.1990e+003, 3.2659e+003, 1.3997e+003, 4.6656e+002, 1.3997e+003, 3.2659e+003, 5.5987e+003, 6.0653e+003, 7.4650e+003, 6.0653e+003, 5.5987e+003, 3.2659e+003, 1.8662e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.8662e+003 },
                { 4.6656e+002, 4.6656e+002, 1.8662e+003, 3.2659e+003, 3.2659e+003, 1.8662e+003, 1.3997e+003, 4.6656e+002, 6.5358e-012, 4.6656e+002, 1.3997e+003, 3.2659e+003, 4.1990e+003, 6.0653e+003, 5.5987e+003, 6.0653e+003, 4.1990e+003, 3.2659e+003 }
            };

            double[][] actualDistances = BalancedKMeans.GetDistances(distance, observations, centroids, numClusters, Jagged.Zeros(18, 18));

            for (int i = 0; i < actualDistances.Length; i++)
            {
                for (int j = 0; j < actualDistances[i].Length; j++)
                {
                    double a = actualDistances[i][j];
                    double e = expectedDistances[i, j];
                    Assert.AreEqual(e, a, 0.1);
                }
            }
        }