88 Details<Index_> run(
const Matrix_& data, Cluster_ ncenters, Float_* centers, Cluster_* clusters)
const {
89 auto nobs = data.num_observations();
90 if (internal::is_edge_case(nobs, ncenters)) {
91 return internal::process_edge_case(data, ncenters, centers, clusters);
94 int iter = 0, status = 0;
95 std::vector<Index_> sizes(ncenters);
96 std::vector<Cluster_> copy(nobs);
97 auto ndim = data.num_dimensions();
98 internal::QuickSearch<Float_, Cluster_,
decltype(ndim)> index;
101 index.reset(ndim, ncenters, centers);
103 auto work = data.create_workspace(start, length);
104 for (Index_ obs = start, end = start + length; obs < end; ++obs) {
105 auto dptr = data.get_observation(work);
106 copy[obs] = index.find(dptr);
111 bool updated =
false;
112 for (Index_ obs = 0; obs < nobs; ++obs) {
113 if (copy[obs] != clusters[obs]) {
121 std::copy(copy.begin(), copy.end(), clusters);
123 std::fill(sizes.begin(), sizes.end(), 0);
124 for (Index_ obs = 0; obs < nobs; ++obs) {
125 ++sizes[clusters[obs]];
127 internal::compute_centroids(data, ncenters, centers, clusters, sizes);
134 return Details<Index_>(std::move(sizes), iter, status);