/// <summary> /// Recalculates the statistics. /// </summary> /// <param name="core">Core</param> /// <param name="metric">Metric for statistics</param> /// <param name="statistics">What to calculate</param> /// <param name="prog">Report progress to</param> /// <param name="vmatrix">Value matrix</param> /// <param name="dmatrix">Distance matrix (optional - if not present will be calculated if necessary)</param> internal void RecalculateStatistics(Core core, ConfigurationMetric metric, IntensityMatrix vmatrix, DistanceMatrix dmatrix, EClustererStatistics statistics, ProgressReporter prog) { // Add basics ClustererStatistics[STAT_NUM_VECTORS] = vmatrix.NumRows; ClustererStatistics[STAT_LENGTH_OF_VECTORS] = vmatrix.NumCols; // Don't calculate metrics? if (statistics == EClustererStatistics.None) { return; } // Get the non-insig clusters Cluster[] realClusters = RealClusters.ToArray(); // If we don't have a DMatrix we should calculate the sil. width manually // The DMatrix might be too big to pass to R so its better just to avoid it. prog.Enter("Calculating statistics"); List <ObsFilter> groupFilters = new List <ObsFilter>(); // No filter groupFilters.Add(null); if (!vmatrix.HasSplitGroups) { // Defined filters if (statistics.HasFlag(EClustererStatistics.IncludePartialVectorsForFilters)) { groupFilters.AddRange(core.ObsFilters); } // Group filters (if not already) if (statistics.HasFlag(EClustererStatistics.IncludePartialVectorsForGroups)) { AllGroupsFilters(core, groupFilters); } } List <ForStat> needsCalculating = new List <ForStat>(); prog.Enter("Input vectors"); ProgressParallelHandler progP = prog.CreateParallelHandler(groupFilters.Count); ProgressParallelHandler closure1 = progP; Parallel.ForEach(groupFilters, obsFilter => Thread_AddFilterToCalculationList(core, metric, vmatrix, dmatrix, statistics, realClusters, obsFilter, needsCalculating, closure1)); prog.Leave(); // ASSIGNMENT STATS prog.Enter("Assignments"); progP = prog.CreateParallelHandler(needsCalculating.Count); ProgressParallelHandler closure2 = progP; Parallel.ForEach(needsCalculating, z => Thread_CalculateAssignmentStatistics(statistics, z, realClusters, metric, closure2)); prog.Leave(); // CLUSTER STATS prog.Enter("Clusters"); progP = prog.CreateParallelHandler(this.Clusters.Length); Parallel.ForEach(this.Clusters, z => Thread_CalculateClusterStatistics(core, statistics, z, progP)); prog.Leave(); // SUMMARY STATS prog.Enter("Summary"); CalculateSummaryStatistics(core, statistics, realClusters); prog.Leave(); prog.Leave(); }