1#ifndef KMEANS_HARTIGAN_WONG_HPP
2#define KMEANS_HARTIGAN_WONG_HPP
11#include "QuickSearch.hpp"
13#include "compute_centroids.hpp"
14#include "is_edge_case.hpp"
130template<
typename Index_>
189template<
typename Float_,
typename Index_,
typename Cluster_>
192 std::vector<Cluster_> best_destination_cluster;
193 std::vector<Index_> cluster_sizes;
195 std::vector<Float_> loss_multiplier;
196 std::vector<Float_> gain_multiplier;
197 std::vector<Float_> wcss_loss;
199 std::vector<UpdateHistory<Index_> > update_history;
201 Index_ optra_steps_since_last_transfer = 0;
204 Workspace(Index_ nobs, Cluster_ ncenters) :
206 best_destination_cluster(nobs),
207 cluster_sizes(ncenters),
208 loss_multiplier(ncenters),
209 gain_multiplier(ncenters),
211 update_history(ncenters)
215template<
typename Data_,
typename Float_,
typename Dim_>
225template<
class Matrix_,
typename Cluster_,
typename Float_>
233 auto nobs =
data.num_observations();
234 typedef typename Matrix_::index_type Index_;
246template<
typename Float_>
251template<
typename Dim_,
typename Data_,
typename Index_,
typename Cluster_,
typename Float_>
286template<
class Matrix_,
typename Cluster_,
typename Float_>
288 auto nobs =
data.num_observations();
294 ++
work.optra_steps_since_last_transfer;
297 if (
work.cluster_sizes[
l1] != 1) {
315 auto l2 =
work.best_destination_cluster[
obs];
360 work.optra_steps_since_last_transfer = 0;
361 work.update_history[
l1].set_optimal(
obs);
362 work.update_history[
l2].set_optimal(
obs);
369 if (
work.optra_steps_since_last_transfer ==
nobs) {
388template<
class Matrix_,
typename Cluster_,
typename Float_>
398 auto nobs =
data.num_observations();
403 typedef decltype(
nobs) Index_;
413 if (
work.cluster_sizes[
l1] != 1) {
434 auto l2 =
work.best_destination_cluster[
obs];
498template<
typename Matrix_ = SimpleMatrix<
double,
int>,
typename Cluster_ =
int,
typename Float_ =
double>
513 typedef typename Matrix_::index_type Index_;
526 auto nobs =
data.num_observations();
528 return internal::process_edge_case(
data,
ncenters, centers, clusters);
531 RefineHartiganWong_internal::Workspace<Float_, Index_, Cluster_>
work(
nobs,
ncenters);
533 RefineHartiganWong_internal::find_closest_two_centers(
data,
ncenters, centers, clusters,
work.best_destination_cluster, my_options.
num_threads);
535 ++
work.cluster_sizes[clusters[
obs]];
537 internal::compute_centroids(
data,
ncenters, centers, clusters,
work.cluster_sizes);
542 work.loss_multiplier[
cen] = (
num > 1 ?
num / (
num - 1) : RefineHartiganWong_internal::big_number<Float_>());
553 auto quick_status = RefineHartiganWong_internal::quick_transfer(
567 internal::compute_centroids(
data,
ncenters, centers, clusters,
work.cluster_sizes);
583 work.optra_steps_since_last_transfer = 0;
Report detailed clustering statistics.
Interface for k-means refinement.
Implements the variance partitioning method of Su and Dy (2007).
Definition InitializeVariancePartition.hpp:164
InitializeVariancePartition()=default
Implements the Hartigan-Wong algorithm for k-means clustering.
Definition RefineHartiganWong.hpp:499
RefineHartiganWong(RefineHartiganWongOptions options)
Definition RefineHartiganWong.hpp:504
RefineHartiganWongOptions & get_options()
Definition RefineHartiganWong.hpp:520
Details< Index_ > run(const Matrix_ &data, Cluster_ ncenters, Float_ *centers, Cluster_ *clusters) const
Definition RefineHartiganWong.hpp:525
RefineHartiganWong()=default
Interface for all k-means refinement algorithms.
Definition Refine.hpp:23
Namespace for k-means clustering.
Definition compute_wcss.hpp:12
void parallelize(int num_workers, Task_ num_tasks, Run_ run_task_range)
Definition parallelize.hpp:28
Utilities for parallelization.
Additional statistics from the k-means algorithm.
Definition Details.hpp:20
Options for RefineHartiganWong.
Definition RefineHartiganWong.hpp:27
bool quit_on_quick_transfer_convergence_failure
Definition RefineHartiganWong.hpp:44
int max_iterations
Definition RefineHartiganWong.hpp:32
int num_threads
Definition RefineHartiganWong.hpp:50
int max_quick_transfer_iterations
Definition RefineHartiganWong.hpp:38