public void VisualizeSimpleCPU()
        {
            double seedPercentage = 0.1;
            int    iterationCount = 10;

            ClusteringSimple clustering = new ClusteringSimple(descriptors);

            TestClusteringSimple(clustering);

            clustering.Clusterize(seedPercentage, iterationCount, seed);
            HelperTestClass.VisualizeClustering(clustering.Descriptors, clustering.Centroids, windowSize, windowSize);
        }
        // TODO: warning - no linkage between centroids of different layers. This is just heuristics for the lowest layer.
        public virtual double[] Clusterize(int[] layerSeedCounts, int[] iterationCounts, int randomSeed)
        {
            CheckClusterizeArguments(layerSeedCounts, iterationCounts);

            int layerCount = layerSeedCounts.Length;

            Centroid[][] hierarchicalClusters = new Centroid[layerCount][];

#if VERBOSE
            Console.WriteLine("Computing clusters for layer ID: 0");
#endif
            // compute the highest layer
            ClusteringSimple clusteringSimple = new ClusteringSimple(Descriptors);
            double[]         updateDeltas     = clusteringSimple.Clusterize(layerSeedCounts[0], iterationCounts[0], randomSeed);
            hierarchicalClusters[0] = clusteringSimple.Centroids;

#if VERBOSE
            Console.WriteLine("Helper higher level clustering added: ");
            foreach (Centroid c in clusteringSimple.Centroids)
            {
                Console.WriteLine("{0}:", c.Mean.Id);
            }
#endif

            // run clustering for each other layer
            for (int iLayer = 1; iLayer < layerCount; iLayer++)
            {
#if VERBOSE
                Console.WriteLine("Computing clusters for layer ID: {0}", iLayer);
#endif
                List <Centroid> lowerLayerCentroids = new List <Centroid>();
                int             layerClusterId      = 0;
                foreach (Centroid higherLayerCentroid in hierarchicalClusters[iLayer - 1])
                {
                    Descriptor[] centroidDescriptors = higherLayerCentroid.Descriptors.ToArray();

                    clusteringSimple = new ClusteringSimple(centroidDescriptors);
                    int seedCount = (layerSeedCounts[iLayer] <= centroidDescriptors.Length)
                        ? layerSeedCounts[iLayer]
                        : centroidDescriptors.Length;
#if VERBOSE
                    Console.WriteLine("Clusterization of {0} seeds, {1} iterations.", seedCount, iterationCounts[iLayer]);
#endif
                    clusteringSimple.Clusterize(seedCount, iterationCounts[iLayer], randomSeed);
#if VERBOSE
                    Console.WriteLine("Clusterization complete, {0} clusters found.", clusteringSimple.Centroids.Length);
#endif

                    // offset centroid indexes
                    foreach (Centroid centroid in clusteringSimple.Centroids)
                    {
                        centroid.Id = layerClusterId++;
                    }

                    lowerLayerCentroids.AddRange(clusteringSimple.Centroids);
#if VERBOSE
                    Console.WriteLine("Cluster {0} added: ", higherLayerCentroid.Mean.Id);
                    foreach (Centroid c in clusteringSimple.Centroids)
                    {
                        //Console.WriteLine("{0}:", c.Mean.Id);
                    }
#endif
                }
                hierarchicalClusters[iLayer] = lowerLayerCentroids.ToArray();
#if VERBOSE
                Console.WriteLine("Layer complete, {0} clusters found.", hierarchicalClusters[iLayer].Length);
#endif
            }
            Centroids = hierarchicalClusters;

            return(updateDeltas);    // TODO deltas are just for the first layer
        }