25 #define LOG(verbose, text) \ 27 vector<ostream*>& outputs = \ 28 (verbose ? gVerboseLogOutputs : gLogOutputs); \ 29 if (outputs.size() > 0) \ 31 ostringstream string_stream; \ 32 string_stream << text; \ 33 for (int i = 0; i < (int)outputs.size(); i++) \ 34 *(outputs[i]) << string_stream.str(); \ 49 static double GetSeconds() {
return double(clock()) / CLOCKS_PER_SEC; }
59 double* min_time,
double* max_time,
double* total_time,
60 Scalar* best_centers,
int* best_assignment)
70 for (
int iteration = 0; !is_done; iteration++)
73 is_done = (iteration > 0 && new_cost >= (1 - kEpsilon) * old_cost);
75 LOG(
true,
"Completed iteration #" << (iteration + 1) <<
", cost=" 76 << new_cost <<
"..." << endl);
81 LOG(
false,
"Completed run: cost=" << old_cost <<
" (" << this_time
82 <<
" seconds)" << endl);
86 if (*min_cost < 0 || old_cost < *min_cost)
89 if (best_assignment != 0)
91 if (best_centers != 0)
96 if (*max_cost < old_cost) *max_cost = old_cost;
97 *total_cost += old_cost;
98 if (*min_time < 0 || *min_time > this_time) *min_time = this_time;
99 if (*max_time < this_time) *max_time = this_time;
100 *total_time += this_time;
106 double max_time,
double total_time,
int num_attempts)
108 LOG(
false,
"Aggregate info over " << num_attempts <<
" runs:" << endl);
109 LOG(
false,
" Cost: min=" << min_cost
110 <<
" average=" << (total_cost / num_attempts)
111 <<
" max=" << max_cost << endl);
112 LOG(
false,
" Time: min=" << min_time
113 <<
" average=" << (total_time / num_attempts)
114 <<
" max=" << max_time << endl
126 LOG(
false,
"Running k-means..." << endl);
128 LOG(
false,
"Done preprocessing..." << endl);
132 int* unused_centers = (
int*)malloc(
sizeof(
int) *
n);
133 KM_ASSERT(centers != 0 && unused_centers != 0);
134 Scalar min_cost = -1, max_cost = -1, total_cost = 0;
135 double min_time = -1, max_time = -1, total_time = 0;
140 memset(centers +
n * d, -1, (k - d) *
sizeof(
Scalar));
145 for (
int attempt = 0; attempt < attempts; attempt++)
150 for (
int i = 0; i <
n; i++) unused_centers[i] = i;
151 int num_unused_centers =
n;
152 for (
int i = 0; i < k; i++)
156 centers + i * d,
points + unused_centers[j] * d,
158 unused_centers[j] = unused_centers[num_unused_centers];
163 tree,
n, k, d,
points, centers, &min_cost, &max_cost, &total_cost,
164 start_time, &min_time, &max_time, &total_time, ret_centers,
168 min_cost, max_cost, total_cost, min_time, max_time, total_time,
172 free(unused_centers);
185 LOG(
false,
"Running k-means++..." << endl);
187 LOG(
false,
"Done preprocessing..." << endl);
192 Scalar min_cost = -1, max_cost = -1, total_cost = 0;
193 double min_time = -1, max_time = -1, total_time = 0;
196 for (
int attempt = 0; attempt < attempts; attempt++)
205 tree,
n, k, d,
points, centers, &min_cost, &max_cost, &total_cost,
206 start_time, &min_time, &max_time, &total_time, ret_centers,
210 min_cost, max_cost, total_cost, min_time, max_time, total_time,
Scalar RunKMeans(int n, int k, int d, Scalar *points, int attempts, Scalar *ret_centers, int *ret_assignment)
GLsizei const GLfloat * points
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
#define LOG(verbose, text)
Scalar RunKMeansPlusPlus(int n, int k, int d, Scalar *points, int attempts, Scalar *ret_centers, int *ret_assignment)
Scalar DoKMeansStep(int k, Scalar *centers, int *assignment) const
void ClearKMeansLogging()
static vector< ostream * > gVerboseLogOutputs
#define KM_ASSERT(expression)
Scalar SeedKMeansPlusPlus(int k, Scalar *centers) const
void AddKMeansLogging(std::ostream *out, bool verbose)
static void RunKMeansOnce(const KmTree &tree, int n, int k, int d, Scalar *points, Scalar *centers, Scalar *min_cost, Scalar *max_cost, Scalar *total_cost, double start_time, double *min_time, double *max_time, double *total_time, Scalar *best_centers, int *best_assignment)
static double GetSeconds()
static vector< ostream * > gLogOutputs
void LogMetaStats(Scalar min_cost, Scalar max_cost, Scalar total_cost, double min_time, double max_time, double total_time, int num_attempts)
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".