From 8c35d93a8af875b5da26a928c3f1eb9ffc089b0a Mon Sep 17 00:00:00 2001 From: "dario.genga" <dario.genga@etu.hesge.ch> Date: Sat, 18 Jun 2022 10:13:14 +0200 Subject: [PATCH] Add values_utils files --- kmeans.c | 69 ++++++++++--------------------------------------- kmeans.h | 2 +- makefile | 4 ++- output_data.txt | 14 +++++----- values_utils.c | 50 +++++++++++++++++++++++++++++++++++ values_utils.h | 40 ++++++++++++++++++++++++++++ 6 files changed, 115 insertions(+), 64 deletions(-) create mode 100644 values_utils.c create mode 100644 values_utils.h diff --git a/kmeans.c b/kmeans.c index 0702fb9..ee69567 100644 --- a/kmeans.c +++ b/kmeans.c @@ -3,27 +3,7 @@ #include "kmeans.h" -int random_with_min_man_value(int min, int max) { - return (rand() % (max - min + 1)) + min; -} - -void swap(int *x, int *y) -{ - int tmp = *x; - *x = *y; - *y = tmp; -} -kmeans* kmeans_create_empty() { - kmeans* universe = malloc(sizeof(kmeans)); - universe->points_array = NULL; - universe->nb_points = 0; - universe->k = 0; - universe->dimensions = 0; - universe->clusters_array = NULL; - - return universe; -} /// Create empty clusters for the universe /// \param universe The universe who contains the cluster to create. @@ -82,6 +62,17 @@ point* create_point_from_string(char *line, int dimensions) { return p; } +kmeans* kmeans_create_empty() { + kmeans* universe = malloc(sizeof(kmeans)); + universe->points_array = NULL; + universe->nb_points = 0; + universe->k = 0; + universe->dimensions = 0; + universe->clusters_array = NULL; + + return universe; +} + kmeans* kmeans_create(int k, point** data, int nb_points) { kmeans* universe = malloc(sizeof(kmeans)); universe->points_array = data; @@ -227,46 +218,14 @@ void init_clusters(kmeans *universe) { free(random_index_possible); } -float compute_euclidean_distance(point* p1, point* p2) { - float sum = 0; - float result = 0; - - for (int i = 0; i < p1->dimensions; i++) { - sum += pow(p1->value[i] - p2->value[i], 2); - } - result = sqrt(sum); - return result; -} - -float compute_manhattan_distance(point* p1, point* p2) { - float result = 0; - - for (int i = 0; i < p1->dimensions; i++) { - result += fabs(p1->value[i] - p2->value[i]); - } - return result; -} - -float compute_chebyshev_distance(point* p1, point* p2) { - float result = 0; - - for (int i = 0; i < p1->dimensions; i++) { - int abs_diff = fabs(p1->value[i] - p2->value[i]); - if (abs_diff > result) { - result = abs_diff; - } - } - return result; -} - float compute_distance(point* p1, point* p2) { if (p1->dimensions != p2->dimensions) { printf("The points don't have the same dimensions!\n"); exit(EXIT_FAILURE); } - float euclidean = compute_euclidean_distance(p1, p2); - //float manhattan = compute_manhattan_distance(p1, p2); - //float chebyshev = compute_chebyshev_distance(p1, p2); + float euclidean = compute_euclidean_distance(p1->value, p2->value, p1->dimensions); + //float manhattan = compute_manhattan_distance(p1->value, p2->value, p1->dimensions); + //float chebyshev = compute_chebyshev_distance(p1->value, p2->value, p1->dimensions); return euclidean; } diff --git a/kmeans.h b/kmeans.h index 9d6022c..0013411 100644 --- a/kmeans.h +++ b/kmeans.h @@ -8,8 +8,8 @@ #include <stdlib.h> #include <stdbool.h> #include <string.h> -#include <math.h> #include "files_utils.h" +#include "values_utils.h" #define LINE_INDEX_DIMENSIONS 0 #define LINE_INDEX_CLUSTER 1 diff --git a/makefile b/makefile index 47c8687..bf03ed3 100644 --- a/makefile +++ b/makefile @@ -1,11 +1,13 @@ LIB=-lm CC=gcc -Wall -Wextra -g -main: files_utils.o kmeans.o main.o +main: files_utils.o values_utils.o kmeans.o main.o $(CC) $^ -fsanitize=address -fsanitize=leak -o $@ $(LIB) files_utils.o: files_utils.c files_utils.h $(CC) -c $< $(LIB) +values_utils.o: values_utils.c values_utils.h + $(CC) -c $< $(LIB) kmeans.o: kmeans.c kmeans.h $(CC) -c $< $(LIB) main.o: main.c diff --git a/output_data.txt b/output_data.txt index 174ff2c..c51c549 100644 --- a/output_data.txt +++ b/output_data.txt @@ -1,14 +1,8 @@ 2 3 * --1.00,-5.00 --2.00,-4.00 --3.00,-3.00 --4.00,-2.00 --5.00,-1.00 --1.75,-2.25 -* 0.00,0.00 +-1.00,-5.00 3.10,-4.90 * 1.00,1.00 @@ -19,3 +13,9 @@ -2.25,4.75 2.20,4.40 4.00,2.00 +* +-2.00,-4.00 +-3.00,-3.00 +-4.00,-2.00 +-5.00,-1.00 +-1.75,-2.25 diff --git a/values_utils.c b/values_utils.c new file mode 100644 index 0000000..c4a811d --- /dev/null +++ b/values_utils.c @@ -0,0 +1,50 @@ +// Project : K-means +// Author : Dario GENGA + +#include "values_utils.h" + +int random_with_min_man_value(int min, int max) { + return (rand() % (max - min + 1)) + min; +} + +/// Swap x and y values +/// \param x The first value +/// \param y The second value +void swap(int *x, int *y) +{ + int tmp = *x; + *x = *y; + *y = tmp; +} + +float compute_euclidean_distance(float* p1, float* p2, size_t dimensions) { + float sum = 0; + float result = 0; + + for (size_t i = 0; i < dimensions; i++) { + sum += pow(p1[i] - p2[i], 2); + } + result = sqrt(sum); + return result; +} + +float compute_manhattan_distance(float* p1, float* p2, size_t dimensions) { + float result = 0; + + for (size_t i = 0; i < dimensions; i++) { + result += fabs(p1[i] - p2[i]); + } + return result; +} + +float compute_chebyshev_distance(float* p1, float* p2, size_t dimensions) { + float result = 0; + + for (size_t i = 0; i < dimensions; i++) { + int abs_diff = fabs(p1[i] - p2[i]); + if (abs_diff > result) { + result = abs_diff; + } + } + return result; +} diff --git a/values_utils.h b/values_utils.h new file mode 100644 index 0000000..d47531e --- /dev/null +++ b/values_utils.h @@ -0,0 +1,40 @@ +// Project : K-means +// Author : Dario GENGA + +#ifndef _KMEANS_VALUES_UTILS_H +#define _KMEANS_VALUES_UTILS_H + +#include <math.h> +#include <stdlib.h> + + +/// Get a random value in the min-max range. +/// \param min The minimal value (inclued). +/// \param max The maximal value (inclued). +/// \return A random int value. +int random_with_min_man_value(int min, int max); + +/// Swap x and y values +/// \param x The first value +/// \param y The second value +void swap(int *x, int *y); + +/// Compute the euclidean distance between two points of same dimensions. +/// \param p1 The values of the first point. +/// \param p2 The values of the second point. +/// \return The distance between the two points. +float compute_euclidean_distance(float* p1, float* p2, size_t dimensions); + +/// Compute the manhattan distance between two points of same dimensions. +/// \param p1 The values of the first point. +/// \param p2 The values of the second point. +/// \return The distance between the two points. +float compute_manhattan_distance(float* p1, float* p2, size_t dimensions); + +/// Compute the chebyshev distance between two points of same dimensions. +/// \param p1 The values of the first point. +/// \param p2 The values of the second point. +/// \return The distance between the two points. +float compute_chebyshev_distance(float* p1, float* p2, size_t dimensions); + +#endif -- GitLab