diff options
Diffstat (limited to 'main_23.c')
-rw-r--r-- | main_23.c | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/main_23.c b/main_23.c deleted file mode 100644 index 8460415..0000000 --- a/main_23.c +++ /dev/null @@ -1,182 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> - -struct dval { double x, y; }; -typedef double (*func_t)(double); - -#ifdef PIPE_GNUPLOT - #include <unistd.h> - #include <fcntl.h> - - void print_table(FILE*, const struct dval *, long int); - /// This function is creating a 'gnuplot' pipe - /// and writing data to it to be plotted - void pipe_gnuplot(struct dval *table, long len) { - FILE* gp = popen("gnuplot", "w"); - if (!gp) return; -#ifdef TERMINAL_PLOT - fputs("set terminal block\n", gp); -#endif // TERMINAL_PLOT - fputs("plot '-' with lines\n", gp); - print_table(gp, table, len); - fputs("e\n", gp); - fflush(gp); - - getchar(); - pclose(gp); - } -#endif // PIPE_GNUPLOT - -#ifdef DYNAMIC_LOAD - #include <dlfcn.h> - void* handle = NULL; -#endif // DYNAMIC_LOAD - -double sin2(double x) { - double y = sin(x); - return y*y; -} -double cos2(double x) { - double y = cos(x); - return y*y; -} -double __sincos(double x) { - // sin(x)cos(x) = sin(2x)/2 - return sin(2*x)/2; -} -double sin2x(double x) { - return sin(2*x); -} - -/// generates the table as asked in the task. -/// The core function for task 2 -struct dval *get_table(func_t f, double start, double end, double step, long *length) { - long tlength = lround((end-start)/step); - struct dval *vals = calloc(tlength, sizeof(struct dval)); - for (long i = 0; i < tlength; ++i) { - double x = start + step * i; - // Not accumulative because if step is too small, - // start will never increment - vals[i] = (struct dval){.x = x, .y = f(x)}; - } - *length = tlength; - return vals; -} - -/// generates the table for derivative of function f. -/// The core function for task 3 -struct dval *differentiate(func_t f, double start, double end, double step, long *length) { - long tlength = lround((end-start)/step); - struct dval *vals = calloc(tlength, sizeof(struct dval)); - for (long i = 0; i < tlength; ++i) { - double x = start + step * i; - // central difference - double y = (f(x+step) - f(x-step))/ (2*step); - vals[i] = (struct dval){.x = x, .y = y}; - } - *length = tlength; - return vals; -} - -void print_table(FILE* stream, const struct dval *table, long size) { - for (long i = 0; i < size; ++i) { - fprintf(stream, "%lg %lg\n", table[i].x, table[i].y); - } -} - - -void print_help(int status) { - const char *help = - "This program is Licensed under 'the unlicense license'\n\n" - "Usage: ./t23 -f func_name -o output_file [-x number -h -d]\n" - "\t-h: this help\n" - "\t-d: differentiate function (do task 3)\n" - "\t-f: function: either 'sin2', 'cos2', 'sincos', 'tg' or 'sin2x' .\n" - "\t\tif compiled with -DDYNAMIC_LOAD, file name with dynamic function.\n" - "\t-o: output file.\n" - "\t-x: only needed with -d flag - differentiation step (the dx)\n\n" - "NOTE: the function in dynamic library must be named 'f'.\n" - "NOTE 2: with flag -DPIPE_GNUPLOT output will be piped in gnuplot\n"; - puts(help); - exit(status); -} - -/// Get the function based on the command line flags - either use -/// existing or load one from dynamic library -func_t get_function(const char* name) { - if (!strcmp(name, "cos2")) - return &cos2; - if (!strcmp(name, "sin2")) - return &sin2; - if (!strcmp(name, "sincos")) - return &__sincos; - if (!strcmp(name, "tg")) - return &tan; - if (!strcmp(name, "sin2x")) - return &sin2x; -#ifndef DYNAMIC_LOAD - fputs("ERROR: unknown function. To use dynamic loading, compile with `-DDYNAMIC_LOAD`.\n", stderr); - exit(EXIT_FAILURE); -#else // DYNAMIC_LOAD - handle = dlopen(name, RTLD_NOW); - if (!handle) goto fail; - func_t f = dlsym(handle, "f"); - if (!f) goto fail; - return f; -fail: - fputs(dlerror(), stderr); - exit(EXIT_FAILURE); -#endif // DYNAMIC_LOAD -} - -int main(int argc, char *argv[]) { - func_t function = NULL; - const char *out = NULL; - char task2 = 1; - float dx = 0.0; - // casual argument loop - for (int i = 1; i < argc; ++i) { - if (!strcmp(argv[i], "-h")) - print_help(EXIT_SUCCESS); - else if (!strcmp(argv[i], "-f")) - function = get_function(argv[++i]); - else if (!strcmp(argv[i], "-o")) - out = argv[++i]; - else if (!strcmp(argv[i], "-d")) - task2 = 0; - else if (!strcmp(argv[i], "-x")) - dx = atof(argv[++i]); - else print_help(EXIT_FAILURE); - } - // if function or output file is not set, or if dx is not set for task3, - // then exit with failure - if ((!function || !out) || (!task2 && dx == 0.0)) - print_help(EXIT_FAILURE); - - long table_len; - struct dval *table = NULL; - if (task2) - table = get_table(function, 0, 3, 0.01, &table_len); - else // task 3 - table = differentiate(function, -3, 3, dx, &table_len); - - // print data to stdout and to file - print_table(stdout, table, table_len); - FILE *f = fopen(out, "w+"); - if (f) print_table(f, table, table_len); - else perror(out); - -#ifdef PIPE_GNUPLOT - pipe_gnuplot(table, table_len); -#endif // PIPE_GNUPLOT - - fclose(f); - free(table); -#ifdef DYNAMIC_LOAD - if (handle) dlclose(handle); -#endif // DYNAMIC_LOAD - exit(EXIT_SUCCESS); -} - |