diff options
-rw-r--r-- | README.md | 26 | ||||
-rw-r--r-- | src/main.c | 88 |
2 files changed, 40 insertions, 74 deletions
@@ -1,8 +1,24 @@ KMeans Classifier Implementation -Example: - # generate test data with 1000 rows clustered around 3 points - ./gen-data.rb 1000 3 > example.dat +Examples: - # classify data, plot results as png - ./km-test kmeans example.dat example.png +Generate 1000 rows of test data, clustered around 3 points: + + # generate test data + ./gen-data.rb 1000 3 > example.dat + + # classify data, plot results as png + ./km-test kmeans example.dat example.png + +Run all tests and save best clustering in current directory along with +PNGs of results: + + for i in tests/*dat; do + # build paths + png_path=kmeans-$(basename ${i/dat/png}) + dst_path=kmeans-$(basename $i) + + # run test + echo $i + ./km-test kmeans $i $png_path > $dst_path + done @@ -13,7 +13,7 @@ #include "km.h" #define MAX_CLUSTERS 10 -#define NUM_TESTS 300 +#define NUM_TESTS 100 #define MAX_BEST 10 #define IM_WIDTH 128 @@ -75,19 +75,21 @@ ctx_best_sort( ); } -static void -ctx_best_walk( - const ctx_t * const ctx, - void (*on_best)(const km_set_t * const, const size_t, const float, void *), - void * const cb_data -) { - if (on_best) { - // walk best sets and emit each one - for (size_t i = 0; i < ctx_get_max_best(ctx); i++) { - on_best(&(ctx->best[i].set), i, ctx->best[i].score, cb_data); - } - } -} +/* + * static void + * ctx_best_walk( + * const ctx_t * const ctx, + * void (*on_best)(const km_set_t * const, const size_t, const float, void *), + * void * const cb_data + * ) { + * if (on_best) { + * // walk best sets and emit each one + * for (size_t i = 0; i < ctx_get_max_best(ctx); i++) { + * on_best(&(ctx->best[i].set), i, ctx->best[i].score, cb_data); + * } + * } + * } + */ static bool load_on_shape( @@ -224,31 +226,6 @@ FIND_CBS = { static uint8_t im_data[3 * IM_WIDTH * IM_HEIGHT]; static void -save_on_best( - const km_set_t * const set, - const size_t rank, - const float score, - void * const cb_data -) { - const ctx_t * const ctx = cb_data; - const bool is_best = (rank == ctx_get_max_best(ctx) - 1); - UNUSED(score); - - // convert rank to channel brightness - if (is_best) { - // draw best in green - km_set_draw(set, im_data, IM_WIDTH, IM_HEIGHT, 3, 0x00ff00); - } else if (false) { - // draw lower-ranked "best" results - const uint8_t ch = 0x33 + (0xff - 0x33) * (1.0 * rank + 1) / (MAX_BEST); - const uint32_t color = (ch & 0xff) << 16; - - // draw clusters - km_set_draw(set, im_data, IM_WIDTH, IM_HEIGHT, 2, color); - } -} - -static void ctx_save_png( const ctx_t * const ctx, const char * const png_path, @@ -263,8 +240,9 @@ ctx_save_png( die("stbi_write_png(\"%s\")", png_path); } - // draw best cluster points - ctx_best_walk(ctx, save_on_best, (void*) ctx); + // draw best centroids in green + const km_set_t * const best_set = &(ctx->best[ctx_get_max_best(ctx) - 1].set); + km_set_draw(best_set, im_data, IM_WIDTH, IM_HEIGHT, 3, 0x00ff00); // save png if (!stbi_write_png(png_path, IM_WIDTH, IM_HEIGHT, 3, im_data, IM_STRIDE)) { @@ -272,31 +250,6 @@ ctx_save_png( } } -/* - * static void - * ctx_best_print_on_best( - * const km_set_t * const set, - * const size_t rank, - * const float score, - * void * const cb_data - * ) { - * FILE * const fh = cb_data; - * - * fprintf(fh, "rank = %zu, score = %0.3f, num_clusters = %zu: [\n", rank, score, set->num_rows); - * for (size_t i = 0; i < set->num_rows; i++) { - * const float * const vals = km_set_get_row(set, i); - * fprintf(fh, " ["); - * - * for (size_t j = 0; j < set->shape.num_floats; j++) { - * fprintf(fh, "%s%0.3f", (j > 0) ? ", " : "", vals[j]); - * } - * - * fprintf(fh, "], (%d rows)\n", set->ints[i]); - * } - * fprintf(fh, "]\n"); - * } - */ - static void ctx_best_print( const ctx_t * const ctx, @@ -355,9 +308,6 @@ int main(int argc, char *argv[]) { die("km_find()"); } - // print csv - // ctx_csv_print(&ctx, stdout); - // sort best results from lowest to highest ctx_best_sort(&ctx); |