diff --git a/src/cluster.c b/src/cluster.c new file mode 100644 index 0000000000000000000000000000000000000000..84e6beb82636b3446668219fb52766ea4177a0c0 --- /dev/null +++ b/src/cluster.c @@ -0,0 +1,81 @@ +#include "cluster.h" +#include "vector.h" + + +cluster_int_t* cluster_create_int(vector_int_t* center) { + cluster_int_t* cluster = malloc(sizeof(cluster_int_t)); + if (NULL == cluster) return NULL; + cluster->center = center; + cluster->points = list_points_create_int(); +} + +cluster_fpt_t* cluster_create_fpt(vector_fpt_t* center) { + cluster_fpt_t* cluster = malloc(sizeof(cluster_fpt_t)); + if (NULL == cluster) return NULL; + cluster->center = center; + cluster->points = list_points_create_fpt(); +} + + +void cluster_destroy_int(cluster_int_t* cluster) { + if (NULL == cluster) return; + vector_destroy_int(cluster->center); + list_points_destroy_int(cluster->points, false); + free(cluster); +} + +void cluster_destroy_fpt(cluster_fpt_t* cluster) { + if (NULL == cluster) return; + vector_destroy_fpt(cluster->center); + list_points_destroy_fpt(cluster->points, false); + free(cluster); +} + + +void cluster_add_point_int(cluster_int_t* cluster, point_int_t* point) { + //TODO + if (NULL == cluster || NULL == point) return; + if (NULL == cluster->center) { + cluster->center = vector_copy_int(point->vector); + } else { + vector_int_t* delta = vector_copy_int(point->vector); + 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) { + //TODO + if (NULL == cluster || NULL == point) return; + if (NULL == cluster->center) { + cluster->center = vector_copy_fpt(point->vector); + } else { + vector_fpt_t* delta = vector_copy_fpt(point->vector); + vector_div_inplace_fpt(delta, cluster->points->size); + vector_add_inplace_fpt(cluster->center, *delta); + vector_destroy_fpt(delta); + } +} + + +void cluster_update_center_int(cluster_int_t* cluster) { + //TODO +} + +void cluster_update_center_fpt(cluster_fpt_t* cluster) { + //TODO +} + + +void cluster_reset_int(cluster_int_t* cluster) { + //TODO + list_points_destroy_int(cluster->points, false); + cluster->points = list_points_create_int(); +} + +void cluster_reset_fpt(cluster_fpt_t* cluster) { + //TODO + list_points_destroy_fpt(cluster->points, false); + cluster->points = list_points_create_fpt(); +} diff --git a/src/cluster.h b/src/cluster.h new file mode 100644 index 0000000000000000000000000000000000000000..963e417c27a38e58d9f62304e988c55a65cfbedb --- /dev/null +++ b/src/cluster.h @@ -0,0 +1,46 @@ +#ifndef PROG_KMEANS_CLUSTER_H +#define PROG_KMEANS_CLUSTER_H + +#include <stdlib.h> +#include "linkedlist.h" +#include "point.h" +#include "vector.h" + + +typedef struct cluster_int { + vector_int_t* center; + list_points_int_t* points; +} cluster_int_t; + +typedef struct cluster_fpt { + vector_fpt_t* center; + list_points_fpt_t* points; +} cluster_fpt_t; + + +cluster_int_t* cluster_create_int(vector_int_t* center); + +cluster_fpt_t* cluster_create_fpt(vector_fpt_t* center); + + +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_fpt(cluster_fpt_t* cluster, point_fpt_t* point); + + +void cluster_update_center_int(cluster_int_t* cluster); + +void cluster_update_center_fpt(cluster_fpt_t* cluster); + + +void cluster_reset_int(cluster_int_t* cluster); + +void cluster_reset_fpt(cluster_fpt_t* cluster); + + +#endif //PROG_KMEANS_CLUSTER_H diff --git a/src/distance.c b/src/distance.c index 1655e2fb41b110272a18c338270e86ae7cf93af3..b6abfaed5d038923071ab7bca71b9681870fc734 100644 --- a/src/distance.c +++ b/src/distance.c @@ -1,7 +1,3 @@ -// -// by Boris Stefanovic on 24/05/22 -// - #include "distance.h" #include <math.h> #include "common.h" diff --git a/src/distance.h b/src/distance.h index 166cd54c43349d1a13d5f8954a570a5a55f8960f..f046c904ddf12b5edc202433a2254f78ab118b1d 100644 --- a/src/distance.h +++ b/src/distance.h @@ -1,7 +1,3 @@ -// -// by Boris Stefanovic on 24/05/22 -// - #ifndef PROG_KMEANS_DISTANCE_H #define PROG_KMEANS_DISTANCE_H diff --git a/src/linkedlist.c b/src/linkedlist.c index b9c8f83e3faf84518be00ea2bc0a377bcd22a9b1..898c7d3c124dbc724476ceed2b502c35e0e1875e 100644 --- a/src/linkedlist.c +++ b/src/linkedlist.c @@ -4,20 +4,20 @@ #include "point.h" -list_points_node_int_t* list_points_create_node_int(vector_int_t* vec) { +list_points_node_int_t* list_points_node_create_int(vector_int_t* vec) { list_points_node_int_t* node = malloc(sizeof(list_points_node_int_t)); if (NULL == node) return NULL; - point_int_t* point = point_int_create(vec); + 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_create_node_fpt(vector_fpt_t* vec) { +list_points_node_fpt_t* list_points_node_create_fpt(vector_fpt_t* vec) { list_points_node_fpt_t* node = malloc(sizeof(list_points_node_fpt_t)); if (NULL == node) return NULL; - point_fpt_t* point = point_fpt_create(vec); + point_fpt_t* point = point_create_fpt(vec); if (NULL == point) return NULL; node->point = point; node->next = NULL; @@ -25,15 +25,15 @@ list_points_node_fpt_t* list_points_create_node_fpt(vector_fpt_t* vec) { } -void list_points_destroy_node_int(list_points_node_int_t* node, const bool full) { +void list_points_node_destroy_int(list_points_node_int_t* node, const bool full) { if (NULL == node) return; - if (full) point_int_destroy(node->point); + if (full) point_destroy_int(node->point); free(node); } -void list_points_destroy_node_fpt(list_points_node_fpt_t* node, const bool full) { +void list_points_node_destroy_fpt(list_points_node_fpt_t* node, const bool full) { if (NULL == node) return; - if (full) point_fpt_destroy(node->point); + if (full) point_destroy_fpt(node->point); free(node); } @@ -64,7 +64,7 @@ void list_points_destroy_int(list_points_int_t* list, const bool full) { list_points_node_int_t* node; while ((node = list->head) != NULL) { list->head = node->next; - list_points_destroy_node_int(node, full); + list_points_node_destroy_int(node, full); } free(list); } @@ -74,7 +74,7 @@ void list_points_destroy_fpt(list_points_fpt_t* list, const bool full) { list_points_node_fpt_t* node; while ((node = list->head) != NULL) { list->head = node->next; - list_points_destroy_node_fpt(node, full); + list_points_node_destroy_fpt(node, full); } free(list); } @@ -82,7 +82,7 @@ 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_create_node_int(vector); + list_points_node_int_t* node = list_points_node_create_int(vector); if (NULL == list->head) { // if list is empty list->head = node; list->tail = list->head; @@ -95,7 +95,7 @@ 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) { if (NULL == vector) return; - list_points_node_fpt_t* node = list_points_create_node_fpt(vector); + list_points_node_fpt_t* node = list_points_node_create_fpt(vector); if (NULL == list->head) { // if list is empty list->head = node; list->tail = list->head; diff --git a/src/linkedlist.h b/src/linkedlist.h index a269942fb1799a0f7286bc5d524aaf714337fb6e..adfdeb9c1ab0d9b8f09cea9517fe14dd80f26d7a 100644 --- a/src/linkedlist.h +++ b/src/linkedlist.h @@ -1,7 +1,3 @@ -// -// by Boris Stefanovic on 31/05/22 -// - #ifndef PROG_KMEANS_LINKEDLIST_H #define PROG_KMEANS_LINKEDLIST_H @@ -15,33 +11,33 @@ typedef struct list_points_node_int { struct list_points_node_int* next; } list_points_node_int_t; -typedef struct list_points_int { - list_points_node_int_t* head; - list_points_node_int_t* tail; - size_t size; -} list_points_int_t; - - typedef struct list_points_node_fpt { point_fpt_t* point; struct list_points_node_fpt* next; } list_points_node_fpt_t; -typedef struct list_points_fpt { - list_points_node_fpt_t* head; - list_points_node_fpt_t* tail; - size_t size; -} list_points_fpt_t; +list_points_node_int_t* list_points_node_create_int(vector_int_t* vec); -list_points_node_int_t* list_points_create_node_int(vector_int_t* vec); +list_points_node_fpt_t* list_points_node_create_fpt(vector_fpt_t* vec); -list_points_node_fpt_t* list_points_create_node_fpt(vector_fpt_t* vec); +void list_points_node_destroy_int(list_points_node_int_t* node, const bool full); -void list_points_destroy_node_int(list_points_node_int_t* node, const bool full); +void list_points_node_destroy_fpt(list_points_node_fpt_t* node, const bool full); -void list_points_destroy_node_fpt(list_points_node_fpt_t* node, const bool full); + +typedef struct list_points_int { + list_points_node_int_t* head; + list_points_node_int_t* tail; + size_t size; +} list_points_int_t; + +typedef struct list_points_fpt { + list_points_node_fpt_t* head; + list_points_node_fpt_t* tail; + size_t size; +} list_points_fpt_t; list_points_int_t* list_points_create_int(); diff --git a/src/point.c b/src/point.c index cb2e30f6db969423e9215be856932240737c23ed..3dcb58f75293d920c1e1d1db5ac364bbc45aa179 100644 --- a/src/point.c +++ b/src/point.c @@ -3,7 +3,7 @@ #include "vector.h" -point_int_t* point_int_create(vector_int_t* vector) { +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; @@ -11,8 +11,7 @@ point_int_t* point_int_create(vector_int_t* vector) { return point; } - -point_fpt_t* point_fpt_create(vector_fpt_t* vector) { +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; @@ -21,15 +20,14 @@ point_fpt_t* point_fpt_create(vector_fpt_t* vector) { } -void point_int_destroy(point_int_t* cp) { +void point_destroy_int(point_int_t* cp) { if (NULL == cp) return; - vector_int_destroy(cp->vector); + vector_destroy_int(cp->vector); free(cp); } - -void point_fpt_destroy(point_fpt_t* cp) { +void point_destroy_fpt(point_fpt_t* cp) { if (NULL == cp) return; - vector_fpt_destroy(cp->vector); + vector_destroy_fpt(cp->vector); free(cp); } diff --git a/src/point.h b/src/point.h index 58694e5877511013352ca1eb50c8bee71b29101a..381dabe7c1781dbb22b70b52c03cdd4f80f8140c 100644 --- a/src/point.h +++ b/src/point.h @@ -1,5 +1,5 @@ -#ifndef PROG_KMEANS_CLUSTER_H -#define PROG_KMEANS_CLUSTER_H +#ifndef PROG_KMEANS_POINT_H +#define PROG_KMEANS_POINT_H #include "vector.h" @@ -9,21 +9,20 @@ typedef struct point_int { 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_int_create(vector_int_t* vector); +point_int_t* point_create_int(vector_int_t* vector); -point_fpt_t* point_fpt_create(vector_fpt_t* vector); +point_fpt_t* point_create_fpt(vector_fpt_t* vector); -void point_int_destroy(point_int_t* cp); +void point_destroy_int(point_int_t* cp); -void point_fpt_destroy(point_fpt_t* cp); +void point_destroy_fpt(point_fpt_t* cp); -#endif //PROG_KMEANS_CLUSTER_H +#endif //PROG_KMEANS_POINT_H diff --git a/src/vector.c b/src/vector.c index f72d46675298ee66e1c992abc635e33e57fa6269..b70c9f124a7c0c4a201e278ed474a88fee5a0d19 100644 --- a/src/vector.c +++ b/src/vector.c @@ -87,3 +87,27 @@ void vector_print_to_file_fpt(FILE* file, const vector_fpt_t* v) { for (size_t i = 1; i < v->dim; ++i) fprintf(file, " , %lf", v->data[i]); fprintf(file, "\n"); } + + +void vector_add_inplace_int(vector_int_t* v, const vector_int_t a) { + if (NULL == v) return; + const size_t dim = v->dim < a.dim ? v->dim : a.dim; + for (size_t i = 0; i < dim; ++i) v->data[i] += a.data[i]; +} + +void vector_add_inplace_fpt(vector_fpt_t* v, const vector_fpt_t a) { + if (NULL == v) return; + const size_t dim = v->dim < a.dim ? v->dim : a.dim; + for (size_t i = 0; i < dim; ++i) v->data[i] += a.data[i]; +} + + +void vector_div_inplace_int(vector_int_t* v, const int_t a) { + if (NULL == v) return; + for (size_t i = 0; i < v->dim; ++i) v->data[i] /= a; +} + +void vector_div_inplace_fpt(vector_fpt_t* v, const fpt_t a) { + if (NULL == v) return; + for (size_t i = 0; i < v->dim; ++i) v->data[i] /= a; +} diff --git a/src/vector.h b/src/vector.h index 8291ac9b6351a125c4ac251654ddbfd576515895..155fb78db50502e6577dadf5e8b438d40fb127fc 100644 --- a/src/vector.h +++ b/src/vector.h @@ -44,4 +44,14 @@ void vector_print_to_file_int(FILE* file, const vector_int_t* v); void vector_print_to_file_fpt(FILE* file, const vector_fpt_t* v); +void vector_add_inplace_int(vector_int_t* v, const vector_int_t a); + +void vector_add_inplace_fpt(vector_fpt_t* v, const vector_fpt_t a); + + +void vector_div_inplace_int(vector_int_t* v, const int_t a); + +void vector_div_inplace_fpt(vector_fpt_t* v, const fpt_t a); + + #endif //PROG_KMEANS_VECTOR_H