public void MeansClustering()
        {
            // Re-create the mouse test

            double[] x = new double[3];
            double[] y = new double[3];
            double[] s = new double[3];

            x[0] = 0.25;
            y[0] = 0.75;
            s[0] = 0.1;

            x[1] = 0.75;
            y[1] = 0.75;
            s[1] = 0.1;

            x[2] = 0.5;
            y[2] = 0.5;
            s[2] = 0.2;

            MultivariateSample points = new MultivariateSample(2);
            Random             rng    = new Random(1);
            NormalDistribution d      = new NormalDistribution();

            for (int i = 0; i < 100; i++)
            {
                int k = rng.Next(3);
                points.Add(x[k] + s[k] * d.GetRandomValue(rng), y[k] + s[k] * d.GetRandomValue(rng));
            }

            MeansClusteringResult result = points.MeansClustering(3);

            Assert.IsTrue(result.Count == 3);
            Assert.IsTrue(result.Dimension == 2);
        }
        public void MeansClustering2()
        {
            ColumnVector[] centers = new ColumnVector[] {
                new ColumnVector(0.0, 0.0, 0.0),
                new ColumnVector(2.0, 0.0, 0.0),
                new ColumnVector(0.0, 2.0, 0.0),
                new ColumnVector(0.0, 0.0, 2.0)
            };

            FrameTable table    = new FrameTable();
            string     alphabet = "abcdefghijklmnopqrstuvwxyz";

            for (int j = 0; j < 3; j++)
            {
                table.AddColumn <double>(alphabet[j].ToString());
            }


            List <int>          inputAssignments = new List <int>();
            List <ColumnVector> inputVectors     = new List <ColumnVector>();
            Random rng = new Random(2);
            ContinuousDistribution dist = new NormalDistribution(0.0, 1.0);

            for (int i = 0; i < 100; i++)
            {
                int inputAssignment = rng.Next(0, centers.Length);
                inputAssignments.Add(inputAssignment);
                ColumnVector inputVector = centers[inputAssignment].Copy();
                for (int k = 0; k < inputVector.Dimension; k++)
                {
                    inputVector[k] += dist.GetRandomValue(rng);
                }
                inputVectors.Add(inputVector);
                table.AddRow <double>(inputVector);
            }

            MeansClusteringResult result = table.AsColumns <double>().MeansClustering(centers.Length);

            //MultivariateSample s = new MultivariateSample(3);
            //foreach (ColumnVector v in inputVectors) { s.Add(v); }
            //MeansClusteringResult result = s.MeansClustering(centers.Length);

            List <int> outputAssignments = new List <int>();

            for (int i = 0; i < inputVectors.Count; i++)
            {
                int assignment = result.Classify(inputVectors[i]);
                outputAssignments.Add(assignment);
            }

            // Map the output centroids to the original centroids
            Dictionary <int, int> map = new Dictionary <int, int>();

            for (int outputIndex = 0; outputIndex < result.Count; outputIndex++)
            {
                ColumnVector centroid            = result.Centroid(outputIndex);
                int          mappedInputIndex    = -1;
                double       mappedInputDistance = Double.MaxValue;
                for (int inputIndex = 0; inputIndex < centers.Length; inputIndex++)
                {
                    double distance = (centroid - centers[inputIndex]).Norm();
                    if (distance < mappedInputDistance)
                    {
                        mappedInputIndex    = inputIndex;
                        mappedInputDistance = distance;
                    }
                }
                Assert.IsTrue(mappedInputIndex >= 0);
                Assert.IsTrue(mappedInputDistance < 1.0);
                map.Add(outputIndex, mappedInputIndex);
            }

            int correctCount = 0;

            for (int i = 0; i < outputAssignments.Count; i++)
            {
                if (map[outputAssignments[i]] == inputAssignments[i])
                {
                    correctCount++;
                }
            }
            Assert.IsTrue(correctCount >= 0.50 * outputAssignments.Count);
        }