aboutsummaryrefslogtreecommitdiff
path: root/km.h
diff options
context:
space:
mode:
Diffstat (limited to 'km.h')
-rw-r--r--km.h126
1 files changed, 104 insertions, 22 deletions
diff --git a/km.h b/km.h
index 0c49832..642560b 100644
--- a/km.h
+++ b/km.h
@@ -2,6 +2,8 @@
#define KM_H
#include <stddef.h> // size_t
+#include <stdint.h> // uint8_t
+#include <stdio.h> // FILE
// forward typedef for callbacks
typedef struct km_rand_src_t_ km_rand_src_t;
@@ -33,9 +35,19 @@ typedef struct {
num_ints;
} km_shape_t;
+typedef enum {
+ KM_SET_STATE_INIT,
+ KM_SET_STATE_NORMALIZED,
+ KM_SET_STATE_FINI,
+ KM_SET_STATE_LAST,
+} km_set_state_t;
+
// data set
typedef struct {
- float *floats;
+ km_set_state_t state;
+
+ float *floats,
+ *bounds;
int *ints;
km_shape_t shape;
@@ -50,14 +62,28 @@ _Bool km_set_init(km_set_t * const, const km_shape_t *, const size_t);
void km_set_fini(km_set_t * const);
// append rows to data set, growing set if necessary
-_Bool km_set_push_rows(km_set_t *, const size_t, const float *, const int *);
+_Bool km_set_push(km_set_t *, const size_t, const float *, const int *);
-// get row from data set
+// normalize data set
+_Bool km_set_normalize(km_set_t * const);
+
+// get pointer to data set row
float *km_set_get_row(const km_set_t *, const size_t);
-// init a cluster set of size N from a data set by picking random
-// cluster centers
-_Bool km_clusters_rand_init(
+typedef struct {
+ float d2;
+ size_t cluster;
+} km_row_map_t;
+
+typedef struct {
+ const float *means;
+ const float *variances;
+ const size_t num_clusters;
+} km_solve_stats_t;
+
+// init a set with num_clusters clusters of shape num_floats by picking
+// random cluster centers
+_Bool km_set_init_rand_clusters(
km_set_t *,
const size_t,
const size_t,
@@ -65,40 +91,96 @@ _Bool km_clusters_rand_init(
);
typedef struct {
- void (*on_step)(const km_set_t *, void *);
- void (*on_means)(const km_set_t *, const float *, const size_t, void *);
-} km_clusters_solve_cbs_t;
+ void (*on_step)(const km_set_t *, const km_row_map_t *, void *);
+ void (*on_stats)(const km_set_t *, const km_solve_stats_t *, void *);
+} km_solve_cbs_t;
// use k-means to iteratively update the cluster centroids until there
// are no more changes to the centroids
_Bool
-km_clusters_solve(
+km_solve(
km_set_t * const,
const km_set_t * const,
- const km_clusters_solve_cbs_t * const,
+ const km_solve_cbs_t * const,
void * const
);
typedef struct {
const km_set_t * const cluster_set;
- const size_t num_clusters;
- const float mean_distance;
- const size_t num_empty_clusters;
-} km_search_row_t;
-typedef void (*km_search_row_cb_t)(
- const km_search_row_t * const,
+ const float mean_distance,
+ mean_variance,
+ mean_cluster_size;
+
+ const size_t num_clusters,
+ num_empty_clusters;
+} km_find_data_t;
+
+typedef _Bool (*km_find_init_cb_t)(
+ km_set_t * const cluster_set,
+ const size_t num_floats,
+ const size_t num_clusters,
+ void *cb_data
+);
+
+typedef _Bool (*km_find_fini_cb_t)(
+ km_set_t * const cluster_set,
+ void *cb_data
+);
+
+typedef void (*km_find_data_cb_t)(
+ const km_find_data_t * const,
void *
);
+typedef struct {
+ size_t max_clusters;
+ size_t num_tests;
+ km_rand_src_t *rand_src;
+
+ km_find_init_cb_t on_init;
+ km_find_fini_cb_t on_fini;
+ km_find_data_cb_t on_data;
+} km_find_cbs_t;
+
// repeatedly test different cluster sizes and report results
_Bool
-km_search(
+km_find(
const km_set_t * const set,
- const size_t max_clusters,
- const size_t num_tests,
- const km_search_row_cb_t on_row,
- void *cb_data
+ const km_find_cbs_t * const cbs,
+ void * const cb_data
+);
+
+// render set to rgb buffer
+void
+km_set_draw(
+ const km_set_t * const set,
+ uint8_t * const rgb,
+ const size_t width,
+ const size_t height,
+ const uint32_t color
+);
+
+// load callbacks
+typedef struct {
+ _Bool (*on_shape)(const km_shape_t * const, void *);
+ _Bool (*on_row)(const float *, const int *, void *);
+ void (*on_error)(const char * const, void *);
+} km_load_cbs_t;
+
+// load set from file
+_Bool
+km_load(
+ FILE * const fh,
+ const km_load_cbs_t * const cbs,
+ void * const cb_data
+);
+
+_Bool
+km_load_path(
+ const char * const path,
+ const km_load_cbs_t * const cbs,
+ void * const cb_data
);
#endif /* KM_H */