Skip to content
Snippets Groups Projects
Commit b07e03a1 authored by Boris Stefanovic's avatar Boris Stefanovic
Browse files

EDIT: points do not need to know the cluster they belong to

parent 8f1689ff
Branches main
No related tags found
No related merge requests found
...@@ -32,26 +32,28 @@ void cluster_destroy_fpt(cluster_fpt_t* cluster) { ...@@ -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 //TODO
if (NULL == cluster || NULL == point) return; if (NULL == cluster || NULL == point) return;
list_points_append_int(cluster->points, point);
if (NULL == cluster->center) { if (NULL == cluster->center) {
cluster->center = vector_copy_int(point->vector); cluster->center = vector_copy_int(point);
} else { } 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_div_inplace_int(delta, cluster->points->size);
vector_add_inplace_int(cluster->center, *delta); vector_add_inplace_int(cluster->center, *delta);
vector_destroy_int(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 //TODO
if (NULL == cluster || NULL == point) return; if (NULL == cluster || NULL == point) return;
list_points_append_fpt(cluster->points, point);
if (NULL == cluster->center) { if (NULL == cluster->center) {
cluster->center = vector_copy_fpt(point->vector); cluster->center = vector_copy_fpt(point);
} else { } 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_div_inplace_fpt(delta, cluster->points->size);
vector_add_inplace_fpt(cluster->center, *delta); vector_add_inplace_fpt(cluster->center, *delta);
vector_destroy_fpt(delta); vector_destroy_fpt(delta);
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
#include <stdlib.h> #include <stdlib.h>
#include "linkedlist.h" #include "linkedlist.h"
#include "point.h"
#include "vector.h" #include "vector.h"
...@@ -28,9 +27,9 @@ void cluster_destroy_int(cluster_int_t* center); ...@@ -28,9 +27,9 @@ void cluster_destroy_int(cluster_int_t* center);
void cluster_destroy_fpt(cluster_fpt_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); void cluster_update_center_int(cluster_int_t* cluster);
......
#include "kmeans.h" #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) { cluster_int_t** kmeans_init_clusters_int(const vector_int_t** points, const size_t point_count, const size_t nclusters) {
if (nclusters < 2) return NULL; if (NULL == points || point_count < 2 || nclusters < 2) return NULL;
if (NULL == points) return NULL; cluster_int_t** clusters = calloc(nclusters, sizeof(vector_int_t*));
vector_int_t** clusters = calloc(nclusters, sizeof(vector_int_t*));
if (NULL == clusters) return NULL; if (NULL == clusters) return NULL;
// determine range in which we are working // determine range in which we are working
vector_int_t* min = vector_copy_int(points[0]->vector); vector_int_t* min = vector_copy_int(points[0]);
vector_int_t* max = vector_copy_int(points[0]->vector); vector_int_t* max = vector_copy_int(points[0]);
for (size_t i = 0; i < point_count; ++i) { for (size_t i = 0; i < point_count; ++i) {
for (size_t p = 0; p < max->dim; ++p) { 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 < min->data[p]) min->data[p] = value;
if (value > max->data[p]) max->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 ...@@ -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]); 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... // TODO: maybe check center is not already in clusters, although probability is extremely low...
clusters[i] = center; clusters[i]->center = center;
} }
return clusters; return clusters;
} }
void kmeans_int( void kmeans_int(
point_int_t** points, const size_t point_count, vector_int_t** points, const size_t point_count,
vector_int_t** clusters, const size_t nb_clusters, cluster_int_t** clusters, const size_t nb_clusters,
fpt_t (* distance_function)(const vector_int_t*, const vector_int_t*)) { fpt_t (* distance_function)(const vector_int_t*, const vector_int_t*)) {
//TODO //TODO
bool changed = true;
while (changed) {}
} }
#ifndef PROG_KMEANS_KMEANS_H #ifndef PROG_KMEANS_KMEANS_H
#define PROG_KMEANS_KMEANS_H #define PROG_KMEANS_KMEANS_H
#include "point.h" #include "cluster.h"
#include "linkedlist.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( void kmeans_int(
point_int_t** points, const size_t point_count, vector_int_t** points, const size_t point_count,
vector_int_t** clusters, const size_t nb_clusters, cluster_int_t** clusters, const size_t nb_clusters,
fpt_t (* distance_function)(const vector_int_t*, const vector_int_t*)); fpt_t (* distance_function)(const vector_int_t*, const vector_int_t*));
......
#include "linkedlist.h" #include "linkedlist.h"
#include <assert.h> #include <assert.h>
#include <stdbool.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)); list_points_node_int_t* node = malloc(sizeof(list_points_node_int_t));
if (NULL == node) return NULL; if (NULL == node) return NULL;
point_int_t* point = point_create_int(vec);
if (NULL == point) return NULL;
node->point = point; node->point = point;
node->next = NULL; node->next = NULL;
return node; 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)); list_points_node_fpt_t* node = malloc(sizeof(list_points_node_fpt_t));
if (NULL == node) return NULL; if (NULL == node) return NULL;
point_fpt_t* point = point_create_fpt(vec);
if (NULL == point) return NULL;
node->point = point; node->point = point;
node->next = NULL; node->next = NULL;
return node; return node;
...@@ -27,20 +24,19 @@ list_points_node_fpt_t* list_points_node_create_fpt(vector_fpt_t* vec) { ...@@ -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) { void list_points_node_destroy_int(list_points_node_int_t* node, const bool full) {
if (NULL == node) return; if (NULL == node) return;
if (full) point_destroy_int(node->point); if (full) vector_destroy_int(node->point);
free(node); free(node);
} }
void list_points_node_destroy_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 (NULL == node) return;
if (full) point_destroy_fpt(node->point); if (full) vector_destroy_fpt(node->point);
free(node); free(node);
} }
list_points_int_t* list_points_create_int() { list_points_int_t* list_points_create_int() {
list_points_int_t* list = NULL; list_points_int_t* list = malloc(sizeof(list_points_int_t));
list = malloc(sizeof(list_points_int_t));
if (NULL == list) return NULL; if (NULL == list) return NULL;
list->head = NULL; list->head = NULL;
list->tail = NULL; list->tail = NULL;
...@@ -49,8 +45,7 @@ list_points_int_t* list_points_create_int() { ...@@ -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_points_create_fpt() {
list_points_fpt_t* list = NULL; list_points_fpt_t* list = malloc(sizeof(list_points_fpt_t));
list = malloc(sizeof(list_points_fpt_t));
if (NULL == list) return NULL; if (NULL == list) return NULL;
list->head = NULL; list->head = NULL;
list->tail = NULL; list->tail = NULL;
...@@ -80,9 +75,9 @@ void list_points_destroy_fpt(list_points_fpt_t* list, const bool full) { ...@@ -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) { void list_points_append_int(list_points_int_t* list, vector_int_t* point) {
if (NULL == vector) return; if (NULL == list || NULL == point) return;
list_points_node_int_t* node = list_points_node_create_int(vector); list_points_node_int_t* node = list_points_node_create_int(point);
if (NULL == list->head) { // if list is empty if (NULL == list->head) { // if list is empty
list->head = node; list->head = node;
list->tail = list->head; list->tail = list->head;
...@@ -93,9 +88,9 @@ void list_points_append_int(list_points_int_t* list, vector_int_t* vector) { ...@@ -93,9 +88,9 @@ void list_points_append_int(list_points_int_t* list, vector_int_t* vector) {
++list->size; ++list->size;
} }
void list_points_append_fpt(list_points_fpt_t* list, vector_fpt_t* vector) { void list_points_append_fpt(list_points_fpt_t* list, vector_fpt_t* point) {
if (NULL == vector) return; if (NULL == list || NULL == point) return;
list_points_node_fpt_t* node = list_points_node_create_fpt(vector); list_points_node_fpt_t* node = list_points_node_create_fpt(point);
if (NULL == list->head) { // if list is empty if (NULL == list->head) { // if list is empty
list->head = node; list->head = node;
list->tail = list->head; list->tail = list->head;
...@@ -107,8 +102,9 @@ void list_points_append_fpt(list_points_fpt_t* list, vector_fpt_t* vector) { ...@@ -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) { vector_int_t** list_points_to_array_int(const list_points_int_t* list) {
point_int_t** a = calloc(list->size, sizeof(point_int_t*)); if (NULL == list) return NULL;
vector_int_t** a = calloc(list->size, sizeof(vector_int_t*));
if (NULL == a) return NULL; if (NULL == a) return NULL;
list_points_node_int_t* cur = list->head; list_points_node_int_t* cur = list->head;
size_t idx = 0; size_t idx = 0;
...@@ -121,8 +117,9 @@ point_int_t** list_points_to_array_int(const list_points_int_t* list) { ...@@ -121,8 +117,9 @@ point_int_t** list_points_to_array_int(const list_points_int_t* list) {
return a; return a;
} }
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) {
point_fpt_t** a = calloc(list->size, sizeof(point_fpt_t*)); if (NULL == list) return NULL;
vector_fpt_t** a = calloc(list->size, sizeof(vector_fpt_t*));
if (NULL == a) return NULL; if (NULL == a) return NULL;
list_points_node_fpt_t* cur = list->head; list_points_node_fpt_t* cur = list->head;
size_t idx = 0; size_t idx = 0;
......
...@@ -2,24 +2,23 @@ ...@@ -2,24 +2,23 @@
#define PROG_KMEANS_LINKEDLIST_H #define PROG_KMEANS_LINKEDLIST_H
#include <stdbool.h> #include <stdbool.h>
#include "point.h"
#include "vector.h" #include "vector.h"
typedef struct list_points_node_int { typedef struct list_points_node_int {
point_int_t* point; vector_int_t* point;
struct list_points_node_int* next; struct list_points_node_int* next;
} list_points_node_int_t; } list_points_node_int_t;
typedef struct list_points_node_fpt { typedef struct list_points_node_fpt {
point_fpt_t* point; vector_fpt_t* point;
struct list_points_node_fpt* next; struct list_points_node_fpt* next;
} list_points_node_fpt_t; } 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); 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); ...@@ -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); 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 #endif //PROG_KMEANS_LINKEDLIST_H
#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);
}
#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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment