Guest User

corr.c (for: http://stackoverflow.com/q/26332811/732016)

a guest
Oct 12th, 2014
400
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.24 KB | None | 0 0
  1. /*
  2.  * corr.c
  3.  * Computes Pearson's correlation coefficient for random data
  4.  * William Chargin
  5.  * 12 October 2014
  6.  */
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <math.h>
  10. #include <time.h>
  11. #include <pthread.h>
  12. #include <sys/sysinfo.h>
  13.  
  14. typedef struct parcorrinfo {
  15.     size_t n;
  16.     size_t trials;
  17. } parcorrinfo_t;
  18.  
  19. static inline double randt()
  20. {
  21.     return 1;
  22.     static double max = (double) RAND_MAX;
  23.     return rand() / max;
  24. }
  25.  
  26. static double corr(const size_t n, const double *xs, const double *ys)
  27. {
  28.     double x, y, x2, y2, xy;
  29.     x = y = x2 = y2 = xy = 0;
  30.  
  31.     size_t i;
  32.     for (i = 0; i < n; i++)
  33.     {
  34.         x += xs[i];
  35.         y += ys[i];
  36.         x2 += xs[i]*xs[i];
  37.         y2 += ys[i]*ys[i];
  38.         xy += xs[i]*ys[i];
  39.     }
  40.  
  41.     return (xy - (x*y)/n) / sqrt((x2 - x*x/n) * (y2 - y*y/n));
  42. }
  43.  
  44. static double test(size_t n, size_t trials)
  45. {
  46.     double sum = 0;
  47.     size_t trial;
  48.  
  49.     double *xs = malloc(sizeof(double) * n);
  50.     double *ys = malloc(sizeof(double) * n);
  51.  
  52.     if (!xs || !ys)
  53.     {
  54.         exit(2);
  55.         fprintf(stderr, "%s", "Failed to allocate memory");
  56.         return -1;
  57.     }
  58.  
  59.     for (trial = 0; trial < trials; trial++)
  60.     {
  61.         // Set values
  62.         size_t i;
  63.         for (i = 0; i < n; i++)
  64.         {
  65.             xs[i] = randt();
  66.             ys[i] = randt();
  67.         }
  68.  
  69.         // Compute correlation
  70.         sum += fabs(corr(n, xs, ys));
  71.     }
  72.  
  73.     free(xs);
  74.     free(ys);
  75.  
  76.     return sum / trials;
  77. }
  78.  
  79. static void *corrhandler(void *arg)
  80. {
  81.     parcorrinfo_t *info = (parcorrinfo_t *) arg;
  82.     double *result = malloc(sizeof(double));
  83.     *result = test(info->n, info->trials);
  84.     free(info);
  85.     return (void *) result;
  86. }
  87.  
  88. static double partest(size_t n, size_t trials, size_t num_threads)
  89. {
  90.     pthread_t *threads = calloc(num_threads, sizeof(pthread_t));
  91.     size_t each_trials = trials / num_threads; /* assume trials >> num_threads */
  92.  
  93.     double total = 0;
  94.  
  95.     size_t i;
  96.  
  97.     if (!threads)
  98.     {
  99.         fprintf(stderr, "%s", "Failed to allocate memory");
  100.         exit(2);
  101.         return -1;
  102.     }
  103.  
  104.     for (i = 0; i < num_threads; i++)
  105.     {
  106.         parcorrinfo_t *info = malloc(sizeof(parcorrinfo_t));
  107.         info->n = n;
  108.         info->trials = each_trials;
  109.  
  110.         pthread_create(&threads[i], NULL, corrhandler, (void *) info);
  111.     }
  112.  
  113.     for (i = 0; i < num_threads; i++)
  114.     {
  115.         double *result;
  116.         pthread_join(threads[i], (void **) &result);
  117.         total += (*result);
  118.         free(result);
  119.     }
  120.  
  121.     free(threads);
  122.  
  123.     return total / num_threads;
  124. }
  125.  
  126. int main(int argc, char **argv)
  127. {
  128.     size_t min, max;
  129.     size_t trials;
  130.     size_t i;
  131.     size_t threads;
  132.  
  133.     if (argc < 4)
  134.     {
  135.         fprintf(stderr, "usage: %s min max trials [threads]\n", argc ? argv[0] : "corr");
  136.         return 1;
  137.     }
  138.  
  139.     sscanf(argv[1], "%zu", &min);
  140.     sscanf(argv[2], "%zu", &max);
  141.     sscanf(argv[3], "%zu", &trials);
  142.     if (argc > 4)
  143.     {
  144.         sscanf(argv[4], "%zu", &threads);
  145.     }
  146.     else
  147.     {
  148.         threads = (size_t) get_nprocs();
  149.     }
  150.  
  151.     srand(time(0));
  152.  
  153.     for (i = min; i <= max; i++)
  154.     {
  155.         printf("%zu\t%lf\n", i, partest(i, trials, threads));
  156.     }
  157.  
  158.     return 0;
  159. }
Add Comment
Please, Sign In to add comment