diff options
Diffstat (limited to 'src/km-init.c')
-rw-r--r-- | src/km-init.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/km-init.c b/src/km-init.c new file mode 100644 index 0000000..280ea81 --- /dev/null +++ b/src/km-init.c @@ -0,0 +1,85 @@ +#include <stdbool.h> // bool +#include <stddef.h> // size_t +#include <string.h> // 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); +} |