diff options
author | Paul Duncan <pabs@pablotron.org> | 2019-02-03 21:12:11 -0500 |
---|---|---|
committer | Paul Duncan <pabs@pablotron.org> | 2019-02-03 21:12:11 -0500 |
commit | 0f544be878f72b09d516a64c60e3cbd66f7cfd81 (patch) | |
tree | adb9868e1b45494f83abac8420107864b009e271 /km-init.c | |
parent | 33a722132491ebdd31722f0cada0f81f6b082282 (diff) | |
download | kmeans-0f544be878f72b09d516a64c60e3cbd66f7cfd81.tar.bz2 kmeans-0f544be878f72b09d516a64c60e3cbd66f7cfd81.zip |
add km_init(), refactor existing init
Diffstat (limited to 'km-init.c')
-rw-r--r-- | km-init.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/km-init.c b/km-init.c new file mode 100644 index 0000000..f04fca0 --- /dev/null +++ b/km-init.c @@ -0,0 +1,80 @@ +#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 *); + +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, +}}; + +#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); +} |