24 #define LOG(verbose, text) \ 26 vector<ostream*>& outputs = \ 27 (verbose ? gVerboseLogOutputs : gLogOutputs); \ 28 if (outputs.size() > 0) \ 30 ostringstream string_stream; \ 31 string_stream << text; \ 32 for (int i = 0; i < (int)outputs.size(); i++) \ 33 *(outputs[i]) << string_stream.str(); \ 48 static double GetSeconds() {
return double(clock()) / CLOCKS_PER_SEC; }
58 double* min_time,
double* max_time,
double* total_time,
59 Scalar* best_centers,
int* best_assignment)
69 for (
int iteration = 0; !is_done; iteration++)
72 is_done = (iteration > 0 && new_cost >= (1 - kEpsilon) * old_cost);
74 LOG(
true,
"Completed iteration #" << (iteration + 1) <<
", cost=" 75 << new_cost <<
"..." << endl);
80 LOG(
false,
"Completed run: cost=" << old_cost <<
" (" << this_time
81 <<
" seconds)" << endl);
85 if (*min_cost < 0 || old_cost < *min_cost)
88 if (best_assignment !=
nullptr)
90 if (best_centers !=
nullptr)
95 if (*max_cost < old_cost) *max_cost = old_cost;
96 *total_cost += old_cost;
97 if (*min_time < 0 || *min_time > this_time) *min_time = this_time;
98 if (*max_time < this_time) *max_time = this_time;
99 *total_time += this_time;
105 double max_time,
double total_time,
int num_attempts)
107 LOG(
false,
"Aggregate info over " << num_attempts <<
" runs:" << endl);
108 LOG(
false,
" Cost: min=" << min_cost
109 <<
" average=" << (total_cost / num_attempts)
110 <<
" max=" << max_cost << endl);
111 LOG(
false,
" Time: min=" << min_time
112 <<
" average=" << (total_time / num_attempts)
113 <<
" max=" << max_time << endl
125 LOG(
false,
"Running k-means..." << endl);
127 LOG(
false,
"Done preprocessing..." << endl);
130 auto* centers = (
Scalar*)malloc(
sizeof(
Scalar) * k * d);
131 int* unused_centers = (
int*)malloc(
sizeof(
int) *
n);
132 KM_ASSERT(centers !=
nullptr && unused_centers !=
nullptr);
133 Scalar min_cost = -1, max_cost = -1, total_cost = 0;
134 double min_time = -1, max_time = -1, total_time = 0;
139 memset(centers +
n * d, -1, (k - d) *
sizeof(
Scalar));
144 for (
int attempt = 0; attempt < attempts; attempt++)
149 for (
int i = 0; i <
n; i++) unused_centers[i] = i;
150 int num_unused_centers =
n;
151 for (
int i = 0; i < k; i++)
155 centers + i * d,
points + unused_centers[j] * d,
157 unused_centers[j] = unused_centers[num_unused_centers];
162 tree,
n, k, d,
points, centers, &min_cost, &max_cost, &total_cost,
163 start_time, &min_time, &max_time, &total_time, ret_centers,
167 min_cost, max_cost, total_cost, min_time, max_time, total_time,
171 free(unused_centers);
184 LOG(
false,
"Running k-means++..." << endl);
186 LOG(
false,
"Done preprocessing..." << endl);
189 auto* centers = (
Scalar*)malloc(
sizeof(
Scalar) * k * d);
191 Scalar min_cost = -1, max_cost = -1, total_cost = 0;
192 double min_time = -1, max_time = -1, total_time = 0;
195 for (
int attempt = 0; attempt < attempts; attempt++)
204 tree,
n, k, d,
points, centers, &min_cost, &max_cost, &total_cost,
205 start_time, &min_time, &max_time, &total_time, ret_centers,
209 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 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
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
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".