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

ADD: finalised theoretical implementation, not tested

parent e1804f98
Branches
No related tags found
No related merge requests found
......@@ -12,49 +12,79 @@
#include "vector.h"
enum DistanceFunctionType {
EUCLID = 0, MANHATTAN = 1, CHEBYSHEV = 2
};
enum DataType {
FLOAT = 0, INT = 1
};
fpt_t (* const DIST_FUNC_INT[])(const vector_int_t*, const vector_int_t*) = {
distance_euclid_int,
distance_manhattan_int,
distance_chebyshev_int};
fpt_t (* const DIST_FUNC_FPT[])(const vector_fpt_t*, const vector_fpt_t*) = {
distance_euclid_fpt,
distance_manhattan_fpt,
distance_chebyshev_fpt};
void help(const char* callname) {
fprintf(stderr, "\nUSAGE: %s <INPUT_FILE> <OUTPUT_FILE>\n", callname);
fprintf(stderr,
"\nUSAGE: %s -i INPUT_FILE -o OUTPUT_FILE -d [euclid,manhattan,chebyshev] -t [fpt,int]\n",
callname);
}
bool init(int argc, char** argv, char** ipath, char** opath) {
if (argc <= 1) {
help(argv[0]);
return false;
}
if (argc > 1) {
*ipath = argv[1];
if (access(*ipath, F_OK) == -1) {
fprintf(stderr, "IFILE: [ %s ] file does not exist !", *ipath);
return false;
void parse_args(int argc, char** argv, char** ipath, char** opath, enum DistanceFunctionType* df, enum DataType* type) {
int opt;
while ((opt = getopt(argc, argv, "i:o:d:t:h")) != -1) {
switch (opt) {
case 'h':
help(argv[0]);
exit(EXIT_FAILURE);
case 'i':
*ipath = optarg;
break;
case 'o':
*opath = optarg;
break;
case 'd':
if (strcmp(optarg, "euclid") == 0) *df = EUCLID;
else if (strcmp(optarg, "manhattan") == 0) *df = MANHATTAN;
else if (strcmp(optarg, "chebyshev") == 0) *df = CHEBYSHEV;
break;
case 't':
if (strcmp(optarg, "fpt") == 0) *type = FLOAT;
else if (strcmp(optarg, "int") == 0) *type = INT;
break;
case '?':
//TODO: perhaps add an "unknown option" message on stderr
break;
default:
// https://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html
abort();
}
} else {
*ipath = NULL;
}
*opath = argc > 2 ? argv[2] : NULL;
return true;
}
void read_points_int(const char* ipath) {
}
int main(int argc, char** argv) {
// INIT
char (* ipath), (* opath);
if (!init(argc, argv, &ipath, &opath)) return EXIT_FAILURE;
int main_int(const char* ipath, const char* opath, const enum DistanceFunctionType dist_func_type) {
// READ
FILE* ifile = ipath != NULL ? fopen(ipath, "r") : stdin;
const size_t dim = io_read_int(ifile);
const size_t nb_clusters = io_read_int(ifile);
if (0 <= dim) {
printf("DIMENSION MUST BE STRICTLY POSITIVE !\n");
fclose(ifile);
return EXIT_FAILURE;
}
if (0 <= nb_clusters) {
printf("NUMBER OF CLUSTERS MUST BE STRICTLY POSITIVE !\n");
fclose(ifile);
return EXIT_FAILURE;
}
list_points_int_t* list = io_get_vector_list_int(ifile, dim);
......@@ -66,7 +96,7 @@ int main(int argc, char** argv) {
list = NULL;
// ALGORITHM
cluster_int_t** clusters = kmeans_init_clusters_int((const vector_int_t**) points, point_count, nb_clusters);
kmeans_int(points, point_count, clusters, nb_clusters, distance_euclid_int); //TODO: choose dist func with command line
kmeans_int(points, point_count, clusters, nb_clusters, DIST_FUNC_INT[dist_func_type]);
// WRITE
FILE* ofile = opath != NULL ? fopen(opath, "w") : stdout;
fprintf(ofile, "%lud\n%lud\n", dim, nb_clusters);
......@@ -74,3 +104,54 @@ int main(int argc, char** argv) {
fclose(ofile);
return EXIT_SUCCESS;
}
int main_fpt(const char* ipath, const char* opath, const enum DistanceFunctionType dist_func_type) {
// READ
FILE* ifile = ipath != NULL ? fopen(ipath, "r") : stdin;
const size_t dim = io_read_int(ifile);
const size_t nb_clusters = io_read_int(ifile);
if (0 <= dim) {
printf("DIMENSION MUST BE STRICTLY POSITIVE !\n");
fclose(ifile);
return EXIT_FAILURE;
}
if (0 <= nb_clusters) {
printf("NUMBER OF CLUSTERS MUST BE STRICTLY POSITIVE !\n");
fclose(ifile);
return EXIT_FAILURE;
}
list_points_fpt_t* list = io_get_vector_list_fpt(ifile, dim);
fclose(ifile);
ifile = NULL;
const size_t point_count = list->size;
vector_fpt_t** points = list_points_to_array_fpt(list);
list_points_destroy_fpt(list, false);
list = NULL;
// ALGORITHM
cluster_fpt_t** clusters = kmeans_init_clusters_fpt((const vector_fpt_t**) points, point_count, nb_clusters);
kmeans_fpt(points, point_count, clusters, nb_clusters, DIST_FUNC_FPT[dist_func_type]);
// WRITE
FILE* ofile = opath != NULL ? fopen(opath, "w") : stdout;
fprintf(ofile, "%lud\n%lud\n", dim, nb_clusters);
io_write_clusters_to_file_fpt(ofile, clusters, point_count);
fclose(ofile);
return EXIT_SUCCESS;
}
int main(int argc, char** argv) {
// init defaults
char (* ipath) = NULL, (* opath) = NULL;
enum DistanceFunctionType disttype = EUCLID;
enum DataType datatype = FLOAT;
// parse args
parse_args(argc, argv, &ipath, &opath, &disttype, &datatype);
switch (datatype) {
case FLOAT:
return main_fpt(ipath, opath, disttype);
case INT:
return main_int(ipath, opath, disttype);
default:
abort();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment