From 7daefc590ab3a810c4ac31d5be5f6ba1b5d3d3d4 Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Sat, 7 Mar 2020 01:50:09 +0000 Subject: [PATCH] ex-7: add pre-trained mode --- ex-7/main.c | 50 +++++++++++++++++++++++++++++++++++--------------- makefile | 2 +- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/ex-7/main.c b/ex-7/main.c index 589bd58..7bdd6a0 100644 --- a/ex-7/main.c +++ b/ex-7/main.c @@ -9,16 +9,19 @@ struct options { size_t nsig; size_t nnoise; int iter; + int trained; + double weights[3]; }; int main(int argc, char **argv) { /* Set default options */ struct options opts; - opts.mode = "fisher"; - opts.nsig = 800; - opts.nnoise = 1000; - opts.iter = 5; + opts.mode = "fisher"; + opts.nsig = 800; + opts.nnoise = 1000; + opts.iter = 5; + opts.trained = 0; /* Process CLI arguments */ for (size_t i = 1; i < argc; i++) { @@ -26,13 +29,20 @@ int main(int argc, char **argv) { else if (!strcmp(argv[i], "-s")) opts.nsig = atol(argv[++i]); else if (!strcmp(argv[i], "-n")) opts.nnoise = atol(argv[++i]); else if (!strcmp(argv[i], "-i")) opts.nnoise = atoi(argv[++i]); + else if (!strcmp(argv[i], "-w")) { + opts.trained = 1; + for (int j = 0; j < 3; j++) + opts.weights[j] = atof(argv[++i]); + } else { - fprintf(stderr, "Usage: %s -[hiIntp]\n", argv[0]); - fprintf(stderr, "\t-h\tShow this message.\n"); - fprintf(stderr, "\t-m MODE\tThe disciminant to use: 'fisher' for " + fprintf(stderr, "Usage: %s -[hminw]\n", argv[0]); + fprintf(stderr, " -h\t\tShow this message.\n"); + fprintf(stderr, " -m MODE\tThe training mode to use: 'fisher' for \n\t\t" "Fisher linear discriminant, 'percep' for perceptron.\n"); - fprintf(stderr, "\t-i N\tThe number of training iterations (for perceptron).\n"); - fprintf(stderr, "\t-n N\tThe number of events in noise class.\n"); + fprintf(stderr, " -i N\t\tThe number of training iterations " + "(for perceptron only).\n"); + fprintf(stderr, " -n N\t\tThe number of events in noise class.\n"); + fprintf(stderr, " -w W₁ W₂ B\tSet weights and bias (if pre-trained).\n"); return EXIT_FAILURE; } } @@ -52,9 +62,19 @@ int main(int argc, char **argv) { sample_t *noise = generate_normal(r, opts.nnoise, &par_noise); gsl_vector *w; - double t_cut; + double cut; - if (!strcmp(opts.mode, "fisher")) { + if (opts.trained) { + /* Pre-trained + * + * Use the provided weigths and bias. + */ + fputs("# Pre-trained \n\n", stderr); + gsl_vector_view v = gsl_vector_view_array(opts.weights, 2); + w = &v.vector; + cut = opts.weights[2]; + } + else if (!strcmp(opts.mode, "fisher")) { /* Fisher linear discriminant * * First calculate the direction w onto @@ -65,7 +85,7 @@ int main(int argc, char **argv) { fputs("# Linear Fisher discriminant\n\n", stderr); double ratio = opts.nsig / (double)opts.nnoise; w = fisher_proj(signal, noise); - t_cut = fisher_cut(ratio, w, signal, noise); + cut = fisher_cut(ratio, w, signal, noise); } else if (!strcmp(opts.mode, "percep")) { /* Perceptron @@ -75,7 +95,7 @@ int main(int argc, char **argv) { * solution in `iter` iterations. */ fputs("# Perceptron \n\n", stderr); - w = percep_train(signal, noise, opts.iter, &t_cut); + w = percep_train(signal, noise, opts.iter, &cut); } else { fputs("\n\nerror: invalid mode. select either" @@ -89,9 +109,9 @@ int main(int argc, char **argv) { fprintf(stderr, "* w: [%.3f, %.3f]\n", gsl_vector_get(w, 0), gsl_vector_get(w, 1)); - fprintf(stderr, "* t_cut: %.3f\n", t_cut); + fprintf(stderr, "* cut: %.3f\n", cut); gsl_vector_fprintf(stdout, w, "%g"); - printf("%f\n", t_cut); + printf("%f\n", cut); /* Print data to stdout for plotting. * Note: we print the sizes to be able diff --git a/makefile b/makefile index 03de3f9..c0e3626 100644 --- a/makefile +++ b/makefile @@ -24,7 +24,7 @@ ex-5/bin/%: ex-5/%.c ex-6/bin/main: ex-6/rl.c ex-6/fft.c $(CCOMPILE) -ex-7/bin/main: ex-7/main.c ex-7/common.c ex-7/fisher.c +ex-7/bin/main: ex-7/main.c ex-7/common.c ex-7/fisher.c ex-7/percep.c $(CCOMPILE) misc/pdfs: misc/pdfs.c