Advertisement
osipyonok

4MO Lab2

Oct 1st, 2016
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.71 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. #define INF 1000010000
  4. #define nl '\n'
  5. #define pb push_back
  6. #define ppb pop_back
  7. #define mp make_pair
  8. #define fi first
  9. #define se second
  10. #define pii pair<int,int>
  11. #define pdd pair<double,double>
  12. #define all(c) (c).begin(), (c).end()
  13. #define SORT(c) sort(all(c))
  14. #define sz(c) (c).size()
  15. #define rep(i,n) for( int i = 0; i < n; ++i )
  16. #define repi(i,n) for( int i = 1 ; i <= n; ++i )
  17. #define repn(i,n) for( int i = n - 1 ; i >= 0 ; --i )
  18. #define repf(j,i,n) for( int j = i ; j < n ; ++j )
  19. #define die(s) {std::cout << s << nl;}
  20. #define dier(s) {std::cout << s; return 0;}
  21. #define vi vector<int>
  22. typedef long long ll;
  23.  
  24. using namespace std;
  25. #define eps 1e-3
  26. int n;
  27. vector<double> X_;
  28.  
  29.  
  30. inline double EuclideanNorm(vector<double> v){
  31.     double sum = 0;
  32.     rep(i , sz(v))sum += v[i] * v[i];
  33.     return sqrt(sum);
  34. }
  35.  
  36. inline vector<double> Substract(vector<double> & a , vector<double> & b){
  37.     vector<double> res(n , 0.);
  38.     rep(i , n)res[i] = a[i] - b[i];
  39.     return res;
  40. }
  41.  
  42. inline double Residual(vector<vector<double> > & A , vector<double> & X , vector<double> & B){
  43.     vector<double> res(n , 0.);
  44.     rep(i , n){
  45.         double sum = 0;
  46.         rep(j , n){
  47.             sum += A[i][j] * X[j];
  48.         }
  49.         res[i] = sum - B[i];
  50.     }
  51.     return EuclideanNorm(res);
  52. }
  53.  
  54. inline double AnsDiff(vector<double> & X){
  55.     return EuclideanNorm(Substract(X , X_));
  56. }
  57.  
  58. inline void DiagonallyDomination(vector<vector<double> > & A){
  59.     rep(i , n){
  60.         int sgn = A[i][i] < 0 ? -1 : 1;
  61.         double sum = -abs(A[i][i]);
  62.         rep(j , n){
  63.             sum += abs(A[i][j]);
  64.         }
  65.         if(sum > abs(A[i][i])){
  66.             A[i][i] = sgn * (sum + (rand() % 5));
  67.         }
  68.     }
  69. }
  70.  
  71. inline void solve1(vector<vector<double> > A , vector<double> B){//Gauss
  72.     vector<double> X(n);
  73.     rep(j , n){
  74.         repf(i , j + 1 , n){
  75.         /*  int mx = j;
  76.             rep(k , n)if(abs(A[k][j]) > abs(A[mx][j]))mx = k;
  77.             swap(A[i] , A[mx]);
  78.             swap(B[i] , B[mx]);*/
  79.             double k = A[i][j] / A[j][j];
  80.             rep(r , n){
  81.                 A[i][r] -= k * A[j][r];
  82.             }
  83.             B[i] -= k * B[j];
  84.         }
  85.     }
  86.    
  87.     repn(i , n){
  88.         double res = B[i];
  89.         repf(j , i + 1 , n){
  90.             res -= A[i][j] * X[j];
  91.         }
  92.         res /= A[i][i];
  93.         X[i] = res;
  94.         if(X[i] == -0.)X[i] = 0;
  95.     }
  96.     rep(i , n)cout << X[i] << " ";
  97.     cout << nl;
  98. }
  99.  
  100. inline void solve2(vector<vector<double> > A , vector<double> B){//Jacobi
  101.     vector<double> X = B;
  102.     vector<double> T = B;
  103.     int cnt = 0;
  104.     do{
  105.         ++cnt;
  106.         X = T;
  107.         rep(i , n){
  108.             double sum = 0;
  109.             rep(j , n){
  110.                 if(i == j)continue;
  111.                 sum += A[i][j] * X[j];
  112.             }
  113.             T[i] = (B[i] - sum) / A[i][i];
  114.         }
  115.         cout << "Step " << cnt << ", residual is " << Residual(A , T , B) << ", diff " << AnsDiff(T) << nl;
  116.     }
  117.     while(EuclideanNorm(Substract(X , T)) > eps);
  118.     rep(i , n)cout << T[i] << " ";
  119.     cout << nl;
  120. }
  121.  
  122. inline void solve3(vector<vector<double> > A , vector<double> B){//Seidel
  123.     vector<double> X = B;
  124.     vector<double> T = B;
  125.     int cnt = 0;
  126.     do{
  127.         ++cnt;
  128.         X = T;
  129.         rep(i , n){
  130.             double sum = 0;
  131.             rep(j , n){
  132.                 if(i == j)continue;
  133.                 sum += A[i][j] * T[j];
  134.             }
  135.             T[i] = (B[i] - sum) / A[i][i];
  136.         }
  137.         cout << "Step " << cnt << ", residual is " << Residual(A , T , B) << ", diff " << AnsDiff(T) << nl;
  138.     }while(EuclideanNorm(Substract(X , T)) > eps);
  139.     rep(i , n)cout << T[i] << " ";
  140.     cout << nl;
  141. }
  142.  
  143. int main() {
  144.     ios_base::sync_with_stdio(false);
  145.     cin.tie(NULL);
  146.     cout.precision(5);
  147.     cout.setf(ios::fixed);
  148.     cin >> n;
  149.     srand(std::chrono::duration_cast<std::chrono::nanoseconds>((std::chrono::high_resolution_clock::now().time_since_epoch())).count() + time(0));
  150.     vector<vector<double> > A(n , vector<double>(n));
  151.     rep(i , n){
  152.         rep(j , n){
  153.             A[i][j] = ((rand() % 500) / 100.) - 2.5;
  154.          // A[i][j] = 1. / (i + j + 1);
  155.         }
  156.     }
  157.     DiagonallyDomination(A);
  158.     rep(i , n){
  159.         rep(j , n){
  160.             cout << setw(6) << A[i][j] << " ";
  161.         }
  162.         cout << nl;
  163.     }
  164.     vector<double> b(n);
  165.     rep(i , n){
  166.         X_.pb(0);
  167.         cin >> X_[i];
  168.     }
  169.     rep(i , n){
  170.         double cur = 0;
  171.         rep(j , n){
  172.             cur += X_[j] * A[i][j];
  173.         }
  174.         b[i] = cur;
  175.     }
  176.     cout << "B: ";
  177.     rep(i , n)cout << b[i] << " ";
  178.     cout << nl;
  179.     solve1(A , b);
  180.     solve2(A , b);
  181.     solve3(A , b);
  182.     return 0;
  183. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement