lab.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. #define _USE_MATH_DEFINES
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<math.h>
  5. #include<time.h>
  6. // Необязательный флаг для дебага (можно удалить)
  7. #define DEBUG 0
  8. // Фиксированная размерность матрицы (обрабатывается препроцессором, просто alias)
  9. #define N 10
  10. //
  11. struct N_eps {
  12. double eps;
  13. int I;
  14. };
  15. // Тип вектора
  16. typedef double vec[N];
  17. // Тип матрицы
  18. typedef double mat[N][N];
  19. // Скалярное произведение
  20. double dot(vec v, vec u) {
  21. double res = 0;
  22. for(int i = 0; i < N; i++) res += v[i]*u[i];
  23. return res;
  24. }
  25. // Прибавление вектора
  26. void add(vec v, vec u, vec result) {
  27. for(int i = 0; i < N; i++) {
  28. result[i] = v[i] + u[i];
  29. }
  30. }
  31. // Вычитание вектора
  32. void sub(vec v, vec u, vec result) {
  33. for(int i = 0; i < N; i++) {
  34. result[i] = v[i] - u[i];
  35. }
  36. }
  37. // Умножение на скаляр
  38. void mul(vec v, double a) {
  39. for(int i = 0; i < N; i++) {
  40. v[i] *= a;
  41. }
  42. }
  43. // Умножение матрицы на вектор (res = m*v)
  44. void apply(mat m, vec v, vec res) {
  45. for(int i = 0; i < N; i++) {
  46. res[i] = 0;
  47. for(int j = 0; j < N; j++) {
  48. res[i] += m[i][j] * v[j];
  49. }
  50. }
  51. }
  52. // Копирование матрицы (copy = m)
  53. void copy_vec(vec copy, vec x) {
  54. for(int i = 0; i < N; i++) {
  55. copy[i] = x[i];
  56. }
  57. }
  58. //Ошибка между двумя векторами
  59. double error(vec a, vec b){
  60. double error = 0;
  61. for (int i = 0; i < N; i++) {
  62. if (error < fabs(a[i] - b[i])) {
  63. error = fabs(a[i] - b[i]);
  64. }
  65. }
  66. return error;
  67. }
  68. // Чтение матрицы из файла
  69. void mat_from_file(FILE* f, mat m) {
  70. double d;
  71. for (int i = 0; i < N; i++) {
  72. for (int j = 0; j < N; j++) {
  73. fscanf(f, "%lf,", &d);
  74. m[i][j] = d;
  75. }
  76. }
  77. }
  78. // Чтение матрицы из файла
  79. void min_max_from_file(FILE* f, vec v) {
  80. double d;
  81. for (int i = 0; i < 2; i++) {
  82. fscanf(f, "%lf,", &d);
  83. v[i] = d;
  84. }
  85. }
  86. // Красивая печать матрицы
  87. void print_mat(mat m) {
  88. for(int j = 0; j < N; j++) {
  89. printf("-----------|");
  90. }
  91. printf("\n");
  92. for(int i = 0; i < N; i++) {
  93. for(int j = 0; j < N; j++) {
  94. printf("%10.4lf |", m[i][j]);
  95. }
  96. printf("\n");
  97. for(int j = 0; j < N; j++) {
  98. printf("-----------|");
  99. }
  100. printf("\n");
  101. }
  102. }
  103. // Красивая печать вектора
  104. void print_vec(vec v) {
  105. for(int j = 0; j < N; j++) {
  106. printf("%10.4lf |", v[j]);
  107. }
  108. printf("\n");
  109. }
  110. void mx_b(mat m, vec x, vec b, vec result){
  111. apply(m,x,result);
  112. sub(b,result,result);
  113. }
  114. // Решение СЛАУ методом Ричардсона
  115. struct N_eps solve(mat m, double eps, int M, double min, double max) {
  116. struct N_eps result;
  117. result.I = 0;
  118. vec x = { 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9};
  119. vec x1;
  120. vec b;
  121. vec var;
  122. vec x_k = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
  123. apply(m,x_k,b);
  124. print_vec(b);
  125. for (int k = 0; k < M; k++) {
  126. double t = cos(M_PI * (2 * (k + 1) - 1) / (2 * M));
  127. printf("\n t = %lf\n", t);
  128. double alpha = 2.0 / ((min + max) + ((max - min)*t));
  129. mx_b(m, x, b, var);
  130. //print_vec(var);
  131. mul(var,alpha);
  132. //print_vec(var);
  133. add(x,var,x1);
  134. print_vec(x1);
  135. if (error(x,x1) < eps){
  136. result.eps = error(x,x1);
  137. result.I += 1;
  138. break;
  139. }
  140. result.eps = error(x,x1);
  141. result.I += 1;
  142. copy_vec(x,x1);
  143. print_vec(x);
  144. }
  145. return result;
  146. }
  147. //взять из мат лаба
  148. int main(){
  149. FILE* f;
  150. FILE* f2;
  151. if ((f = fopen("lab4_1.txt", "r")) == NULL) return 1;
  152. if ((f2 = fopen("min_max.txt", "r")) == NULL) return 1;
  153. mat m;
  154. vec min_max;
  155. FILE* file;
  156. FILE* file2;
  157. if ((file = fopen("lab_4_cond.csv", "w+")) == NULL) return 1;
  158. if ((file2 = fopen("lab_4_time.csv", "w+")) == NULL) return 1;
  159. for (int k = 0; k < 8; k++){
  160. mat_from_file(f, m);
  161. min_max_from_file(f2, min_max);
  162. clock_t begin = clock();
  163. struct N_eps result = solve(m, pow(10, -5), 1000, min_max[0], min_max[1]);
  164. clock_t end = clock();
  165. printf("\n\n\n");
  166. fprintf(file, "%.5lf, %e\n", pow(10, k), result.eps);
  167. fprintf(file2, "%.5lf, %e\n", pow(10, k), ((float)(end - begin) / CLOCKS_PER_SEC));
  168. }
  169. fclose(f);
  170. fclose(f2);
  171. fclose(file);
  172. fclose(file2);
  173. FILE* fbad = fopen("lab_4_error_bad.txt", "r");
  174. FILE* fminbad = fopen("min_max2.txt", "r");
  175. FILE* fbade = fopen("lab_4_error_bad.csv", "w+");
  176. FILE* fbadm = fopen("lab_4_M_bad.csv", "w+");
  177. mat_from_file(fbad,m);
  178. min_max_from_file(fminbad, min_max);
  179. for (int i = 1; i < 6; i++) {
  180. struct N_eps result = solve(m, pow(10, -i), 1000, min_max[0], min_max[1]);
  181. fprintf(fbade, "%e, %e\n", pow(10, -i), result.eps);
  182. fprintf(fbadm, "%e, %d\n", pow(10, -i), result.I);
  183. }
  184. fclose(fbad);
  185. fclose(fminbad);
  186. fclose(fbade);
  187. fclose(fbadm);
  188. FILE* fgood = fopen("lab_4_error_good.txt", "r");\
  189. FILE* fmingood = fopen("min_max3.txt", "r");
  190. FILE* fgoode = fopen("lab_4_error_good.csv", "w+");
  191. FILE* fgoodm = fopen("lab_4_M_good.csv", "w+");
  192. mat_from_file(fgood,m);
  193. min_max_from_file(fmingood, min_max);
  194. for (int i = 1; i < 16; i++) {
  195. struct N_eps result = solve(m, pow(10, -i), 1000, min_max[0], min_max[1]);
  196. fprintf(fgoodm, "%e, %d\n", pow(10, -i), result.I);
  197. fprintf(fgoode, "%e, %e\n", pow(10, -i), result.eps);
  198. }
  199. fclose(fgood);
  200. fclose(fmingood);
  201. fclose(fgoode);
  202. fclose(fgoodm);
  203. FILE* fbad2 = fopen("lab_4_error_bad.txt", "r");
  204. FILE* fminbad2 = fopen("min_max2.txt", "r");
  205. FILE* fbadmt = fopen("lab_4_M_bad_tol.csv", "w+");
  206. mat_from_file(fbad2,m);
  207. min_max_from_file(fminbad2, min_max);
  208. for (int i = 0; i < 41; i++) {
  209. struct N_eps result = solve(m, pow(10, -15), i, min_max[0], min_max[1]);
  210. fprintf(fbadmt, "%e, %d\n", result.eps, result.I);
  211. }
  212. fclose(fbad2);
  213. fclose(fminbad2);
  214. fclose(fbadmt);
  215. FILE* fgood2 = fopen("lab_4_error_good.txt", "r");
  216. FILE* fmindoof2 = fopen("min_max3.txt", "r");
  217. FILE* fgoodmt2 = fopen("lab_4_M_good_tol.csv", "w+");
  218. mat_from_file(fgood2,m);
  219. min_max_from_file(fmindoof2, min_max);
  220. for (int i = 0; i < 41; i++) {
  221. struct N_eps result = solve(m, pow(10, -15), i, min_max[0], min_max[1]);
  222. fprintf(fgoodmt2, "%e, %d\n", result.eps, i);
  223. }
  224. fclose(fgood2);
  225. fclose(fmindoof2);
  226. fclose(fgoodmt2);
  227. }