24 for (
int i = 0; i <
n; i++)
31 KM_ASSERT(bound_v1 != 0 && bound_v2 != 0);
34 for (
int i = 1; i <
n; i++)
35 for (
int j = 0; j < d; j++) {
58 memset(bad_center, 0xff,
d_ *
sizeof(
Scalar));
62 int *counts = (
int*)calloc(k,
sizeof(
int));
63 int num_candidates = 0;
64 int *candidates = (
int*)malloc(k *
sizeof(
int));
65 KM_ASSERT(sums != 0 && counts != 0 && candidates != 0);
66 for (
int i = 0; i < k; i++)
67 if (memcmp(centers + i*
d_, bad_center,
d_ *
sizeof(
Scalar)) != 0)
68 candidates[num_candidates++] = i;
75 for (
int i = 0; i < k; i++) {
97 char **next_node_data) {
99 Node *node = (
Node*)(*next_node_data);
100 (*next_node_data) +=
sizeof(
Node);
102 (*next_node_data) +=
sizeof(
Scalar) *
d_;
104 (*next_node_data) +=
sizeof(
Scalar) *
d_;
106 (*next_node_data) +=
sizeof(
Scalar) *
d_;
109 node->
num_points = (last_index - first_index + 1);
116 KM_ASSERT(bound_p1 != 0 && bound_p2 != 0);
119 for (
int i = first_index+1; i <= last_index; i++)
120 for (
int j = 0; j <
d_; j++) {
122 if (bound_p1[j] >
c) bound_p1[j] =
c;
123 if (bound_p2[j] <
c) bound_p2[j] =
c;
129 for (
int j = 0; j <
d_; j++) {
130 node->
median[j] = (bound_p1[j] + bound_p2[j]) / 2;
131 node->
radius[j] = (bound_p2[j] - bound_p1[j]) / 2;
132 if (node->
radius[j] > max_radius) {
133 max_radius = node->
radius[j];
141 if (max_radius == 0) {
144 if (last_index != first_index)
154 int i1 = first_index, i2 = last_index, size1 = 0;
158 if (!is_i1_good && !is_i2_good) {
162 is_i1_good = is_i2_good =
true;
174 KM_ASSERT(size1 >= 1 && size1 <= last_index - first_index);
204 for (
int i = 0; i <
d_; i++) {
219 Scalar *sums,
int *counts,
int *assignment)
const {
222 int closest_i = candidates[0];
223 for (
int i = 1; i < k; i++) {
225 if (dist_sq < min_dist_sq) {
226 min_dist_sq = dist_sq;
227 closest_i = candidates[i];
235 int *new_candidates = (
int*)malloc(k *
sizeof(
int));
237 for (
int i = 0; i < k; i++)
239 new_candidates[new_k++] = candidates[i];
244 sums, counts, assignment) +
246 sums, counts, assignment);
247 free(new_candidates);
250 free(new_candidates);
257 if (assignment != 0) {
274 int best_index,
int test_index)
const {
275 if (best_index == test_index)
278 Scalar *best = centers + best_index*
d_;
279 Scalar *test = centers + test_index*
d_;
281 for (
int i = 0; i <
d_; i++) {
282 Scalar component = test[i] - best[i];
283 lhs += component * component;
285 rhs += (box_median[i] + box_radius[i] - best[i]) * component;
287 rhs += (box_median[i] - box_radius[i] - best[i]) * component;
289 return (lhs >= 2*rhs);
301 for (
int j = 0; j <
n_; j++) {
303 total_cost += dist_sq[j];
307 for (
int new_cluster = 1; new_cluster < k; new_cluster++) {
309 Scalar cutoff = (rand() /
Scalar(RAND_MAX)) * total_cost;
311 for (i = 0; i <
n_; i++) {
312 cur_cost += dist_sq[i];
313 if (cur_cost >= cutoff)
363 if (i1 == i2 && i1 != -1)
void BASE_IMPEXP memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) MRPT_NO_THROWS
An OS and compiler independent version of "memcpy".
KmTree(int n, int d, Scalar *points)
Scalar * PointAllocate(int d)
void PointCopy(Scalar *p1, const Scalar *p2, int d)
bool ShouldBePruned(Scalar *box_median, Scalar *box_radius, Scalar *centers, int best_index, int test_index) const
GLsizei const GLfloat * points
Scalar GetNodeCost(const Node *node, Scalar *center) const
void PointAdd(Scalar *p1, const Scalar *p2, int d)
void PointScale(Scalar *p, Scalar scale, int d)
Scalar DoKMeansStep(int k, Scalar *centers, int *assignment) const
Scalar SeedKmppUpdateAssignment(const Node *node, int new_cluster, Scalar *centers, Scalar *dist_sq) const
#define KM_ASSERT(expression)
Scalar DoKMeansStepAtNode(const Node *node, int k, int *candidates, Scalar *centers, Scalar *sums, int *counts, int *assignment) const
Scalar SeedKMeansPlusPlus(int k, Scalar *centers) const
Node * BuildNodes(Scalar *points, int first_index, int last_index, char **next_node_data)
GLsizei const GLfloat * value
void PointFree(Scalar *p)
Scalar PointDistSq(const Scalar *p1, const Scalar *p2, int d)
void SeedKmppSetClusterIndex(const Node *node, int index) const