Year 3 parallel coursework

single.c 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <time.h>
  6. #include <string.h>
  7. #include <pthread.h>
  8. // this code is left uncommented as it is self explanatory or the same as the
  9. // parallel version
  10. bool allow_print;
  11. void printSquare(double **array, unsigned long dimension) {
  12. unsigned long i, j;
  13. for (i = 0; i < dimension; i++) {
  14. for (j = 0; j < dimension; j++) printf("%f ", array[i][j]);
  15. printf("\n");
  16. }
  17. }
  18. long double time_seconds(struct timespec begin, struct timespec end) {
  19. long long sec_diff = end.tv_sec - begin.tv_sec;
  20. long long nsec_diff = end.tv_nsec - begin.tv_nsec;
  21. long long as_ns = sec_diff * 1000000000L + nsec_diff;
  22. return (long double) as_ns / 1000000000.0;
  23. }
  24. unsigned long solveArray(double **array, unsigned long dimension,
  25. double precision) {
  26. unsigned long i, j, k;
  27. bool solved;
  28. struct timespec begin, end;
  29. k = 0;
  30. clock_gettime(CLOCK_MONOTONIC, &begin);
  31. while (1) {
  32. k++;
  33. solved = true;
  34. for (i = 1; i < dimension - 1; i++) {
  35. for (j = 1; j < dimension - 1; j++) {
  36. double previous = array[i][j];
  37. double avg = (array[i][j - 1] + array[i][j + 1] + array[i - 1][j] +
  38. array[i + 1][j]) / 4.0;
  39. array[i][j] = avg;
  40. if (solved == true && fabs(avg - previous) > precision) {
  41. solved = false;
  42. }
  43. }
  44. }
  45. if (solved == true) {
  46. clock_gettime(CLOCK_MONOTONIC, &end);
  47. if (allow_print) printf("time taken: %Lf\n", time_seconds(begin, end));
  48. return k;
  49. }
  50. }
  51. }
  52. double **constructBigArray(double top, double bottom, double left,
  53. double right, long unsigned int n) {
  54. long unsigned int i, j, k;
  55. double **arr = (double **) malloc(n * sizeof(double *));
  56. for (k = 0; k < n; k++) {
  57. arr[k] = (double *) malloc(n * sizeof(double));
  58. }
  59. for (i = 0; i < n; i++) {
  60. for (j = 0; j < n; j++) {
  61. if (i == 0) {
  62. if (j == 0 || j == n - 1) arr[i][j] = 0;
  63. else arr[i][j] = top;
  64. } else if (i == n - 1) {
  65. if (j == 0 || j == n - 1) arr[i][j] = 0;
  66. else arr[i][j] = bottom;
  67. } else if (j == 0) {
  68. arr[i][j] = left;
  69. } else if (j == n - 1) {
  70. arr[i][j] = right;
  71. } else {
  72. arr[i][j] = 0;
  73. }
  74. }
  75. }
  76. return arr;
  77. }
  78. typedef struct arg_data {
  79. double precision;
  80. unsigned long dimension;
  81. double top_start;
  82. double bottom_start;
  83. double left_start;
  84. double right_start;
  85. } ARG_DATA_T;
  86. int argsContain(const char *val, char **arr, int size) {
  87. int i;
  88. for (i = 0; i < size; i++) {
  89. if (strcmp(arr[i], val) == 0)
  90. return i;
  91. }
  92. return -1;
  93. }
  94. ARG_DATA_T *parseArgs(int argc, char **argv) {
  95. int tmp;
  96. ARG_DATA_T *args = (ARG_DATA_T *) malloc(sizeof(ARG_DATA_T));
  97. allow_print = true;
  98. if ((tmp = argsContain("-p", argv, argc)) >= 0 ||
  99. (tmp = argsContain("--precision", argv, argc)) >= 0) {
  100. args->precision = strtod(argv[tmp + 1], NULL);
  101. } else {
  102. args->precision = 0.00001;
  103. }
  104. if ((tmp = argsContain("-d", argv, argc)) >= 0
  105. || (tmp = argsContain("--dimension", argv, argc)) >= 0) {
  106. args->dimension = (unsigned long) strtol(argv[tmp + 1], NULL, 10);
  107. } else {
  108. args->dimension = 10;
  109. }
  110. if ((tmp = argsContain("-t", argv, argc)) >= 0
  111. || (tmp = argsContain("--top", argv, argc)) >= 0) {
  112. args->top_start = strtod(argv[tmp + 1], NULL);
  113. } else {
  114. args->top_start = 1;
  115. }
  116. if ((tmp = argsContain("-l", argv, argc)) >= 0
  117. || (tmp = argsContain("--left", argv, argc)) >= 0) {
  118. args->left_start = strtod(argv[tmp + 1], NULL);
  119. } else {
  120. args->left_start = 2;
  121. }
  122. if ((tmp = argsContain("-r", argv, argc)) >= 0
  123. || (tmp = argsContain("--right", argv, argc)) >= 0) {
  124. args->right_start = strtod(argv[tmp + 1], NULL);
  125. } else {
  126. args->right_start = 4;
  127. }
  128. if ((tmp = argsContain("-b", argv, argc)) >= 0
  129. || (tmp = argsContain("--bottom", argv, argc)) >= 0) {
  130. args->bottom_start = strtod(argv[tmp + 1], NULL);
  131. } else {
  132. args->bottom_start = 3;
  133. }
  134. if ((tmp = argsContain("-q", argv, argc)) > 0 ||
  135. (tmp = argsContain("--quiet", argv, argc)) >= 0) {
  136. allow_print = false;
  137. }
  138. if (argsContain("-h", argv, argc) >= 0
  139. || argsContain("--help", argv, argc) >= 0) {
  140. printf("Usage: %s [-p N] [-d N] [-t N] [-l N] [-r N] [-b N]\n",
  141. argv[0]);
  142. printf("Constructs a 2D array of doubles, with values from arguments "
  143. "of size dimension^2 and performs relaxation method"
  144. " to given precision.\n");
  145. printf("Options:\n");
  146. printf("-p/--precision: A double value to specify precision. "
  147. "Default: 0.0001\n");
  148. printf("-d/--dimension: A long value to specify width and height of "
  149. "grid. Default: 10\n");
  150. printf("-t/--top: A double indicating the values along the top of the "
  151. "array. Default: 1.0\n");
  152. printf("-l/--left: A double indicating the values along the left side"
  153. " of the array. Default: 2.0\n");
  154. printf("-b/--bottom: A double indicating the values along the bottom "
  155. "of the array. Default: 3.0\n");
  156. printf("-r/--right: A double indicating the values along the right "
  157. "side of the array. Default: 4.0\n");
  158. printf("-q/--quiet: Disables all printing except the result.\n");
  159. exit(0);
  160. }
  161. return args;
  162. }
  163. int main(int argc, char **argv) {
  164. unsigned long iter;
  165. ARG_DATA_T *args;
  166. args = parseArgs(argc, argv);
  167. double **array = constructBigArray(args->top_start, args->bottom_start,
  168. args->left_start, args->right_start, args->dimension);
  169. iter = solveArray(array, args->dimension, args->precision);
  170. if (allow_print) printf("completed with iters: %lu\n", iter);
  171. printSquare(array, args->dimension);
  172. }