private void PrecomputeAllDistances() { Parallel.For(0, centroidDistances.Length, i => { for (int j = 0; j < i; j++) { // precompute distance centroidDistances[i][j] = WeightedCentroid.GetDistance(weightedCentroids[i], weightedCentroids[j]); // precompute minimal distance in a row if (centroidDistances[i][j] < rowMinimalDistances[i]) { rowMinimalDistances[i] = centroidDistances[i][j]; rowMinimalDistanceIds[i] = j; } } }); }
private void ComputeNewDistances(int mergedCentroidId, int droppedCentroidId) { // invalidate dropped data rowMinimalDistances[droppedCentroidId] = double.NaN; rowMinimalDistanceIds[droppedCentroidId] = -1; Parallel.For(0, droppedCentroidId, j => { centroidDistances[droppedCentroidId][j] = double.NaN; }); Parallel.For(droppedCentroidId + 1, centroidDistances.Length, i => { centroidDistances[i][droppedCentroidId] = double.NaN; }); // compute new distances and minimal value in mergedId row rowMinimalDistances[mergedCentroidId] = double.MaxValue; Parallel.For(0, mergedCentroidId, j => { if (!isDropped[j]) { centroidDistances[mergedCentroidId][j] = WeightedCentroid.GetDistance(weightedCentroids[j], weightedCentroids[mergedCentroidId]); // update minimal distances if (centroidDistances[mergedCentroidId][j] < rowMinimalDistances[mergedCentroidId]) { rowMinimalDistances[mergedCentroidId] = centroidDistances[mergedCentroidId][j]; rowMinimalDistanceIds[mergedCentroidId] = j; } } }); if (rowMinimalDistances[mergedCentroidId] == double.MaxValue) { rowMinimalDistances[mergedCentroidId] = double.NaN; } // compute new distances in mergedId column Parallel.For(mergedCentroidId + 1, centroidDistances.Length, i => { if (!isDropped[i]) { centroidDistances[i][mergedCentroidId] = WeightedCentroid.GetDistance(weightedCentroids[i], weightedCentroids[mergedCentroidId]); // update minimal distances if (centroidDistances[i][mergedCentroidId] < rowMinimalDistances[i]) { rowMinimalDistances[i] = centroidDistances[i][mergedCentroidId]; rowMinimalDistanceIds[i] = mergedCentroidId; } } }); // find new minimal value in the row if the value from dropped column was minimal for (int i = droppedCentroidId + 1; i < centroidDistances.Length; i++) { if (!isDropped[i] && rowMinimalDistanceIds[i] == droppedCentroidId) { rowMinimalDistances[i] = double.MaxValue; rowMinimalDistanceIds[i] = -1; for (int j = 0; j < i; j++) { if (!isDropped[j] && centroidDistances[i][j] < rowMinimalDistances[i]) { rowMinimalDistances[i] = centroidDistances[i][j]; rowMinimalDistanceIds[i] = j; } } if (rowMinimalDistances[i] == double.MaxValue) { rowMinimalDistances[i] = double.NaN; } } } }