aboutsummaryrefslogtreecommitdiff
path: root/src/km-init.c
blob: 280ea8170eedee847c328b1edfe3c976936427e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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);
}