#include // bool #include // size_t #include // strcmp() #include "util.h" #include "km.h" typedef bool (*km_init_fn_t)( km_set_t *, const size_t, const km_set_t *, km_rand_t * ); bool km_init_rand(km_set_t *, const size_t, const km_set_t *, km_rand_t *); bool km_init_forgy(km_set_t *, const size_t, const km_set_t *, km_rand_t *); bool km_init_kmeans(km_set_t *, const size_t, const km_set_t *, km_rand_t *); static const struct { const km_init_type_t type; const char * const name; const km_init_fn_t init; } TYPES[] = {{ .name = "rand", .type = KM_INIT_TYPE_RAND, .init = km_init_rand, }, { .name = "forgy", .type = KM_INIT_TYPE_FORGY, .init = km_init_forgy, }, { .name = "kmeans", .type = KM_INIT_TYPE_KMEANS, .init = km_init_kmeans, }}; #define NUM_TYPES (sizeof(TYPES) / sizeof(TYPES[0])) km_init_type_t km_init_get_type( const char * const s ) { // find init method for (size_t i = 0; i < NUM_TYPES; i++) { if (!strcmp(s, TYPES[i].name)) { // return type return TYPES[i].type; } } // return failure return KM_INIT_TYPE_LAST; } static km_init_fn_t get_init_func( const km_init_type_t type ) { // find init method for (size_t i = 0; i < NUM_TYPES; i++) { if (type == TYPES[i].type) { // return init func return TYPES[i].init; } } // return failure return NULL; } bool km_init( km_set_t * const cs, const km_init_type_t init_type, const size_t num_clusters, const km_set_t * const set, km_rand_t * const rs ) { km_init_fn_t init_fn = get_init_func(init_type); if (!init_fn) { die("unknown cluster init method"); } // call init, return result return init_fn(cs, num_clusters, set, rs); }