176{
177 double *distances;
178 uint32_t p1 = 0, p2 = 0;
179 uint32_t duplicate_count = 1;
180 double max_dst = -1;
181
182
183 assert(n > 0);
184 if (k < 2)
185 {
186 centers[0] = objs[0];
187 return;
188 }
189
190
191 for (uint32_t i = 1; i < n; i++)
192 {
193
196 if ((dst_p1 > max_dst) || (dst_p2 > max_dst))
197 {
198 if (dst_p1 > dst_p2)
199 {
200 max_dst = dst_p1;
201 p2 = i;
202 }
203 else
204 {
205 max_dst = dst_p2;
206 p1 = i;
207 }
208 }
209 if ((dst_p1 == 0) || (dst_p2 == 0))
210 duplicate_count++;
211 }
212 if (duplicate_count > 1)
214 "%s: there are at least %u duplicate inputs, number of output clusters may be less than you requested",
215 __func__,
216 duplicate_count);
217
218
219 assert(p1 != p2 && max_dst >= 0);
220
221
222 centers[0] = objs[p1];
223 centers[1] = objs[p2];
224
225 if (k > 2)
226 {
227
228 distances =
lwalloc(
sizeof(
double) * n);
229
230
231 for (uint32_t j = 0; j < n; j++)
233 distances[p1] = -1;
234 distances[p2] = -1;
235
236
237 for (uint32_t i = 2; i < k; i++)
238 {
239 uint32_t candidate_center = 0;
240 double max_distance = -DBL_MAX;
241
242
243 for (uint32_t j = 0; j < n; j++)
244 {
245
246 if (distances[j] < 0)
247 continue;
248
249
251 if (current_distance < distances[j])
252 distances[j] = current_distance;
253
254
255 if (distances[j] > max_distance)
256 {
257 candidate_center = j;
258 max_distance = distances[j];
259 }
260 }
261
262
263 assert(max_distance >= 0);
264
265
266 distances[candidate_center] = -1;
267
268
269 centers[i] = objs[candidate_center];
270 }
272 }
273}
void * lwalloc(size_t size)
void lwnotice(const char *fmt,...) __attribute__((format(printf
Write a notice out to the notice handler.
static double distance3d_sqr_pt4d_pt4d(const POINT4D *p1, const POINT4D *p2)