From b4c7f2d872c294768c9d63603f9a7e74de2af0a9 Mon Sep 17 00:00:00 2001 From: AZEN-SGG Date: Wed, 2 Apr 2025 00:14:36 +0300 Subject: [PATCH] Task 14 doesn't work correctly --- 2025.03.21/dist/Matvei/Makefile | 6 +- 2025.04.04/14Ex/array_io.c | 9 +-- 2025.04.04/14Ex/array_io.h | 2 +- 2025.04.04/14Ex/main.c | 42 +++++++++++++- 2025.04.04/14Ex/matrix.c | 72 +++++++++++++++--------- 2025.04.04/14Ex/matrix.h | 4 +- 2025.04.04/14Ex/solve.c | 98 ++++++++++++++++++++++----------- 2025.04.04/14Ex/solve.h | 8 +-- 8 files changed, 165 insertions(+), 76 deletions(-) diff --git a/2025.03.21/dist/Matvei/Makefile b/2025.03.21/dist/Matvei/Makefile index 8204905..8899e6f 100644 --- a/2025.03.21/dist/Matvei/Makefile +++ b/2025.03.21/dist/Matvei/Makefile @@ -1,14 +1,14 @@ FLAGS = -fstack-protector-all -W -Wall -Wextra -Wunused -Wcast-align -Werror -pedantic -pedantic-errors -Wfloat-equal -Wpointer-arith -Wformat-security -Wmissing-format-attribute -Wformat=1 -Wwrite-strings -Wcast-align -Wno-long-long -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wdeclaration-after-statement -Wbad-function-cast -Wnested-externs -O3 -%.exe: %.o array.o comparison.o +%.out: %.o array.o comparison.o gcc $(FLAGS) $^ -o $@ -lm %.o: %.c gcc -c $(FLAGS) $< -all: a01.exe a02.exe a03.exe a04.exe a05.exe a06.exe a07.exe a08.exe a09.exe a10.exe +all: a01.out a02.out a03.out a04.out a05.out a06.out a07.out a08.out a09.out a10.out array.o: array.c array.h comparison.o: comparison.c comparison.h clean: - del *.o *.exe + rm *.o *.out diff --git a/2025.04.04/14Ex/array_io.c b/2025.04.04/14Ex/array_io.c index 2011499..188d677 100644 --- a/2025.04.04/14Ex/array_io.c +++ b/2025.04.04/14Ex/array_io.c @@ -1,4 +1,5 @@ #include +#include #include #include "array_io.h" @@ -9,7 +10,7 @@ io_status read_matrix(double *a, int n, const char *name) if (!(fp = fopen(name, "r"))) return ERROR_OPEN; for (i = 0; i < n; i++) for (j = 0; j < n; j++) - if (fscanf(fp, "%lf", a + i * m + j) != 1) + if (fscanf(fp, "%lf", a + i * n + j) != 1) {fclose(fp); return ERROR_READ;} fclose(fp); return SUCCESS; @@ -23,7 +24,7 @@ void print_matrix(const double *a, int n, int p) for (i = 0; i < np; i++) { for (j = 0; j < np; j++) - printf(" %10.3e", a[i * m + j]); + printf(" %10.3e", a[i * n + j]); printf("\n"); } } @@ -35,8 +36,8 @@ void init_matrix(double *a, int n, int k) int i, j; q = f[k-1]; for (i = 0; i < n; i++) - for (j = 0; j < m; j++) - a[i * m + j] = q(n, m, i+1, j+1); + for (j = 0; j < n; j++) + a[i * n + j] = q(n, n, i+1, j+1); } void init_identity_matrix(double *a, int n) diff --git a/2025.04.04/14Ex/array_io.h b/2025.04.04/14Ex/array_io.h index 51a8ac8..77b4508 100644 --- a/2025.04.04/14Ex/array_io.h +++ b/2025.04.04/14Ex/array_io.h @@ -7,6 +7,6 @@ io_status read_matrix(double *a, int n, const char *name); void print_matrix(const double *a, int n, int p); void init_matrix(double *a, int n, int k); -void init_identity_matrix(double *a, int n;) +void init_identity_matrix(double *a, int n); #endif diff --git a/2025.04.04/14Ex/main.c b/2025.04.04/14Ex/main.c index 44ab36b..53a4bdd 100644 --- a/2025.04.04/14Ex/main.c +++ b/2025.04.04/14Ex/main.c @@ -4,13 +4,14 @@ #include #include "array_io.h" #include "io_status.h" +#include "matrix.h" #include "solve.h" /* ./a.out n p k [filename] */ int main(int argc, char *argv[]) { - double t, *a, *x; - int n, p, k, res, *c, task = 14; + double t, *a, *x, r1 = 0, r2 = 0; + int n, p, k, res = 0, *c, task = 14; char *name = 0; if (!((argc == 4 || argc == 5) && @@ -42,7 +43,7 @@ int main(int argc, char *argv[]) if (!c) { free(a); - free(b); + free(x); printf("Not enough memory\n"); return 2; } @@ -82,6 +83,41 @@ int main(int argc, char *argv[]) res = t14_solve(n, a, x, c); t = omp_get_wtime() - t; + if (res == SINGULAR) + { + free(a); + free(x); + free(c); + + printf("The matrix is degenerate\n"); + return 4; + } + + if (name) + { /* из файла */ + io_status ret; + ret = read_matrix(a, n, name); + do { + switch (ret) + { + case SUCCESS: + continue; + case ERROR_OPEN: + printf("Cannot open %s\n", name); + break; + case ERROR_READ: + printf("Cannot read %s\n", name); + } + free(a); + free(x); + free(c); + return 3; + } while (0); + } else init_matrix(a, n, k); + + r1 = get_r1(n, a, x); + r2 = get_r2(n, a, x); + printf("Inverse matrix:\n"); print_matrix(x, n, p); printf("%s : Task = %d Res1 = %e Res2 = %e Elapsed = %.2f K = %d N = %d\n", argv[0], task, r1, r2, t, k, n); diff --git a/2025.04.04/14Ex/matrix.c b/2025.04.04/14Ex/matrix.c index 0cf5bbb..149ac2c 100644 --- a/2025.04.04/14Ex/matrix.c +++ b/2025.04.04/14Ex/matrix.c @@ -29,45 +29,65 @@ void matvec_mul(int n, const double * restrict A, const double * restrict x, dou } } -double get_r1(const double * restrict A, const double * restrict x_k, const double * restrict b, int n) +double get_r1(const int n, const double * restrict A, const double * restrict X) { - double norm_r1x_1 = 0; - double residual_norm_1 = 0; - double r1 = 0; + double maximum = 0; - #pragma omp parallel for reduction(+:residual_norm_1, norm_r1x_1) - for (int i = 0; i < n; ++i) + if (n > 4000) return 0; + + #pragma omp parallel for reduction(max:maximum) + for (int j = 0; j < n; ++j) { - double bi = b[i]; double sum = 0; #pragma omp simd reduction(+:sum) - for (int j = 0; j < n; ++j) - sum += A[i*n + j] * x_k[j]; - - residual_norm_1 += fabs(sum - bi); - norm_r1x_1 += fabs(bi); + for (int i = 0; i < n; ++i) + { + int in = i*n; + double sum_ij = - (i == j); + + #pragma omp simd reduction(+:sum_ij) + for (int k = 0; k < n; ++k) + sum_ij += A[in + k] * X[k*n + j]; + + sum += fabs(sum_ij); + } + + if (maximum < sum) + maximum = sum; } - r1 = residual_norm_1 / norm_r1x_1; - - return r1; + return maximum; } -double get_r2_value(const double * restrict x_k, int n) +double get_r2(const int n, const double * restrict A, const double * restrict X) { - double relative_error = 0; - double total_diff = 0; - double template_sum = 0; + double maximum = 0; - #pragma omp parallel for reduction(+:total_diff, template_sum) - for (int i = 0; i < n; ++i) + if (n > 4000) return 0; + + #pragma omp parallel for reduction(max:maximum) + for (int j = 0; j < n; ++j) { - short int modi = !(i & 1); - total_diff += fabs(x_k[i] - modi); - template_sum += modi; + double sum = 0; + + #pragma omp simd reduction(+:sum) + for (int i = 0; i < n; ++i) + { + int in = i*n; + double sum_ij = - (i == j); + + #pragma omp simd reduction(+:sum_ij) + for (int k = 0; k < n; ++k) + sum_ij += X[in + k] * A[k*n + j]; + + sum += fabs(sum_ij); + } + + if (maximum < sum) + maximum = sum; } - relative_error = total_diff / template_sum; - return relative_error; + return maximum; } + diff --git a/2025.04.04/14Ex/matrix.h b/2025.04.04/14Ex/matrix.h index a170f22..72e27c0 100644 --- a/2025.04.04/14Ex/matrix.h +++ b/2025.04.04/14Ex/matrix.h @@ -3,7 +3,7 @@ void init_vec_b(const double * restrict a, double * restrict b, int n); void matvec_mul(int n, const double * restrict A, const double * restrict x, double * restrict x_k); -double get_r1(const double * restrict A, const double * restrict x_k, const double * restrict b, int n); -double get_r2_value(const double * restrict x_k, int n); +double get_r1(const int n, const double * restrict A, const double * restrict X); +double get_r2(const int n, const double * restrict A, const double * restrict X); #endif diff --git a/2025.04.04/14Ex/solve.c b/2025.04.04/14Ex/solve.c index 6fb23cd..5bdc3e8 100644 --- a/2025.04.04/14Ex/solve.c +++ b/2025.04.04/14Ex/solve.c @@ -1,80 +1,114 @@ #include "solve.h" #include "io_status.h" #include +#include // c - changes in rows int t14_solve(int n, double * restrict A, double * restrict X, int * restrict c) { for (int k = 0; k < n; ++k) { - max_t max = { .val = -1.0 }; - - #pragma omp parallel for reduction(+:max) + double maximum = -1.; + int max_i = 0, max_j = 0; + + #pragma omp parallel for collapse(2) reduction(max:maximum) for (int i = k; i < n; ++i) for (int j = k; j < n; ++j) { double aij = fabs(A[i * n + j]); - if (aij > max.val) { - max.val = aij; - max.i = i; - max.j = j; + #pragma omp critical + { + if (aij > maximum) { + maximum = aij; + max_i = i; + max_j = j; + } } } - if (fabs(max.val) < DBL_EPSILON) + if (fabs(maximum) < DBL_EPSILON) return SINGULAR; - if (max.i != k) + if (max_i != k) { + int kn = k*n; + int in = max_i*n; + #pragma omp simd - for (int kn = k*n, in = max.i*n; kn < k*(n+1); ++kn, ++in) + for (int i = 0; i < k; ++i) { - double swap = X[kn]; - X[kn] = X[in]; - X[in] = swap; - } + int kni = kn+i, ini = in+i; + double swap = X[kni]; + X[kni] = X[ini]; + X[ini] = swap; + } #pragma omp parallel for simd - for (int kn = k*n+k, in = max.i*n+k; kn < (k+1)*n; ++kn, ++in) + for (int i = k; i < n; ++i) { - double swap = X[kn]; - X[kn] = X[in]; - X[in] = swap; + int kni = kn+i, ini = in+i; + double swap = X[kni]; + X[kni] = X[ini]; + X[ini] = swap; - swap = A[kn]; - A[kn] = A[in]; - A[in] = swap; + swap = A[kni]; + A[kni] = A[ini]; + A[ini] = swap; } } - if (max.j != j) + if (max_j != k) { - int swap_temp = c[max.j]; - c[max.j] = k; + int swap_temp = c[max_j]; + c[max_j] = k; c[k] = swap_temp; #pragma omp simd for (int in = k * n; in < n; in+=n) { double swap = A[in + k]; - A[in + k] = A[in + max.j]; - A[in + max.j] = swap; + A[in + k] = A[in + max_j]; + A[in + max_j] = swap; } } gauss_inverse(n, k, A, X); - gauss_back_substitution(n, A, X); + } - for (int k = 0; k < n; ++k) + gauss_back_substitution(n, A, X); + + for (int k = 0; k < n; ++k) + { + int str_k = k; + int str_i = c[k]; + + if (str_i != k) { - int str - while ( + #pragma omp parallel for + for (int j = 0; j < n; ++j) + { + double elem = X[k*n + j]; + + do { + X[str_i*n + j] = elem; + elem = X[str_i*n + j]; + + str_k = str_i; + str_i = c[str_i]; + c[str_k] = str_k; + } while (str_i != k); + + X[k*n + j] = elem; + } } } + + return 0; } void gauss_inverse(const int n, const int k, double * restrict A, double * restrict X) { - const int kn = k*n, const int kk = kn + k; + const int kn = k*n; + const int kk = kn + k; const double inv_akk = 1./A[kn + k]; A[kn + k] = 1.; @@ -119,7 +153,7 @@ void gauss_back_substitution(const int n, double * restrict A, double * restrict const int kn = k * n; #pragma omp parallel for - for (int i = 0; i < j; ++i) + for (int i = 0; i < k; ++i) { const int in = i*n; const double aik = A[in + k]; diff --git a/2025.04.04/14Ex/solve.h b/2025.04.04/14Ex/solve.h index d098c47..2e54ac9 100644 --- a/2025.04.04/14Ex/solve.h +++ b/2025.04.04/14Ex/solve.h @@ -1,10 +1,8 @@ #ifndef SOLVE_H #define SOLVE_H -typedef struct { - double val; - int i; - int j; -} max_t; +int t14_solve(int n, double * restrict A, double * restrict X, int * restrict c); +void gauss_inverse(const int n, const int k, double * restrict A, double * restrict X); +void gauss_back_substitution(const int n, double * restrict A, double * restrict X); #endif