kmeans
k-means clustering in C++
Loading...
Searching...
No Matches
remove_unused_centers.hpp
Go to the documentation of this file.
1#ifndef KMEANS_REMOVE_UNUSED_CENTERS_HPP
2#define KMEANS_REMOVE_UNUSED_CENTERS_HPP
3
4#include <vector>
5#include <cstddef>
6#include <algorithm>
7
8#include "sanisizer/sanisizer.hpp"
9
10#include "utils.hpp"
11
17namespace kmeans {
18
47template<typename Index_, typename Cluster_, typename Float_>
49 const std::size_t num_dimensions,
50 const Index_ num_observations,
51 Cluster_* const clusters,
52 const Cluster_ num_centers,
53 Float_* const centers,
54 std::vector<Index_>& sizes
55) {
56 bool has_zero = false;
57 for (Cluster_ c = 0; c < num_centers; ++c) {
58 if (sizes[c] == 0) {
59 has_zero = true;
60 break;
61 }
62 }
63 if (!has_zero) {
64 return num_centers;
65 }
66
67 auto remapping = sanisizer::create<std::vector<Index_> >(num_centers);
68 Cluster_ remaining = 0;
69 for (Cluster_ c = 0; c < num_centers; ++c) {
70 if (sizes[c]) {
71 remapping[c] = remaining;
72 if (remaining != c) {
73 std::copy_n(
74 centers + sanisizer::product_unsafe<std::size_t>(c, num_dimensions),
75 num_dimensions,
76 centers + sanisizer::product_unsafe<std::size_t>(remaining, num_dimensions)
77 );
78 sizes[remaining] = sizes[c];
79 }
80 ++remaining;
81 }
82 }
83
84 // Zeroing the leftovers, just in case.
85 std::fill(sizes.begin() + remaining, sizes.end(), 0);
86 std::fill(
87 centers + sanisizer::product_unsafe<std::size_t>(remaining, num_dimensions),
88 centers + sanisizer::product_unsafe<std::size_t>(num_centers, num_dimensions),
89 0
90 );
91
92 for (Index_ o = 0; o < num_observations; ++o) {
93 clusters[o] = remapping[clusters[o]];
94 }
95
96 return remaining;
97}
98
99}
100
101#endif
Perform k-means clustering.
Definition compute_wcss.hpp:16
Cluster_ remove_unused_centers(const std::size_t num_dimensions, const Index_ num_observations, Cluster_ *const clusters, const Cluster_ num_centers, Float_ *const centers, std::vector< Index_ > &sizes)
Definition remove_unused_centers.hpp:48