Advertisement
Guest User

Zinovev/Pronin

a guest
Nov 18th, 2016
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.43 KB | None | 0 0
  1.  
  2. #include <cstdio>
  3. #include <iostream>
  4. #include <fstream>
  5. #include <math.h>
  6. #include <ctime>
  7. #include <chrono>
  8. #include <omp.h>
  9. #include <iostream>
  10.  
  11. using namespace std;
  12.  
  13. const double EPS = 0.001;
  14.  
  15. //Матричные функции
  16. double **CreateTestMatrix(int size);
  17. double **CopyMatrix(double** src, int size);
  18. void MatrixEcho(double** d, int size);
  19. double ToDiag_opt(double** d, int size, double eps);
  20. void ToDiag_no_opt(double** d, int size, double eps);
  21. void ToDiag_parallel(double** d, int size, double eps);
  22. double Norm(double** d, int size);
  23. void FindMax(int &j, int&k, double**d, int size);
  24. void Rotate (double**d, int size, int j, int k, double c, double s);
  25.  
  26. //скалярные функции
  27. int signum(double x)
  28. {
  29.     if (x>0)
  30.         return 1;
  31.     if (x<0)
  32.         return -1;
  33.     else
  34.         return 0;
  35. }
  36.  
  37. double abs(double x)
  38. {
  39.     if (x>=0)
  40.         return x;
  41.     else
  42.         return -x;
  43. }
  44.  
  45. int thread_nums;
  46.  
  47. int main(int argc, char **argv)
  48. {
  49.    
  50.     srand(time(0));
  51.     ofstream out;
  52.     out.open("result.txt");
  53.    
  54.     double **d;
  55.     int size=200;
  56.     out<<"name\tperf\tsize\tthreads\titers\ttime"<<endl;
  57.     for (size=400; size<=1600; size=size+200)
  58.     {
  59.         //cout<<size<<endl;
  60.         double iters=0;
  61.         d=CreateTestMatrix(size);
  62.         for (thread_nums=1; thread_nums<=48; thread_nums++)
  63.         {
  64.             if ((thread_nums==1)||(thread_nums%4 == 0))
  65.             {
  66.                 //cout<<thread_nums<<endl;
  67.            
  68.            
  69.                 double** d1=CopyMatrix(d,size);
  70.                 omp_set_num_threads(thread_nums);
  71.                 double start = omp_get_wtime();
  72.                 iters=ToDiag_opt(d1,size,EPS);
  73.                 double end = omp_get_wtime();
  74.                 double sum_time=end-start;
  75.                 double R=iters*(double)(size*size*size*6) / (sum_time);
  76.                 out<<"\t"<<R<<"\t"<<size<<"\t"<<thread_nums<<"\t"<<iters<<"\t"<<sum_time<< endl;
  77.                 for (int i=0;i<size;i++)
  78.                 {
  79.                     delete[] d1[i];
  80.                 }
  81.                 delete[] d1;
  82.                
  83.             }
  84.         }
  85.        
  86.        
  87.     }
  88.     out.close();
  89.     return 0;
  90. }
  91.  
  92. double** CreateTestMatrix(int size)
  93. {
  94.     double **d = new double*[size];
  95.     for (int k = 0; k < size; k++)
  96.     {
  97.         d[k] = new double[size];
  98.     }
  99.     int i,j;
  100.    
  101.     for (i = 0; i < size; i++){
  102.         double res[size];
  103.     //  #pragma omp paralell for private(i,size)
  104.         for (j = i; j < size; j++)
  105.             {
  106.                 //d[i][j] = Random(-100, 100);
  107.                
  108.                 res[j] = (double)(rand()) / RAND_MAX;
  109.                 res[j]=res[j]*(100 - (-100)) + (-100);
  110.                
  111.             }
  112.            
  113.             for (j = i; j < size; j++)
  114.             {
  115.                 d[i][j]=res[j];
  116.             }
  117.        
  118.     }
  119.    
  120.    
  121.    
  122.    
  123.     for (i = 0; i < size; i++)
  124.     {
  125.         for (j = 0; j <=i; j++)
  126.         {
  127.             d[i][j] = d[j][i];
  128.         }
  129.        
  130.     }
  131.    
  132.     return d;
  133. }
  134.  
  135. double **CopyMatrix (double** src, int size)
  136. {
  137.     double **d = new double*[size];
  138.     for (int k = 0; k < size; k++)
  139.     {
  140.         d[k] = new double[size];
  141.     }
  142.     int i,j;
  143.     for (i=0;i<size;i++)
  144.     {
  145.         for (j=0;j<size;j++)
  146.         {
  147.             d[i][j]=src[i][j];
  148.         }
  149.     }
  150.     return d;
  151.    
  152. }
  153.  
  154.  
  155. void MatrixEcho(double** d, int size=0)
  156. {
  157.     for (int i=0;i<size;i++)
  158.     {
  159.         for (int j=0;j<size;j++)
  160.         {
  161.             if (abs(d[i][j])>0.0001)
  162.                 cout<<d[i][j]<<" ";
  163.             else
  164.                 cout<<"0"<<" ";
  165.         }
  166.         cout<<endl;
  167.     }
  168. }
  169.  
  170.  
  171.  
  172. void ToDiag_no_opt(double **d, int size, double eps)
  173. {
  174.     double norm= Norm(d, size);
  175.     long iters=0;
  176.     while (norm>eps)
  177.     {
  178.         iters++;
  179.         int j=0,k=1;
  180.         //Нашли наибольший элемент
  181.         FindMax(j, k, d,size);
  182.         norm=sqrt(norm*norm-d[j][k]*d[j][k]);
  183.         if (abs(d[j][k])>0.0001)
  184.         {
  185.             double tau,t,c,s;
  186.             if(d[j][j]!=d[k][k])
  187.             {
  188.                 tau=(d[j][j] - d[k][k])/(2*d[j][k]);
  189.                 t=signum(tau)/(abs(tau) + sqrt(1+tau*tau));
  190.                 c=1/sqrt(1+t*t);
  191.                 s=c*t;
  192.             }
  193.             else
  194.             {
  195.                 c=1/(sqrt(2));
  196.                 s=c;
  197.             }
  198.             Rotate(d,size, j,k, c,s);
  199.            
  200.         }
  201.        
  202.        
  203.        
  204.     }
  205.     cout<<iters<<" "<<endl;
  206. }
  207.  
  208. double ToDiag_opt(double **d, int size, double eps)
  209. {
  210.     double norm= Norm(d, size);
  211.     double iters=0;
  212.     while (norm>eps)
  213.     {
  214.         for (int j=0;j<size;j++)
  215.         {
  216.             for (int k=j+1;k<size;k++)
  217.             {
  218.             iters++;
  219.        
  220.        
  221.             norm=sqrt(norm*norm-d[j][k]*d[j][k]);
  222.            
  223.            
  224.             if (abs(d[j][k])>0.0001)
  225.             {
  226.                 double tau,t,c,s;
  227.                 if(d[j][j]!=d[k][k])
  228.                 {
  229.                     tau=(d[j][j] - d[k][k])/(2*d[j][k]);
  230.                     t=signum(tau)/(abs(tau) + sqrt(1+tau*tau));
  231.                     c=1/sqrt(1+t*t);
  232.                     s=c*t;
  233.                 }
  234.                 else
  235.                 {
  236.                     c=1/(sqrt(2));
  237.                     s=c;
  238.                 }
  239.            
  240.                 Rotate(d,size, j,k, c,s);
  241.                 if (norm<eps)
  242.                 break;
  243.            
  244.             }
  245.             }
  246.             if (norm < eps)
  247.                 break;
  248.         }
  249.        
  250.        
  251.        
  252.     }
  253.     //cout<<iters<<" "<<endl;
  254.     return iters;
  255. }
  256.  
  257. void Rotate (double**d, int size, int j, int k, double c, double s)
  258. {
  259.     #pragma omp parallel
  260.     {
  261.    
  262.     #pragma omp for    
  263.     /*for (int q=0;q<size/thread_nums;q++ )
  264.     {*/
  265.         for (int i=0;i<size;i++)
  266.         {
  267.             /*int cur_index=q*thread_nums+i;
  268.             if (cur_index>=size)
  269.                 break;*/
  270.             double d1=d[j][i];
  271.             double d2=d[k][i];
  272.             double c1=c,s1=s;
  273.             int j1=j, k1=k;
  274.             d[j1][i]=d1*c1+d2*s1;
  275.             d[k1][i]=-s1*d1+c1*d2;
  276.             if ((i!=j1)&&(i!=k1))
  277.             {
  278.                 d[i][j1]=d[j1][i];
  279.                 d[i][k1]=d[k1][i];
  280.             }
  281.         //cout<<i<<" ";
  282.         }
  283.     }
  284.     //}
  285.     //cout<<endl;
  286.     double d1=d[j][j];
  287.     double d2=d[k][j];
  288.     d[j][j]=d1*c+d2*s;
  289.     d[k][j]=0;
  290.    
  291.     d1=d[j][k];
  292.     d2=d[k][k];
  293.     d[j][k]=0;
  294.     d[k][k]=-s*d1+c*d2;
  295. }
  296.  
  297. double Norm(double** d ,int size)
  298. {
  299.     double result=0;
  300.     for (int i=0;i<size;i++)
  301.     {
  302.         for (int j=i+1;j<size;j++)
  303.         {
  304.             result+=d[i][j]*d[i][j];
  305.         }
  306.     }
  307.     result=sqrt(result);
  308.     return result;
  309.    
  310. }
  311.  
  312. void FindMax(int &j, int&k, double**d, int size)
  313. {
  314.     double max=d[j][k];
  315.     for (int p=0;p<size;p++)
  316.     {
  317.         for (int q=p+1;q<size;q++)
  318.         {
  319.             if (abs(d[p][q])>max)
  320.             {
  321.                 max=abs(d[p][q]);
  322.                 j=p;
  323.                 k=q;
  324.             }
  325.         }
  326.     }
  327. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement