From b07e03a171359c44b7e4fc2e40e318bcf501efa8 Mon Sep 17 00:00:00 2001 From: Boris Stefanovic <owldev@bluewin.ch> Date: Tue, 7 Jun 2022 16:04:08 +0200 Subject: [PATCH] EDIT: points do not need to know the cluster they belong to --- src/cluster.c | 14 ++++++++------ src/cluster.h | 5 ++--- src/kmeans.c | 22 +++++++++++----------- src/kmeans.h | 8 ++++---- src/linkedlist.c | 43 ++++++++++++++++++++----------------------- src/linkedlist.h | 13 ++++++------- src/point.c | 33 --------------------------------- src/point.h | 28 ---------------------------- 8 files changed, 51 insertions(+), 115 deletions(-) delete mode 100644 src/point.c delete mode 100644 src/point.h diff --git a/src/cluster.c b/src/cluster.c index 84e6beb..939ae5c 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -32,26 +32,28 @@ void cluster_destroy_fpt(cluster_fpt_t* cluster) { } -void cluster_add_point_int(cluster_int_t* cluster, point_int_t* point) { +void cluster_add_point_int(cluster_int_t* cluster, vector_int_t* point) { //TODO if (NULL == cluster || NULL == point) return; + list_points_append_int(cluster->points, point); if (NULL == cluster->center) { - cluster->center = vector_copy_int(point->vector); + cluster->center = vector_copy_int(point); } else { - vector_int_t* delta = vector_copy_int(point->vector); + vector_int_t* delta = vector_copy_int(point); vector_div_inplace_int(delta, cluster->points->size); vector_add_inplace_int(cluster->center, *delta); vector_destroy_int(delta); } } -void cluster_add_point_fpt(cluster_fpt_t* cluster, point_fpt_t* point) { +void cluster_add_point_fpt(cluster_fpt_t* cluster, vector_fpt_t* point) { //TODO if (NULL == cluster || NULL == point) return; + list_points_append_fpt(cluster->points, point); if (NULL == cluster->center) { - cluster->center = vector_copy_fpt(point->vector); + cluster->center = vector_copy_fpt(point); } else { - vector_fpt_t* delta = vector_copy_fpt(point->vector); + vector_fpt_t* delta = vector_copy_fpt(point); vector_div_inplace_fpt(delta, cluster->points->size); vector_add_inplace_fpt(cluster->center, *delta); vector_destroy_fpt(delta); diff --git a/src/cluster.h b/src/cluster.h index 963e417..0e2993a 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -3,7 +3,6 @@ #include <stdlib.h> #include "linkedlist.h" -#include "point.h" #include "vector.h" @@ -28,9 +27,9 @@ void cluster_destroy_int(cluster_int_t* center); void cluster_destroy_fpt(cluster_fpt_t* center); -void cluster_add_point_int(cluster_int_t* cluster, point_int_t* point); +void cluster_add_point_int(cluster_int_t* cluster, vector_int_t* point); -void cluster_add_point_fpt(cluster_fpt_t* cluster, point_fpt_t* point); +void cluster_add_point_fpt(cluster_fpt_t* cluster, vector_fpt_t* point); void cluster_update_center_int(cluster_int_t* cluster); diff --git a/src/kmeans.c b/src/kmeans.c index 55ddccd..7ee9705 100644 --- a/src/kmeans.c +++ b/src/kmeans.c @@ -1,18 +1,16 @@ #include "kmeans.h" -#include "point.h" -vector_int_t** kmeans_init_clusters_int(const point_int_t** points, const size_t point_count, const size_t nclusters) { - if (nclusters < 2) return NULL; - if (NULL == points) return NULL; - vector_int_t** clusters = calloc(nclusters, sizeof(vector_int_t*)); +cluster_int_t** kmeans_init_clusters_int(const vector_int_t** points, const size_t point_count, const size_t nclusters) { + if (NULL == points || point_count < 2 || nclusters < 2) return NULL; + cluster_int_t** clusters = calloc(nclusters, sizeof(vector_int_t*)); if (NULL == clusters) return NULL; // determine range in which we are working - vector_int_t* min = vector_copy_int(points[0]->vector); - vector_int_t* max = vector_copy_int(points[0]->vector); + vector_int_t* min = vector_copy_int(points[0]); + vector_int_t* max = vector_copy_int(points[0]); for (size_t i = 0; i < point_count; ++i) { for (size_t p = 0; p < max->dim; ++p) { - const int_t value = points[i]->vector->data[p]; + const int_t value = points[i]->data[p]; if (value < min->data[p]) min->data[p] = value; if (value > max->data[p]) max->data[p] = value; } @@ -24,15 +22,17 @@ vector_int_t** kmeans_init_clusters_int(const point_int_t** points, const size_t center->data[p] = rand_int_range(min->data[p], max->data[p]); } // TODO: maybe check center is not already in clusters, although probability is extremely low... - clusters[i] = center; + clusters[i]->center = center; } return clusters; } void kmeans_int( - point_int_t** points, const size_t point_count, - vector_int_t** clusters, const size_t nb_clusters, + vector_int_t** points, const size_t point_count, + cluster_int_t** clusters, const size_t nb_clusters, fpt_t (* distance_function)(const vector_int_t*, const vector_int_t*)) { //TODO + bool changed = true; + while (changed) {} } diff --git a/src/kmeans.h b/src/kmeans.h index c1c5ff7..34a83c8 100644 --- a/src/kmeans.h +++ b/src/kmeans.h @@ -1,15 +1,15 @@ #ifndef PROG_KMEANS_KMEANS_H #define PROG_KMEANS_KMEANS_H -#include "point.h" +#include "cluster.h" #include "linkedlist.h" -vector_int_t** kmeans_init_clusters_int(const point_int_t** points, const size_t point_count, const size_t nclusters); +cluster_int_t** kmeans_init_clusters_int(const vector_int_t** points, const size_t point_count, const size_t nclusters); void kmeans_int( - point_int_t** points, const size_t point_count, - vector_int_t** clusters, const size_t nb_clusters, + vector_int_t** points, const size_t point_count, + cluster_int_t** clusters, const size_t nb_clusters, fpt_t (* distance_function)(const vector_int_t*, const vector_int_t*)); diff --git a/src/linkedlist.c b/src/linkedlist.c index 898c7d3..3ea5994 100644 --- a/src/linkedlist.c +++ b/src/linkedlist.c @@ -1,24 +1,21 @@ #include "linkedlist.h" #include <assert.h> #include <stdbool.h> -#include "point.h" -list_points_node_int_t* list_points_node_create_int(vector_int_t* vec) { +list_points_node_int_t* list_points_node_create_int(vector_int_t* point) { + if (NULL == point) return NULL; list_points_node_int_t* node = malloc(sizeof(list_points_node_int_t)); if (NULL == node) return NULL; - point_int_t* point = point_create_int(vec); - if (NULL == point) return NULL; node->point = point; node->next = NULL; return node; } -list_points_node_fpt_t* list_points_node_create_fpt(vector_fpt_t* vec) { +list_points_node_fpt_t* list_points_node_create_fpt(vector_fpt_t* point) { + if (NULL == point) return NULL; list_points_node_fpt_t* node = malloc(sizeof(list_points_node_fpt_t)); if (NULL == node) return NULL; - point_fpt_t* point = point_create_fpt(vec); - if (NULL == point) return NULL; node->point = point; node->next = NULL; return node; @@ -27,20 +24,19 @@ list_points_node_fpt_t* list_points_node_create_fpt(vector_fpt_t* vec) { void list_points_node_destroy_int(list_points_node_int_t* node, const bool full) { if (NULL == node) return; - if (full) point_destroy_int(node->point); + if (full) vector_destroy_int(node->point); free(node); } void list_points_node_destroy_fpt(list_points_node_fpt_t* node, const bool full) { if (NULL == node) return; - if (full) point_destroy_fpt(node->point); + if (full) vector_destroy_fpt(node->point); free(node); } list_points_int_t* list_points_create_int() { - list_points_int_t* list = NULL; - list = malloc(sizeof(list_points_int_t)); + list_points_int_t* list = malloc(sizeof(list_points_int_t)); if (NULL == list) return NULL; list->head = NULL; list->tail = NULL; @@ -49,8 +45,7 @@ list_points_int_t* list_points_create_int() { } list_points_fpt_t* list_points_create_fpt() { - list_points_fpt_t* list = NULL; - list = malloc(sizeof(list_points_fpt_t)); + list_points_fpt_t* list = malloc(sizeof(list_points_fpt_t)); if (NULL == list) return NULL; list->head = NULL; list->tail = NULL; @@ -80,9 +75,9 @@ void list_points_destroy_fpt(list_points_fpt_t* list, const bool full) { } -void list_points_append_int(list_points_int_t* list, vector_int_t* vector) { - if (NULL == vector) return; - list_points_node_int_t* node = list_points_node_create_int(vector); +void list_points_append_int(list_points_int_t* list, vector_int_t* point) { + if (NULL == list || NULL == point) return; + list_points_node_int_t* node = list_points_node_create_int(point); if (NULL == list->head) { // if list is empty list->head = node; list->tail = list->head; @@ -93,9 +88,9 @@ void list_points_append_int(list_points_int_t* list, vector_int_t* vector) { ++list->size; } -void list_points_append_fpt(list_points_fpt_t* list, vector_fpt_t* vector) { - if (NULL == vector) return; - list_points_node_fpt_t* node = list_points_node_create_fpt(vector); +void list_points_append_fpt(list_points_fpt_t* list, vector_fpt_t* point) { + if (NULL == list || NULL == point) return; + list_points_node_fpt_t* node = list_points_node_create_fpt(point); if (NULL == list->head) { // if list is empty list->head = node; list->tail = list->head; @@ -107,8 +102,9 @@ void list_points_append_fpt(list_points_fpt_t* list, vector_fpt_t* vector) { } -point_int_t** list_points_to_array_int(const list_points_int_t* list) { - point_int_t** a = calloc(list->size, sizeof(point_int_t*)); +vector_int_t** list_points_to_array_int(const list_points_int_t* list) { + if (NULL == list) return NULL; + vector_int_t** a = calloc(list->size, sizeof(vector_int_t*)); if (NULL == a) return NULL; list_points_node_int_t* cur = list->head; size_t idx = 0; @@ -121,8 +117,9 @@ point_int_t** list_points_to_array_int(const list_points_int_t* list) { return a; } -point_fpt_t** list_points_to_array_fpt(const list_points_fpt_t* list) { - point_fpt_t** a = calloc(list->size, sizeof(point_fpt_t*)); +vector_fpt_t** list_points_to_array_fpt(const list_points_fpt_t* list) { + if (NULL == list) return NULL; + vector_fpt_t** a = calloc(list->size, sizeof(vector_fpt_t*)); if (NULL == a) return NULL; list_points_node_fpt_t* cur = list->head; size_t idx = 0; diff --git a/src/linkedlist.h b/src/linkedlist.h index adfdeb9..de857ef 100644 --- a/src/linkedlist.h +++ b/src/linkedlist.h @@ -2,24 +2,23 @@ #define PROG_KMEANS_LINKEDLIST_H #include <stdbool.h> -#include "point.h" #include "vector.h" typedef struct list_points_node_int { - point_int_t* point; + vector_int_t* point; struct list_points_node_int* next; } list_points_node_int_t; typedef struct list_points_node_fpt { - point_fpt_t* point; + vector_fpt_t* point; struct list_points_node_fpt* next; } list_points_node_fpt_t; -list_points_node_int_t* list_points_node_create_int(vector_int_t* vec); +list_points_node_int_t* list_points_node_create_int(vector_int_t* point); -list_points_node_fpt_t* list_points_node_create_fpt(vector_fpt_t* vec); +list_points_node_fpt_t* list_points_node_create_fpt(vector_fpt_t* point); void list_points_node_destroy_int(list_points_node_int_t* node, const bool full); @@ -55,9 +54,9 @@ void list_points_append_int(list_points_int_t* list, vector_int_t* vector); void list_points_append_fpt(list_points_fpt_t* list, vector_fpt_t* vector); -point_int_t** list_points_to_array_int(const list_points_int_t* list); +vector_int_t** list_points_to_array_int(const list_points_int_t* list); -point_fpt_t** list_points_to_array_fpt(const list_points_fpt_t* list); +vector_fpt_t** list_points_to_array_fpt(const list_points_fpt_t* list); #endif //PROG_KMEANS_LINKEDLIST_H diff --git a/src/point.c b/src/point.c deleted file mode 100644 index 3dcb58f..0000000 --- a/src/point.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "point.h" -#include <stdlib.h> -#include "vector.h" - - -point_int_t* point_create_int(vector_int_t* vector) { - point_int_t* point = malloc(sizeof(point_int_t)); - if (NULL == point) return NULL; - point->vector = vector; - point->cluster = NULL; - return point; -} - -point_fpt_t* point_create_fpt(vector_fpt_t* vector) { - point_fpt_t* point = malloc(sizeof(point_fpt_t)); - if (NULL == point) return NULL; - point->vector = vector; - point->cluster = NULL; - return point; -} - - -void point_destroy_int(point_int_t* cp) { - if (NULL == cp) return; - vector_destroy_int(cp->vector); - free(cp); -} - -void point_destroy_fpt(point_fpt_t* cp) { - if (NULL == cp) return; - vector_destroy_fpt(cp->vector); - free(cp); -} diff --git a/src/point.h b/src/point.h deleted file mode 100644 index 381dabe..0000000 --- a/src/point.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef PROG_KMEANS_POINT_H -#define PROG_KMEANS_POINT_H - -#include "vector.h" - - -typedef struct point_int { - vector_int_t* vector; - vector_int_t* cluster; -} point_int_t; - -typedef struct point_fpt { - vector_fpt_t* vector; - vector_fpt_t* cluster; -} point_fpt_t; - - -point_int_t* point_create_int(vector_int_t* vector); - -point_fpt_t* point_create_fpt(vector_fpt_t* vector); - - -void point_destroy_int(point_int_t* cp); - -void point_destroy_fpt(point_fpt_t* cp); - - -#endif //PROG_KMEANS_POINT_H -- GitLab