/// <summary> /// Gets specified centre. /// </summary> public List <IReadOnlyList <double> > GetCentre(ECentreMode mode, ECandidateMode iMode) { List <IReadOnlyList <double> > centre = new List <IReadOnlyList <double> >(); this.GetCentre(mode, iMode, centre); return(centre); }
/// <summary> /// Assigns peaks to clusters /// A single k-means iteration. /// </summary> public static bool Assign(IntensityMatrix vmatrix, IReadOnlyList <Cluster> toChoose, ECandidateMode source, ConfigurationMetric distanceMetric, ProgressReporter prog) { // Get the current cluster centres prog.SetProgress(0, vmatrix.NumRows); for (int index = 0; index < toChoose.Count; index++) { prog.SetProgress(index, toChoose.Count); toChoose[index].SetCentre(ECentreMode.Average, source); } // Clear the previous assignments Dictionary <Cluster, List <Vector> > previousAssignments = new Dictionary <Cluster, List <Vector> >(); for (int index = 0; index < toChoose.Count; index++) { previousAssignments.Add(toChoose[index], toChoose[index].Assignments.Vectors.ToList()); toChoose[index].Assignments.ClearAll(); } // Detect changes so we know when the algorithm has converged bool somethingChanged = false; // Assign peaks to centres for (int index = 0; index < vmatrix.NumRows; index++) { Vector vec = vmatrix.Vectors[index]; prog.SetProgress(index, vmatrix.NumRows); ClusterScore best = FindClosestCluster(vec.Values, toChoose, distanceMetric); // Something changed? if (!previousAssignments[best.Cluster].Contains(vec)) { somethingChanged = true; } // Create new assignment best.Cluster.Assignments.Add(new Assignment(vec, best.Cluster, best.Score)); } return(somethingChanged); }
/// <summary> /// Calculates cluster centre. /// </summary> private void GetCentre(ECentreMode mode, ECandidateMode iMode, List <IReadOnlyList <double> > centres) { centres.Clear(); IEnumerable <IReadOnlyList <double> > list; int listCount; switch (iMode) { case ECandidateMode.Exemplars: list = this.Exemplars; listCount = this.Exemplars.Count; break; case ECandidateMode.Assignments: list = this.Assignments.Vectors.Select(z => z.Values); listCount = this.Assignments.List.Count; break; default: throw new InvalidOperationException("Invalid switch. 9B5EF96B-53F3-4651-AF7D-60B27475C7B5"); } if (list.IsEmpty()) // check this function { return; } switch (mode) { case ECentreMode.All: ////////////////// // ALL EXEMPLARS { foreach (IReadOnlyList <double> e in list) { centres.Add(e); } } break; case ECentreMode.Average: //////////////////////////// // AVERGE OF ALL EXEMPLARS { int numPoints = list.First().Count; double[] centre = new double[numPoints]; for (int o = 0; o < numPoints; o++) { double total = 0; foreach (IReadOnlyList <double> v in list) { total += v[o]; } centre[o] = total / listCount; } centres.Add(centre); } break; } }
/// <summary> /// Calculates cluster centre. /// </summary> public void SetCentre(ECentreMode mode, ECandidateMode iMode) { this.GetCentre(mode, iMode, this.Centres); }