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