Val_Kir

2lab13 (метод Ж-Г)

Jul 4th, 2018
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.48 KB | None | 0 0
  1. /*  Написать функцию вычисления определителя методом Жордана-Гаусса.
  2.     Обязательный входной параметр – исходная матрица.
  3.     Поиск ведущего элемента проводить по столбцу или прямоугольной области матрицы.
  4. */
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <locale.h>
  10. #include <math.h>
  11.  
  12.  
  13. template <class T> void swap ( T& a, T& b )
  14. {
  15.   T c(a); a=b; b=c;
  16. }
  17.  
  18. FILE* fopen_secure(const char fname[], const char mode[]) //функция безопасного открытия
  19. {
  20.     FILE *f=fopen(fname, mode);
  21.     if(f==NULL) //если fopen возвращает нулевой указатель, то выводит ошибку
  22.     {
  23.         fclose(f);
  24.         printf("Cannot open file %s with mode %s\n", fname, mode);
  25.         exit(0);
  26.     }
  27.     return f;
  28. }
  29.  
  30. void Det (FILE *res, int n, float **M) //вычисление определителя
  31. {
  32.     float eps=0.01;
  33.     float det=1;
  34.     int c; //номер строки в которой будет макс эл
  35.  
  36.     for ( int j=0; j<n; j++ )
  37.     {
  38.         c=j;
  39.         for (int i=j+1; i<n; i++ )  //поиск макс эл в столбце
  40.         {
  41.             if ( abs(M[i][j]) > abs(M[c][j]) )
  42.                 c = i;
  43.         }
  44.  
  45.         if ( abs(M[c][j]) < eps )   //проверка на нулевой столбец
  46.         {
  47.             det=0;
  48.             break;
  49.         }
  50.        
  51.         if ( c != j)
  52.         {
  53.             swap(M[j],M[c]);    //меняем строки местами
  54.             det=-det;   //меняем знак определителя
  55.         }
  56.        
  57.  
  58.         //промежуточная проверка
  59.  
  60. /*      for (int i=0; i<n; i++)
  61.         {   for (int j=0; j<n; j++)
  62.                 printf("%f ",M[i][j]);
  63.             putchar('\n');
  64.         }
  65.         putchar('\n');
  66.     */
  67.         det*=M[j][j]; //счет определителя
  68. //      printf("%f ",det);
  69. //      putchar('\n');
  70.         for ( int i=j+1; i<n; i++ ) //диагон множитель выносим
  71.             M[j][i]/=M[j][j];
  72.  
  73.         M[j][j]=1;
  74.  
  75.         for ( int i=0; i<n ; i++)   //вычитание строк
  76.         {
  77.             if ( (i!=j) && (abs(M[i][j])>eps) ) //если эл не (диагон и нул)
  78.             {
  79.                 for ( int k=j+1; k<n; k++)  //вычитаем верхнюю строку
  80.                     M[i][k]-=M[j][k]*M[i][j];
  81.                 M[i][j]=0;  //обнуление столбца
  82.             }
  83.         }
  84.  
  85.         //промежуточная проверка
  86.         /*
  87.         for (int i=0; i<n; i++)
  88.         {   for (int j=0; j<n; j++)
  89.                 printf("%f ",M[i][j]);
  90.             putchar('\n');
  91.         }
  92.         putchar('\n');
  93.         */
  94.  
  95.  
  96.     }
  97.  
  98.  
  99. //промежуточная проверка
  100. /*  for (int i=0; i<n; i++)
  101.     {   for (int j=0; j<n; j++)
  102.             printf("%f ",M[i][j]);
  103.         putchar('\n');
  104.     }
  105. */
  106.     ceil(det);
  107.     fprintf(res,"%f ",det);
  108.     fflush(res);
  109. }
  110.  
  111. void Inv(FILE *f, int n, float **M) //обратная матрица
  112. {
  113.     int v=0;
  114.     float el, c;
  115.  
  116.     for (int i=0; i<n; i++)
  117.     {   for (int j=0; j<n; j++)
  118.             printf("%f ",M[i][j]);
  119.         putchar('\n');
  120.     }
  121.  
  122.     float **D=new float *[n]; //обратная матрица
  123.     for ( int i=0; i<n; ++i )
  124.     {
  125.         D[i]=new float[n];
  126.     }
  127.  
  128.     for (int i=0; i<n; i++)
  129.     {
  130.         for (int j=0; j<n; j++)
  131.         {
  132.             if (i==j)
  133.                 D[i][j]=1;
  134.             else D[i][j]=0;
  135.         }
  136.     }
  137.  
  138.  
  139.     for( int i=0; i<n; i++)
  140.     {
  141.         v=i;
  142.         for (int j=i+1; j<n; j++) //выбор ведущего эл
  143.         {
  144.             if ( abs(M[j][i]) > abs(M[v][i]) )
  145.                 v=j;
  146.         }
  147.  
  148.        
  149.  
  150.         if ( abs(M[v][i])<0.001)
  151.         {
  152.             n=i;
  153.             break;
  154.         }
  155.         else
  156.         {
  157.             if (v != i) //перестановка строк
  158.             {
  159.                 swap(M[i],M[v]);
  160.                 swap(D[i],D[v]);
  161.             }
  162.  
  163.             el=M[i][i]; //деление строки на диаг эл
  164.             for (int j=i; j<n; j++)
  165.                 M[i][j]/=el;
  166.             for (int j=0; j<n; j++)
  167.                 D[i][j]/=el;
  168.  
  169.             for( int k=0; k<n; k++) //вычисление
  170.             {
  171.                 if (k!= i)
  172.                 {
  173.                     c=M[k][i];
  174.                     for (int j=i; j<n; j++)
  175.                         M[k][j]-=c*M[i][j];
  176.                     for (int j=0; j<n; j++)
  177.                         D[k][j]-=c*D[i][j];
  178.                 }
  179.             }
  180.         }
  181.     }
  182.  
  183.     fprintf(f, "    Обратная матрица: \n");
  184.  
  185.     for (int i=0; i<n; i++)
  186.     {
  187.         for (int j=0; j<n; j++)
  188.             fprintf(f,"%4f ",floor(D[i][j]*1000)/1000);
  189.         fprintf(f, "\n");
  190.     }
  191.  
  192. }
  193.  
  194. int main()
  195. {
  196.     setlocale(LC_CTYPE, "rus");
  197.  
  198.     FILE *f, *res, *res_m;
  199.     int ch=0, n, pr=0, m=0;
  200.     char *str, *test, *a;
  201.  
  202.     a=new char[];
  203.    
  204.  
  205.     str=new char[];
  206.     str[0]='\0';
  207.  
  208.     test=new char[];
  209.  
  210.     f=fopen_secure("13 det_tests.txt","r");
  211.     res=fopen_secure("res.txt","w+");
  212.     res_m=fopen_secure("res_m.txt","w+");
  213.  
  214.     printf ("введите номер теста от 1 до 9:\n");
  215.     scanf ("%d", &ch);
  216.  
  217.     while ( (ch < 1) || (ch > 9) )
  218.     {
  219.         printf ("Выберите тест из предложенного диапозона (1-9), пожалуйста");
  220.         scanf ("%d", ch);
  221.     }
  222.  
  223.     int z=ch;
  224.     sprintf(test, "%s %d", "Тест", ch);
  225.  
  226.     fscanf(f,"%s %d", str,&n);
  227.     sprintf(str, "%s %d", str, n);
  228.  
  229.     while(strcmp(test,str))
  230.     {
  231.         fscanf(f,"%s %d", str,&n);
  232.         sprintf(str, "%s %d", str, n);
  233.     }
  234.  
  235.     fscanf(f,"%d", &m);
  236.  
  237.     float **M=new float *[m];
  238.     for ( int i=0; i<m; ++i )
  239.     {
  240.         M[i]=new float[m];
  241.     }
  242.  
  243.     for ( int i=0; i<m && (!feof(f)); ++i )
  244.     {
  245.         for ( int j=0; j<m && (!feof(f)); ++j )
  246.         {
  247.             fscanf(f,"%4f",&M[i][j]);
  248.         }
  249.     }
  250.  
  251.  
  252.  
  253.     //промежуточная проверка
  254.    
  255.     for (int i=0; i<m; i++)
  256.     {   for (int j=0; j<m; j++)
  257.             printf("%f ",M[i][j]);
  258.         putchar('\n');
  259.     }
  260.  
  261.     float **I=new float *[m];
  262.     for ( int i=0; i<m; ++i )
  263.     {
  264.         I[i]=new float[m];
  265.     }
  266.  
  267.     for (int i=0; i<m; i++)
  268.     {   for (int j=0; j<m; j++)
  269.             I[i][j]=M[i][j];
  270.     }
  271.    
  272.     Inv(res_m,m,I);
  273.     Det(res,m,M);
  274. }
Advertisement
Add Comment
Please, Sign In to add comment