/// <summary>
        ///
        /// </summary>
        protected override IEnumerable <Cluster> Cluster(IntensityMatrix vmatrix, DistanceMatrix UNUSED, ArgsClusterer args, ConfigurationClusterer tag, ProgressReporter prog)
        {
            // GET OPTIONS
            int k = (int)args.Parameters[0];

            // CREATE RANDOM CENTRES
            Random rnd = new Random();

            var            potentialCentres = new List <Vector>(vmatrix.Vectors);
            List <Cluster> clusters         = new List <Cluster>();

            for (int n = 0; n < k; n++)
            {
                int random = rnd.Next(potentialCentres.Count);

                Cluster p   = new Cluster((clusters.Count + 1).ToString(), tag);
                Vector  vec = potentialCentres[random];
                p.Exemplars.Add(vec.Values);

                potentialCentres.RemoveAt(random);

                clusters.Add(p);
            }

            // Assign to exemplars
            prog.Enter("Initialising assignments");
            LegacyClustererHelper.Assign(vmatrix, clusters, ECandidateMode.Exemplars, args.Distance, prog);
            prog.Leave();

            // Centre
            LegacyClustererHelper.PerformKMeansCentering(vmatrix, clusters, args.Distance, prog);

            return(clusters);
        }
        /// <summary>
        ///
        /// </summary>
        protected override IEnumerable <Cluster> Cluster(IntensityMatrix vmatrix, DistanceMatrix UNUSED, ArgsClusterer args, ConfigurationClusterer tag, ProgressReporter prog)
        {
            // Get parameters
            // COUNT LIMIT
            int countLimit = (int)tag.UntypedArgs.Parameters[0];
            // DISTANCE LIMIT
            double distanceLimit = (double)tag.UntypedArgs.Parameters[1];
            // SEED PEAK
            WeakReference <Peak> seedPeakRef = (WeakReference <Peak>)tag.UntypedArgs.Parameters[2];
            Peak seedPeak = seedPeakRef.GetTargetOrThrow();
            // SEED GROUP
            GroupInfo groupInfo = (GroupInfo)tag.UntypedArgs.Parameters[3];
            // DO-K-MEANS?
            bool doKMeans = (bool)tag.UntypedArgs.Parameters[4];

            // Create the seed cluster
            Cluster        seedCluster = new Cluster("1", tag);
            List <Cluster> seedList    = new List <Cluster> {
                seedCluster
            };
            int seedIndex = vmatrix.FindIndex(new IntensityMatrix.RowHeader(seedPeak, args.SplitGroups ? groupInfo : null));

            if (seedIndex == -1)
            {
                throw new InvalidOperationException($"The chosen peak {{{seedPeak}}} cannot be used a seed because it is not present in the value matrix. Please check that this peak has not been excluded by the filter condition {{{args.PeakFilter}}}.");
            }

            seedCluster.Exemplars.Add(vmatrix.Vectors[seedIndex]);

            // Autogenerate the clusters
            int?   nCountLimit    = (countLimit != Int32.MinValue) ? countLimit : (int?)null;
            double?nDistanceLimit = (distanceLimit != Double.MinValue) ? countLimit : (double?)null;

            List <Cluster> autoGenClusters = AutogenerateClusters(vmatrix, seedList, nDistanceLimit, nCountLimit, args.Distance, tag, prog);

            // Do k-means (if requested)
            if (doKMeans)
            {
                prog.Enter("k-means");
                LegacyClustererHelper.PerformKMeansCentering(vmatrix, autoGenClusters, args.Distance, prog);
                prog.Leave();
            }

            // Return full list
            return(autoGenClusters);
        }