diff --git a/2025.04.18/01Ex/main.c b/2025.04.18/01Ex/main.c index cf6a447..c352c59 100644 --- a/2025.04.18/01Ex/main.c +++ b/2025.04.18/01Ex/main.c @@ -24,7 +24,6 @@ int main(int argc, char *argv[]) return 1; } - // TODO: Удалить вывод в stderr X = (double *)malloc(n * sizeof(double)); if (!X) { @@ -64,6 +63,16 @@ int main(int argc, char *argv[]) r = t1_solve(x_0, n, X, Y); t = (clock() - t) / CLOCKS_PER_SEC; + if (fabs(r - DBL_MAX) < DBL_EPSILON) + { + fprintf(stderr, "%s\n", ERR_FUNC); + + free(X); + free(Y); + + return 4; + } + printf("%s : Task = %d Result = %e Elapsed = %.2f\n", argv[0], task, r, t); free(X); diff --git a/2025.04.18/02Ex/io_status.h b/2025.04.18/02Ex/io_status.h index 778a4a1..8867bee 100644 --- a/2025.04.18/02Ex/io_status.h +++ b/2025.04.18/02Ex/io_status.h @@ -4,6 +4,7 @@ #define ERR_MEM "Error: Not enough memory!" #define ERR_OPEN "Error: Cannot open file" #define ERR_READ "Error: Cannot read file" +#define ERR_FUNC "Error: Algorithm is not applicable!" typedef enum _io_status { diff --git a/2025.04.18/02Ex/main.c b/2025.04.18/02Ex/main.c index 4e8ed94..19baa42 100644 --- a/2025.04.18/02Ex/main.c +++ b/2025.04.18/02Ex/main.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include "array_io.h" #include "io_status.h" @@ -63,6 +65,16 @@ int main(int argc, char *argv[]) r = t2_solve(x_0, n, X, Y); t = (clock() - t) / CLOCKS_PER_SEC; + if (fabs(r - DBL_MAX) < DBL_EPSILON) + { + fprintf(stderr, "%s\n", ERR_FUNC); + + free(X); + free(Y); + + return 4; + } + printf("%s : Task = %d Result = %e Elapsed = %.2f\n", argv[0], task, r, t); free(X); diff --git a/2025.04.18/02Ex/solve.c b/2025.04.18/02Ex/solve.c index 1287e22..654b3ec 100644 --- a/2025.04.18/02Ex/solve.c +++ b/2025.04.18/02Ex/solve.c @@ -7,16 +7,15 @@ // the Newton interpolation polynomial double t2_solve (const double x_0, const int n, const double * restrict X, double * restrict Y) { - double last_x, last_y; - - double value = 0; - double start_value = 0; + double value, start_value; for (int k = 0; k < n-1; ++k) { + double last_x; + double last_y = Y[n-1]; + // printf ("------- K = %d -------\n", k); - last_y = Y[n-1]; for (int i = n-2; i >= k; --i) { const double x_i = X[i-k]; @@ -33,16 +32,13 @@ double t2_solve (const double x_0, const int n, const double * restrict X, doubl } } - last_x = X[0]; start_value = 1; - value = Y[0]; + value = 0; - for (int i = 1; i < n; ++i) + for (int i = 0; i < n; ++i) { - start_value *= (x_0 - last_x); - if (fabs(Y[i]) > DBL_EPSILON) - value += Y[i] * start_value; - last_x = X[i]; + value += Y[i] * start_value; + start_value *= (x_0 - X[i]); } return value; diff --git a/2025.04.18/03Ex/Makefile b/2025.04.18/03Ex/Makefile new file mode 100644 index 0000000..792dc8d --- /dev/null +++ b/2025.04.18/03Ex/Makefile @@ -0,0 +1,42 @@ +WFLAGS = -fstack-protector-all -W -Wall -Wextra -Wunused \ +-Wempty-body -Wlogical-op -Wold-style-declaration -Wmissing-parameter-type \ +-Wignored-qualifiers -Winit-self -Wshadow -Wtype-limits \ +-Wpointer-arith -Wformat-security -Wmissing-format-attribute -Wformat=1 \ +-Wdeclaration-after-statement -Wbad-function-cast -Wnested-externs \ +-Wmissing-prototypes -Wmissing-declarations -Wold-style-definition \ +-Wcast-align -Werror -pedantic -pedantic-errors -Wfloat-equal \ +-Wwrite-strings -Wno-long-long -std=gnu99 -Wstrict-prototypes \ +-Wmissing-field-initializers -Wpointer-sign + +LDFLAGS = -std=gnu99 -mfpmath=sse -O3 +LDLIBS = -lm + +ifeq ($(OS),Windows_NT) + EXE = exe + CLEAN = del + LDLIBS += -lssp +else + EXE = out + CLEAN = rm -f +endif + +TARGET = a03.$(EXE) +OBJ = main.o solve.o array_io.o + +%.o: %.c + gcc $(WFLAGS) $(LDFLAGS) -c $< -o $@ + +$(TARGET): $(OBJ) + gcc $^ -o $@ $(LDLIBS) + +# Отладочная сборка (gdb) +gdb: LDFLAGS = -std=gnu99 -mfpmath=sse -g -O0 +gdb: clean $(TARGET) + +# Профилировочная сборка (gprof) +prof: LDFLAGS += -pg +prof: LDLIBS += -pg +prof: clean $(TARGET) + +clean: + $(CLEAN) *.o *$(EXE) diff --git a/2025.04.18/03Ex/array_io.c b/2025.04.18/03Ex/array_io.c new file mode 100644 index 0000000..780f0a3 --- /dev/null +++ b/2025.04.18/03Ex/array_io.c @@ -0,0 +1,26 @@ +#include +#include +#include "array_io.h" + +io_status read_values (double * restrict X, double * restrict Y, const int n, const char * restrict name) +{ + FILE *fp; + if (!(fp = fopen(name, "r"))) + return ERROR_OPEN; + + for (int i = 0; i < n; ++i) + if (fscanf(fp, "%lf\t%lf", X + i, Y + i) != 2) + { fclose(fp); return ERROR_READ; } + + fclose(fp); + return SUCCESS; +} + +void print_values (const double * restrict X, const double * restrict Y, const int n, const int p) +{ + int np = (n > p ? p : n); + + for (int i = 0; i < np; i++) + printf("f(%lf) = %lf\n", X[i], Y[i]); +} + diff --git a/2025.04.18/03Ex/array_io.h b/2025.04.18/03Ex/array_io.h new file mode 100644 index 0000000..7a0ce14 --- /dev/null +++ b/2025.04.18/03Ex/array_io.h @@ -0,0 +1,9 @@ +#ifndef ARRAY_IO_H +#define ARRAY_IO_H + +#include "io_status.h" + +io_status read_values (double * restrict X, double * restrict Y, const int n, const char * restrict name); +void print_values (const double * restrict X, const double * restrict Y, const int n, const int p); + +#endif diff --git a/2025.04.18/03Ex/io_status.h b/2025.04.18/03Ex/io_status.h new file mode 100644 index 0000000..8867bee --- /dev/null +++ b/2025.04.18/03Ex/io_status.h @@ -0,0 +1,16 @@ +#ifndef IO_STATUS_H +#define IO_STATUS_H + +#define ERR_MEM "Error: Not enough memory!" +#define ERR_OPEN "Error: Cannot open file" +#define ERR_READ "Error: Cannot read file" +#define ERR_FUNC "Error: Algorithm is not applicable!" + +typedef enum _io_status +{ + SUCCESS, + ERROR_OPEN, + ERROR_READ +} io_status; + +#endif diff --git a/2025.04.18/03Ex/main.c b/2025.04.18/03Ex/main.c new file mode 100644 index 0000000..3c86193 --- /dev/null +++ b/2025.04.18/03Ex/main.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include + +#include "array_io.h" +#include "io_status.h" +#include "solve.h" + +/* ./a.out x_0 n filename */ +int main(int argc, char *argv[]) +{ + double x_0, t, r = 0, *X = 0, *Y = 0; + int n, task = 3; + char *name = 0; + io_status ret; + + if ( + !((argc == 4) && + sscanf(argv[1], "%lf", &x_0) == 1 && + ((sscanf(argv[2], "%d", &n) == 1) && n > 0) && + ((name = argv[3]) && name)) + ) { + fprintf(stderr, "Usage: %s x_0 n filename\n", argv[0]); + return 1; + } + + X = (double *)malloc(n * sizeof(double)); + if (!X) + { + fprintf(stderr, "%s\n", ERR_MEM); + return 2; + } + + Y = (double *)malloc(n * sizeof(double)); + if (!Y) + { + free(X); + fprintf(stderr, "%s\n", ERR_MEM); + return 2; + } + + ret = read_values(X, Y, n, name); + do { + switch (ret) + { + case SUCCESS: + continue; + case ERROR_OPEN: + fprintf(stderr, "%s '%s'!\n", ERR_OPEN, name); + break; + case ERROR_READ: + fprintf(stderr, "%s '%s'!\n", ERR_READ, name); + break; + } + + free(X); + free(Y); + + return 3; + } while (0); + + t = clock(); + r = t3_solve(x_0, n, X, Y); + t = (clock() - t) / CLOCKS_PER_SEC; + + if (fabs(r - DBL_MAX) < DBL_EPSILON) + { + fprintf(stderr, "%s\n", ERR_FUNC); + + free(X); + free(Y); + + return 4; + } + + printf("%s : Task = %d Result = %e Elapsed = %.2f\n", argv[0], task, r, t); + + free(X); + free(Y); + + return 0; +} + diff --git a/2025.04.18/03Ex/solve.c b/2025.04.18/03Ex/solve.c new file mode 100644 index 0000000..32593b9 --- /dev/null +++ b/2025.04.18/03Ex/solve.c @@ -0,0 +1,36 @@ +#include "solve.h" + +#include +#include +#include + + +// Interpolation polynomial according to Aitken's scheme +double t3_solve (const double x_0, const int n, const double * restrict X, double * restrict Y) +{ + for (int k = 0; k < n-1; ++k) + { + double x_j; + double y_j = Y[n-1]; + +// printf ("------- K = %d -------\n", k); + + for (int i = n-2; i >= k; --i) + { + const double x_i = X[i-k]; + const double y_i = Y[i]; + x_j = X[i+1]; + + if (fabs(x_j - x_i) < DBL_EPSILON) + return DBL_MAX; + + Y[i+1] = ((x_0-x_i) * y_j - (x_0-x_j) * y_i) / (x_j - x_i); +// printf ("I = %d, f(x%d, ... , x%d) = %lf\n", i, i-k+1, i+2, Y[i+1]); + + y_j = y_i; + } + } + + return Y[n-1]; +} + diff --git a/2025.04.18/03Ex/solve.h b/2025.04.18/03Ex/solve.h new file mode 100644 index 0000000..d9da340 --- /dev/null +++ b/2025.04.18/03Ex/solve.h @@ -0,0 +1,6 @@ +#ifndef SOLVE_H +#define SOLVE_H + +double t3_solve (const double x_0, const int n, const double * restrict X, double * restrict Y); + +#endif diff --git a/2025.04.18/tests/constant.txt b/2025.04.18/tests/constant.txt new file mode 100644 index 0000000..5c40d7f --- /dev/null +++ b/2025.04.18/tests/constant.txt @@ -0,0 +1,7 @@ +0 5 +1 5 +2 5 +3 5 +4 5 +5 5 +6 6 diff --git a/2025.04.18/tests/err.txt b/2025.04.18/tests/err.txt new file mode 100644 index 0000000..db76567 --- /dev/null +++ b/2025.04.18/tests/err.txt @@ -0,0 +1,4 @@ +1 1 +1 1 +2 2 +2 3 diff --git a/2025.04.18/tests/x_2.txt b/2025.04.18/tests/x_2.txt index 542a65f..21e2ab0 100644 --- a/2025.04.18/tests/x_2.txt +++ b/2025.04.18/tests/x_2.txt @@ -1,6 +1,3 @@ 1 1 2 4 3 9 -4 16 -5 25 -6 36 diff --git a/2025.04.18/tests/x_3.txt b/2025.04.18/tests/x_3.txt new file mode 100644 index 0000000..04c260f --- /dev/null +++ b/2025.04.18/tests/x_3.txt @@ -0,0 +1,7 @@ +-1 -6 +0 0 +0.42265 0.3849 +1 0 +1.57735 -0.3849 +2 0 +3 6