freesky

task_sem2_1

Nov 3rd, 2012
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.37 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. #define N 10
  6.  
  7. double *el(int n, int i, int j, double *a) {
  8.     return a + i * n + j;
  9. }
  10.  
  11. int maxLine(int n, int i, int j, double *a) {
  12.     double max = *el(n, i, j, a);
  13.     int maxi = i;
  14.  
  15.     for (int k = i; k < n; k++)
  16.         if (fabs(*el(n, k, j, a)) > fabs(max)) {
  17.             max = *el(n, k, j, a);
  18.             maxi = k;
  19.         }
  20.  
  21.     if (max == 0.0)
  22.         return -1;
  23.     else
  24.         return maxi;
  25. }
  26.  
  27. void swapLines(int n, double *a, double *b, int l, int m) {
  28.     for (int j = 0; j < n; j++) {
  29.         double t = *el(n, l, j, a);
  30.         *el(n, l, j, a) = *el(n, m, j, a);
  31.         *el(n, m, j, a) = t;
  32.     }
  33.  
  34.     double t = *(b + l);
  35.     *(b + l) = *(b + m);
  36.     *(b + m) = t;
  37. }
  38.  
  39. int getData(double *a, double *b) {
  40.     FILE *f;
  41.     char fname[64];
  42.     int n;
  43.  
  44.     while (1) {
  45.         printf("filename = "); scanf("%s", fname);
  46.         if ((f = fopen(fname, "r")) != NULL)
  47.             break;
  48.         else
  49.             printf("Ошибка открытия файла %s!\n", fname);
  50.     }
  51.  
  52.     int r = fscanf(f, "%d", &n);
  53.     if (!r || n < 1 || n > N) {
  54.         printf("Неверное число уравнений для решения!\n");
  55.         return 0;
  56.     }
  57.  
  58.     for (int i = 0; i < n; i++) {
  59.         for (int j = 0; j < n; j++)
  60.             if (!fscanf(f, "%lf", el(n, i, j, a))) {
  61.                 printf("Неверно заданный коэффициент (%d,%d)!\n", i + 1, j + 1);
  62.                 return 0;
  63.             }
  64.         if (!fscanf(f, "%lf", b + i)) {
  65.             printf("Неверно задано значение уравнения (%d)!\n", i + 1);
  66.             return 0;
  67.         }
  68.     }
  69.  
  70.     fclose(f);
  71.     return n;
  72. }
  73.  
  74. void printData(int n, double *a, double *b) {
  75.     for (int i = 0; i < n; i++) {
  76.         for (int j = 0; j < n; j++)
  77.             printf("%+-8.4lf\t", *el(n, i, j, a));
  78.         printf("|\t%+-8.4lf\n", *(b + i));
  79.     }
  80. }
  81.  
  82. int linsys(int n, double *a, double *b, double *x) {
  83.     for (int i = 0; i < n - 1; i++) { // for all lines excluding the last...
  84.         int maxl = maxLine(n, i, i, a); // ...we find main item in column and then...
  85.         if (maxl == -1)
  86.             return 0;
  87.         if (maxl > *el(n, i, i, a))
  88.             swapLines(n, a, b, i, maxl);
  89.  
  90.         for (int k = i + 1; k < n; k++) { // ...we will set all items from current column to zero excluding current line
  91.             double coeff = -(*el(n, k, i, a)) / *el(n, i, i, a);
  92.             for (int l = i; l < n; l++)
  93.                 *el(n, k, l, a) += *el(n, i, l, a) * coeff;
  94.  
  95.             *(b + k) += *(b + i) * coeff;
  96.         }
  97.     }
  98.  
  99.     if (*el(n, n - 1, n - 1, a) == 0.0)
  100.         return 0;
  101.     *(x + n - 1) = *(b + n - 1) / *el(n, n - 1, n - 1, a);
  102.     for (int i = n - 2; i >= 0; i--) {
  103.         double y = 0.0;
  104.         for (int j = i + 1; j < n; j++)
  105.             y += *el(n, i, j, a) * *(x + j);
  106.  
  107.         *(x + i) = (*(b + i) - y) / *el(n, i, i, a);
  108.     }
  109.  
  110.     return 1;
  111. }
  112.  
  113. int main(int argc, char *argv[]) {
  114.     double a[N*N], b[N], x[N];
  115.     int n;
  116.  
  117.     if ((n = getData(a, b)) == 0) return 1;
  118.  
  119.     if (linsys(n, a, b, x))
  120.         for (int i = 0; i < n; i++)
  121.             printf("x%d = %+.16e\n", i + 1, *(x + i));
  122.     else
  123.         printf("Система линейных уравнений вырождена\n");
  124.  
  125.     return 0;
  126. }
Advertisement
Add Comment
Please, Sign In to add comment