Dormouses

super_prac

Nov 18th, 2016
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.37 KB | None | 0 0
  1. #define MAX_DATA_POINTS 6000
  2. #define MAX_CLUSTER 101
  3. #define MAX_DATA_DIMENSION 5
  4. #include <mpi.h>
  5. #include <math.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <time.h>
  10. #include <omp.h>
  11.  
  12. int num_data_points;
  13. int num_clusters;
  14. int num_dimensions;
  15. double low_high[MAX_DATA_DIMENSION][2];
  16. double degree_of_memb[MAX_DATA_POINTS][MAX_CLUSTER];
  17. double tmp_degree_of_memb[MAX_DATA_POINTS][MAX_CLUSTER];
  18. double epsilon;
  19. double fuzziness;
  20. double data_point[MAX_DATA_POINTS][MAX_DATA_DIMENSION];
  21. double cluster_centre[MAX_CLUSTER][MAX_DATA_DIMENSION];
  22.  
  23. int real_number_data_points;
  24.  
  25. int
  26. init(char *fname,int start) {
  27.     int i, j, r, rval;
  28.     FILE *f;
  29.     double s;
  30.     if ((f = fopen(fname, "r")) == NULL) {
  31.         printf("Failed to open input file.");
  32.         return -1;
  33.     }
  34.     fscanf(f, "%d %d %d", &num_data_points, &num_clusters, &num_dimensions);
  35.     num_data_points=real_number_data_points;//добавлено
  36.     if (num_clusters > MAX_CLUSTER) {
  37.         printf("Number of clusters should be < %d\n", MAX_CLUSTER);
  38.         goto failure;
  39.     }
  40.     if (num_data_points > MAX_DATA_POINTS) {
  41.         printf("Number of data points should be < %d\n", MAX_DATA_POINTS);
  42.         goto failure;
  43.     }
  44.     if (num_dimensions > MAX_DATA_DIMENSION) {
  45.         printf("Number of dimensions should be >= 1.0 and < %d\n",
  46.                MAX_DATA_DIMENSION);
  47.         goto failure;
  48.     }
  49.     fscanf(f, "%lf", &fuzziness);
  50.     if (fuzziness <= 1.0) {
  51.         printf("Fuzzyness coefficient should be > 1.0\n");
  52.         goto failure;
  53.     }
  54.     fscanf(f, "%lf", &epsilon);
  55.     if (epsilon <= 0.0 || epsilon > 1.0) {
  56.         printf("Termination criterion should be > 0.0 and <= 1.0\n");
  57.         goto failure;
  58.     }
  59.     for (i = 0; i < num_data_points; i++) {
  60.         for (j = 0; j < num_dimensions; j++) {
  61.             fscanf(f, "%lf", &data_point[i][j]);
  62.             if (data_point[i][j] < low_high[j][0])
  63.                 low_high[j][0] = data_point[i][j];
  64.             if (data_point[i][j] > low_high[j][1])
  65.                 low_high[j][1] = data_point[i][j];
  66.         }
  67.     }
  68.     #pragma omp parallel for shared(degree_of_memb) private(i, j, rval)
  69.     for (i = 0; i < num_data_points; i++) {
  70.         s = 0.0;
  71.         r = 100;
  72.         #pragma omp parallel for reduction(+:s), reduction(-:r)
  73.         for (j = 1; j < num_clusters; j++) {
  74.             rval = rand() % (r + 1);
  75.             r -= rval;
  76.             degree_of_memb[i][j] = rval / 100.0;
  77.             s += degree_of_memb[i][j];
  78.         }
  79.         degree_of_memb[i][0] = 1.0 - s;
  80.     }
  81.     fclose(f);
  82.     return 0;
  83. failure:
  84.     fclose(f);
  85.     exit(1);
  86. }
  87.  
  88. int
  89. calculate_centre_vectors(int start) {
  90.     int i, j, k;
  91.     double numerator, denominator;
  92.     double t[MAX_DATA_POINTS][MAX_CLUSTER];
  93.  //   i=0;
  94.     #pragma omp parallel private(i, j)
  95.     {
  96.       #pragma omp for collapse (2)
  97.     for (i = 0; i < num_data_points; i++) {
  98.         for (j = 0; j < num_clusters; j++) {
  99.             t[i][j] = pow(degree_of_memb[i][j], fuzziness);
  100.         }
  101.     }
  102.     }
  103.     #pragma omp parallel shared(t, data_point) private(k, j)
  104.     {
  105.     #pragma omp for collapse (2)
  106.     for (j = 0; j < num_clusters; j++) {
  107.         for (k = 0; k < num_dimensions; k++) {
  108.             numerator = 0.0;
  109.             denominator = 0.0;
  110.           #pragma omp parallel for reduction(+:numerator, denominator)
  111.             for (i = 0; i < num_data_points; i++) {
  112.                 numerator += t[i][j] * data_point[i][k];
  113.                 denominator += t[i][j];
  114.             }
  115.         if(denominator == 0)
  116.             continue;
  117.             cluster_centre[j][k] = numerator / denominator;
  118.         }
  119.     }
  120.     }
  121.     return 0;
  122. }
  123.  
  124. double
  125. get_norm(int i, int j, int start) {
  126.     int k;
  127.     double sum = 0.0;
  128.     #pragma omp parallel for reduction(+:sum) private(k)
  129.     for (k = 0; k < num_dimensions; k++) {
  130.         sum += pow(data_point[i][k] - cluster_centre[j][k], 2);
  131.     }
  132.    
  133.     return sqrt(sum);
  134. }
  135.  
  136. double
  137. get_new_value(int i, int j,int  start) {
  138.     int k;
  139.     double t, p, sum;
  140.     sum = 0.0;
  141.     p = 2 / (fuzziness - 1);
  142.    #pragma omp parallel for reduction(+:sum) private(k, t)
  143.     for (k = 0; k < num_clusters; k++) {
  144.     if(get_norm(i,k, start)== 0)
  145.         continue;
  146.         t = get_norm(i, j, start) / get_norm(i, k, start);
  147.         t = pow(t, p);
  148.         sum += t;
  149.     }
  150.     if(sum == 0)
  151.     {
  152.      printf("masha");
  153.      sum = 1;
  154.     }
  155.     return 1.0 / sum;
  156. }
  157.  
  158. double
  159. update_degree_of_membership(int start) {
  160.     int i, j;
  161.     double new_uij;
  162.     double max_diff = 0.0, diff;
  163.    
  164.     #pragma omp parallel private(j, new_uij,diff)
  165.     {
  166.          #pragma omp for collapse (2)
  167.     for (j = 0; j < num_clusters; j++) {
  168.         for (i = 0; i < num_data_points; i++) {
  169.             new_uij = get_new_value(i, j, start);
  170.             diff = new_uij - degree_of_memb[i][j];
  171.             if (diff > max_diff)
  172.                 max_diff = diff;
  173.             degree_of_memb[i][j] = new_uij;
  174.         }
  175.     }
  176.     }
  177.     return max_diff;
  178. }
  179.  
  180. int
  181. fcm(char *fname, int start) {
  182.     double max_diff;
  183.     int i=0;
  184.     int ii, jj;
  185.     init(fname, start);
  186.    
  187.     do {
  188.         i++;
  189.         calculate_centre_vectors(start);
  190.         MPI_Allreduce(&degree_of_memb, &tmp_degree_of_memb, MAX_DATA_POINTS*MAX_CLUSTER, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
  191.         for (ii=0; i<MAX_DATA_POINTS; i++)
  192.           for (jj=0; jj<MAX_CLUSTER; jj++)
  193.             degree_of_memb[ii][jj]=tmp_degree_of_memb[ii][jj];
  194.         max_diff = update_degree_of_membership(start);
  195.     } while (max_diff > epsilon);
  196.     return i;
  197. }
  198.  
  199. int
  200. main(int argc, char **argv) {
  201.     int num_it, i;
  202.     int ProcNum, rank;
  203.     MPI_Init(&argc,&argv);
  204.     MPI_Comm_size(MPI_COMM_WORLD,&ProcNum);
  205.     MPI_Comm_rank(MPI_COMM_WORLD,&rank);
  206.     printf("%d", rank);
  207.     for (i=1; i<=8; i++)
  208.     {
  209.         omp_set_dynamic(0);
  210.         omp_set_num_threads(i);
  211.         for (real_number_data_points=101; real_number_data_points<MAX_DATA_POINTS; real_number_data_points++)
  212.         {
  213.         //printf("guffifuf\n");
  214.             clock_t before = clock();
  215.             num_it=fcm("file", rank*750);
  216.             clock_t after = clock();
  217.     if ( abs(after-before) <1)
  218.     printf("-1 ");
  219.             printf("%d %d  %d ", i, real_number_data_points, 100*100*real_number_data_points*4*num_it/(after-before));
  220.         fflush (stdout);
  221.         }
  222.         printf("\n");
  223.     }
  224.    MPI_Finalize();
  225.     return 0;
  226. }
Add Comment
Please, Sign In to add comment