Files
secondo/Algebras/ImageSimilarity/fast_kmeans/naive_kernel_kmeans.cpp
2026-01-23 17:03:45 +08:00

88 lines
2.3 KiB
C++

/*
----
This file is NOT part of SECONDO.
Authors: Greg Hamerly and Jonathan Drake
Feedback: hamerly@cs.baylor.edu
See: http://cs.baylor.edu/~hamerly/software/kmeans.php
Copyright 2014
----
//paragraph [1] Title: [{\Large \bf \begin{center}] [\end{center}}]
//[TOC] [\tableofcontents]
[1] Implementation of the naive kernel kmeans algorithm
1 Implementation of the naive kernel kmeans algorithm
*/
/* Authors: Greg Hamerly and Jonathan Drake
* Feedback: hamerly@cs.baylor.edu
* See: http://cs.baylor.edu/~hamerly/software/kmeans.php
* Copyright 2014
*/
#include "naive_kernel_kmeans.h"
#include <algorithm>
#include <iterator>
int NaiveKernelKmeans::runThread(int threadId, int maxIterations) {
int iterations = 0;
int startNdx = start(threadId);
int endNdx = end(threadId);
while ((iterations < maxIterations) && ! converged) {
++iterations;
bool membershipChanged = false;
// precompute the (kernelized) inner product of each center with itself
computeMemberships(threadId, &memberships, &cc);
// we have converged... until we find out we haven't
if (threadId == 0) {
converged = true;
}
synchronizeAllThreads();
// loop over all records
for (int i = startNdx; i < endNdx; ++i) {
unsigned short closest = assignment[i];
double currentDist2 = pointCenterDist2(i, closest);
// now update the lower bound by looking at all other centers
for (int j = 0; j < k; ++j) {
if (j == closest) {
continue;
}
double dist2 = pointCenterDist2(i, j);
if (dist2 < currentDist2) {
closest = j;
currentDist2 = dist2;
}
}
// if the assignment for i has changed, then adjust the counts and
// locations of each center's accumulated mass
if (assignment[i] != closest) {
assignment[i] = closest;
membershipChanged = true;
}
}
verifyAssignment(iterations, startNdx, endNdx);
if (membershipChanged) {
setConverged(false);
}
synchronizeAllThreads();
}
return iterations;
}