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);
}
|