/// <summary>
        /// Calculates the centroids of the clusters
        /// </summary>
        private void CalculateClusterCenters()
        {
            for (int j = 0; j < this.Clusters.Count; j++)
            {
                ClusterCentroid c  = this.Clusters[j];
                double          uX = 0.0;
                double          uY = 0.0;
                double          l  = 0.0;

                for (int i = 0; i < this.Points.Count; i++)
                {
                    ClusterPoint p = this.Points[i];

                    double uu = Math.Pow(U[i, j], this.Fuzzyness);
                    uX += uu * c.X;
                    uY += uu * c.Y;
                    l  += uu;
                }

                c.X = ((int)(uX / l));
                c.Y = ((int)(uY / l));

                this.Log += string.Format("Cluster Centroid: ({0}; {1})" + System.Environment.NewLine, c.X, c.Y);
            }
        }
        /// <summary>
        /// Initialize the algorithm with points and initial clusters
        /// </summary>
        /// <param name="points">Points</param>
        /// <param name="clusters">Clusters</param>
        /// <param name="fuzzy">The fuzzyness factor to be used</param>
        public CMeansAlgorithm(List <ClusterPoint> points, List <ClusterCentroid> clusters, float fuzzy)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }

            if (clusters == null)
            {
                throw new ArgumentNullException("clusters");
            }

            this.Points   = points;
            this.Clusters = clusters;

            U = new double[this.Points.Count, this.Clusters.Count];
            //Uk = new double[this.Points.Count, this.Clusters.Count];

            this.Fuzzyness = fuzzy;

            double diff;

            // Iterate through all points to create initial U matrix
            for (int i = 0; i < this.Points.Count; i++)
            {
                ClusterPoint p   = this.Points[i];
                double       sum = 0.0;

                for (int j = 0; j < this.Clusters.Count; j++)
                {
                    ClusterCentroid c = this.Clusters[j];
                    diff    = Math.Sqrt(Math.Pow(p.X - c.X, 2.0) + Math.Pow(p.Y - c.Y, 2.0));
                    U[i, j] = (diff == 0) ? Eps : diff;
                    sum    += U[i, j];
                }

                double sum2 = 0.0;
                for (int j = 0; j < this.Clusters.Count; j++)
                {
                    U[i, j] = 1.0 / Math.Pow(U[i, j] / sum, 2.0 / (Fuzzyness - 1.0));
                    sum2   += U[i, j];
                }

                for (int j = 0; j < this.Clusters.Count; j++)
                {
                    U[i, j] = U[i, j] / sum2;
                }
            }

            this.RecalculateClusterIndexes();
        }
 /// <summary>
 /// Calculates Euler's distance between point and centroid
 /// </summary>
 /// <param name="p">Point</param>
 /// <param name="c">Centroid</param>
 /// <returns>Calculated distance</returns>
 private double CalculateEulerDistance(ClusterPoint p, ClusterCentroid c)
 {
     return(Math.Sqrt(Math.Pow(p.X - c.X, 2) + Math.Pow(p.Y - c.Y, 2)));
 }