aboutsummaryrefslogtreecommitdiff
path: root/km-init.c
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2019-02-03 21:12:11 -0500
committerPaul Duncan <pabs@pablotron.org>2019-02-03 21:12:11 -0500
commit0f544be878f72b09d516a64c60e3cbd66f7cfd81 (patch)
treeadb9868e1b45494f83abac8420107864b009e271 /km-init.c
parent33a722132491ebdd31722f0cada0f81f6b082282 (diff)
downloadkmeans-0f544be878f72b09d516a64c60e3cbd66f7cfd81.tar.bz2
kmeans-0f544be878f72b09d516a64c60e3cbd66f7cfd81.zip
add km_init(), refactor existing init
Diffstat (limited to 'km-init.c')
-rw-r--r--km-init.c80
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);
+}