public void SetCentroidsAsMeansHighDimensionality() { foreach (Cluster Clust in clusters) { Clust.SetCentroidAsMean(true); } }
public void SetCentroidsAsMeans() { foreach (Cluster Clust in clusters) { Clust.SetCentroidAsMean(); } }
public override void IterateOnce() { double AlphaI = 0; double AlphaJ = 0; double Beta = 0; double Gamma = 0; int Winner; if (!stopped) { if (clusters.Count > 1) { DenseMatrix InterimMatrix = new DenseMatrix(currentDistanceMatrix.RowCount); currentDistanceMatrix.CopyTo(InterimMatrix); Cluster[] InterimClusters = new Cluster[clusters.Count]; Parallel.For(0, clusters.Count, i => { InterimClusters[i] = (Cluster)clusters[i].Clone(); }); List <Cluster> InterimClusterList = InterimClusters.ToList <Cluster>(); Tuple <int, int, double> CurrentMinimumDistance = new Tuple <int, int, double>(0, 0, 0); Parallel.ForEach <Tuple <int, int, double> >(currentDistanceMatrix.EnumerateIndexed(), CurrentTuple => { if (CurrentTuple.Item3 == nextDistance) { CurrentMinimumDistance = CurrentTuple; } }); switch (style) //this loops initialises coefficient values for the lance williams algorithm - this is within the iterate once method //as some styles require iterative recalculation { case HACDistanceStyle.Centroid: AlphaI = calculateMeanAlpha(clusters[CurrentMinimumDistance.Item1], clusters[CurrentMinimumDistance.Item2]); AlphaJ = calculateMeanAlpha(clusters[CurrentMinimumDistance.Item2], clusters[CurrentMinimumDistance.Item1]); Beta = calculateCentroidBeta(clusters[CurrentMinimumDistance.Item1], clusters[CurrentMinimumDistance.Item2]); Gamma = 0; break; case HACDistanceStyle.CLink: AlphaI = 0.5; AlphaJ = 0.5; Beta = 0; Gamma = 0.5; break; case HACDistanceStyle.MeanDist: AlphaI = calculateMeanAlpha(clusters[CurrentMinimumDistance.Item1], clusters[CurrentMinimumDistance.Item2]); AlphaJ = calculateMeanAlpha(clusters[CurrentMinimumDistance.Item2], clusters[CurrentMinimumDistance.Item1]); Beta = 0; Gamma = 0; break; case HACDistanceStyle.SLink: AlphaI = 0.5; AlphaJ = 0.5; Beta = 0; Gamma = -0.5; break; case HACDistanceStyle.Ward: //has to be implemented inside matrix update loop //as requires values for cluster k break; } //handle cluster merging in list InterimClusterList[CurrentMinimumDistance.Item1].Merge(InterimClusterList[CurrentMinimumDistance.Item2]); InterimClusterList.RemoveAt(CurrentMinimumDistance.Item2); updateClusterIndexes(InterimClusterList); //handles removal of subsumed cluster's distances from distance matrix if (CurrentMinimumDistance.Item1 < CurrentMinimumDistance.Item2) { Winner = CurrentMinimumDistance.Item1; } else { //if the item 1 value is further down the distances matrix than the row/column to be removed Winner = CurrentMinimumDistance.Item1 - 1; } InterimMatrix = (DenseMatrix)InterimMatrix.RemoveColumn(CurrentMinimumDistance.Item2).RemoveRow(CurrentMinimumDistance.Item2); Parallel.For(0, InterimMatrix.RowCount, i => { //recalculate distances from new cluster to all other clusters if (style == HACDistanceStyle.Ward) { AlphaI = calculateWardAlpha(clusters[CurrentMinimumDistance.Item1], clusters[CurrentMinimumDistance.Item2], clusters[i]); AlphaJ = calculateWardAlpha(clusters[CurrentMinimumDistance.Item2], clusters[CurrentMinimumDistance.Item1], clusters[i]); Beta = calculateWardBeta(clusters[CurrentMinimumDistance.Item1], clusters[CurrentMinimumDistance.Item2], clusters[i]); Gamma = 0; } double DistanceIJ = nextDistance; double DistanceIK = currentDistanceMatrix[CurrentMinimumDistance.Item1, i]; double DistanceJK = currentDistanceMatrix[CurrentMinimumDistance.Item2, i]; InterimMatrix[Winner, i] = runLanceWilliamsEquation(DistanceIK, DistanceJK, DistanceIJ, AlphaI, AlphaJ, Beta, Gamma); InterimMatrix[i, Winner] = InterimMatrix[Winner, i]; InterimMatrix[Winner, Winner] = artificialMax; }); lastDistance = nextDistance; nextDistance = InterimMatrix.Values.Min(); if (!stopped) { currentDistanceMatrix = (DenseMatrix)InterimMatrix.Clone(); double XValue = InterimClusterList[Winner].XValue; Tuple <string, string, double, double> ThisDendroEntry = new Tuple <string, string, double, double>(clusters[CurrentMinimumDistance.Item1].ClusterID, clusters[CurrentMinimumDistance.Item2].ClusterID, lastDistance, XValue); dendrogram.Add(ThisDendroEntry); clusters = InterimClusterList; iterator++; stopped = StoppingConditionMet(); } else { Parallel.ForEach(clusters, Clust => { Clust.SetCentroidAsMean(); }); stopped = true; } } else { stopped = true; } } else { Parallel.ForEach(clusters, Clust => { Clust.SetCentroidAsMean(); }); } }