Advertisement
999ms

lab5

May 21st, 2019
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.47 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. struct Matrix {
  5.   vector<vector<double> > A;
  6.   int n,m;
  7.   Matrix(int n, int m = -1) {
  8.     if (m < 0)
  9.       m = n;
  10.     this->n = n;
  11.     this->m = m;
  12.     A.assign(n, vector<double> (m, 0));
  13.   }
  14.  
  15.   __inline__ vector<double> & operator [] (const size_t i) {
  16.     return A[i];
  17.   }
  18.  
  19.   void set_E() {
  20.     if(n == m) {
  21.       for(int i=0; i<n; i++) {
  22.         for(int j=0; j<m; j++) {
  23.           A[i][j] = i == j;
  24.         }
  25.       }
  26.     }
  27.   }
  28.  
  29.   void randomize() {
  30.     for(int i=0; i<n; i++) {
  31.       for(int j=0; j<m; j++) {
  32.         A[i][j] = rand() * 1.0 / RAND_MAX - 0.5;
  33.       }
  34.     }
  35.   }
  36.  
  37.   Matrix transponse () {
  38.     Matrix ans(m, n);
  39.     for(int i=0; i<n; i++) {
  40.       for(int j=0; j<m; j++) {
  41.         ans[j][i] = A[i][j];
  42.       }
  43.     }
  44.     return ans;
  45.   }
  46.  
  47.   bool is_symmetric() {
  48.     if(n != m) {
  49.       return false;
  50.     }
  51.     int ans = 0;
  52.     for(int i=0; i<n; i++) {
  53.       for(int j=0; j<m; j++) {
  54.         ans += A[i][j] != A[j][i];
  55.       }
  56.     }
  57.     return ans == 0;
  58.   }
  59.  
  60.   double mistake() {
  61.     double answer = 0;
  62.     for (int i=0; i<n; i++) {
  63.       for(int j = i + 1; j < m; j++) {
  64.         answer += A[i][j] * A[i][j];
  65.       }
  66.     }
  67.     return sqrt(2 * answer);
  68.   }
  69. };
  70.  
  71. inline void mult(Matrix & A, Matrix & B, Matrix & C, int n) {
  72.     for(int i=0;i<n;i++) {
  73.         for(int j=0;j<n;j++) {
  74.             C[i][j] = 0;
  75.             for(int k=0;k<n;k++) {
  76.                 C[i][j] += A[i][k] * B[k][j];
  77.             }
  78.         }
  79.     }
  80. }
  81.  
  82. inline void transp(Matrix & A, Matrix & B, int n) {
  83.     for(int i=0;i<n;i++) {
  84.         for(int j=0;j<n;j++) {
  85.             B[i][j] = A[j][i];
  86.         }
  87.     }
  88. }
  89.  
  90. Matrix rotating_method(Matrix & A, double eps, size_t & iterations) {
  91.   const double multiplier =  sqrt(2) / 2;
  92.   iterations = 0;
  93.   int n = A.n;
  94.   Matrix RM(n),RMT(n), buff(n), ans(n);
  95.   ans.set_E();
  96.   double max_value = 0;
  97.   int x = 0, y = 0;
  98.   double angle = 0;
  99.   while(A.mistake() > eps) {
  100.     iterations++;
  101.     RM.set_E();
  102.     x = 0, y = 0;
  103.     max_value = 0;
  104.     for(int i=0; i<n; i++) {
  105.       for(int j= i + 1; j<n; j++) {
  106.         if(abs(A[i][j]) > max_value) {
  107.           max_value = abs(A[i][j]);
  108.           x = i, y = j;
  109.         }
  110.       }
  111.     }
  112.     if(A[x][x] == A[y][y]) {
  113.       RM[x][x] = RM[y][y] = RM[y][x] = multiplier;
  114.       RM[x][y] = - multiplier;
  115.     } else {
  116.       angle = 0.5 * atan(2.0 * A[x][y] / (A[x][x] - A[y][y]));
  117.       RM[x][x] = RM[y][y] = cos(angle);
  118.       RM[x][y] = -sin(angle);
  119.       RM[y][x] = sin(angle);
  120.     }
  121.         transp(RM, RMT, n);
  122.     mult(RMT, A, buff, n);
  123.     mult(buff, RM, A, n);
  124.     mult(ans, RM, buff, n);
  125.     ans = buff;
  126.   }
  127.   return ans;
  128. }
  129.  
  130. int main() {
  131.   ios_base::sync_with_stdio(false);
  132.   cin.tie(nullptr);
  133.   int n;
  134.   cin>>n;
  135.   double eps;
  136.   cin>>eps;
  137.   Matrix A(n);
  138.   A.randomize();
  139.   Matrix At = A.transponse();
  140.   Matrix buff(n);
  141.   mult(A, At, buff, n);
  142.   A = buff;
  143.   double diag = 0;
  144.   for(int i=0; i<n; i++) {
  145.     diag += A[i][i];
  146.   }
  147.   size_t iterations = 0;
  148.   Matrix ans = rotating_method(A, eps, iterations);
  149.   for(int i=0; i<n; i++) {
  150.     cout<<"Eigenvector "<<i + 1<<" : ";
  151.     for(int j=0; j<n; j++) {
  152.       cout<<ans[j][i]<<" ";
  153.     }
  154.     cout<<endl;
  155.   }
  156.   cout<<"Eigenvalues: ";
  157.   double sum_of_eigenvalues = 0;
  158.   for(int i=0; i<n; i++) {
  159.     cout<<A[i][i]<<" ";
  160.     sum_of_eigenvalues += A[i][i];
  161.   }
  162.   cout<<endl;
  163.   cout<<"Total iteration steps : "<<iterations<<endl;
  164.   cout<<"Diagonal sum : "<<diag<<endl;
  165.   cout<<"Eigenvalues sum : "<<sum_of_eigenvalues<<endl;
  166.   return 0;
  167. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement