///------------------------------------------------------------------------------------------------- /// <summary> Map partition. </summary> /// /// <remarks> Chris Rossbach ([email protected]), 8/7/2012. </remarks> /// /// <param name="partition"> The partition. </param> ///------------------------------------------------------------------------------------------------- public static void MapPartition( object oPartition ) { KMeansMapPartition partition = oPartition as KMeansMapPartition; while (!m_bMapPhasesComplete) { partition.m_newCenters = KMeansCalculator.CreateCenterAccumulatorList(partition.m_nCenters, partition.m_nRank); partition.m_newGroupCounts = KMeansCalculator.CreateGroupCountList(partition.m_nCenters, partition.m_nRank); partition.m_fDelta = 0.0f; partition.m_evtMapWorkAvailable.WaitOne(); if (!m_bMapPhasesComplete) { for (int i = partition.m_nStartIndex; i < partition.m_nPartitionSize; i++) { Vector vec = partition.m_vectors.ElementAt(i); int nIndex = FindNearestCenter(vec, partition.m_oldCenters); if (partition.m_clusterIds.ElementAt(i) != nIndex) { partition.m_fDelta += 1.0f; } partition.m_clusterIds[i] = nIndex; partition.m_newCenters[nIndex] += vec; partition.m_newGroupCounts[nIndex] += 1; } partition.m_barrier.SignalAndWait(); } } }
///------------------------------------------------------------------------------------------------- /// <summary> Updates the centers. </summary> /// /// <remarks> Chris Rossbach ([email protected]), 8/7/2012. </remarks> /// /// <param name="update"> The update. </param> ///------------------------------------------------------------------------------------------------- public static void UpdateCenters( object oUpdate ) { KMeansUpdateCenters update = oUpdate as KMeansUpdateCenters; update.m_nIterations = 0; while (!m_bUpdatePhasesComplete) { update.m_sharedCenters = KMeansCalculator.CreateCenterAccumulatorList(update.m_nCenters, update.m_nRank); update.m_sharedGroupCounts = KMeansCalculator.CreateGroupCountList(update.m_nCenters, update.m_nRank); update.m_fDelta = 0.0f; update.m_evtMapWorkComplete.WaitOne(); if (m_bVerbose) { Console.WriteLine("update..."); } for (int w = 0; w < update.m_workers.Count(); w++) { KMeansMapPartition worker = update.m_workers[w]; update.m_fDelta += worker.m_fDelta; for (int i = 0; i < update.m_nCenters; i++) { update.m_sharedCenters[i] += worker.m_newCenters[i]; update.m_sharedGroupCounts[i] += worker.m_newGroupCounts[i]; } } for (int i = 0; i < update.m_nCenters; i++) { update.m_sharedCenters[i] /= update.m_sharedGroupCounts[i]; } update.m_fDelta /= update.m_nPoints; update.m_nIterations++; if (update.m_nIterations < update.m_options.m_nMaxIterations && update.m_fDelta >= update.m_options.m_fConvergenceThreshold) { for (int w = 0; w < update.m_workers.Count(); w++) { update.m_workers[w].m_oldCenters = update.m_sharedCenters; } update.m_evtMapWorkComplete.Reset(); update.m_evtMapWorkAvailable.Set(); } else { m_bMapPhasesComplete = true; m_bUpdatePhasesComplete = true; update.m_evtMapWorkAvailable.Set(); // shouldn't be needed, but harmless return; } } }