Guest User

Untitled

a guest
Jan 23rd, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.87 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <math.h>
  4. #include <time.h>
  5. #include <omp.h>
  6. #include <string.h>
  7. #include <signal.h>
  8. #include <unistd.h>
  9. #include <stdlib.h>
  10.  
  11. double shanno(double x[], int dim) {
  12. double sum = pow(2 * x[0] - 1, 2);
  13. int i;
  14. for (i = 0; i < dim - 1; i++) {
  15. sum += ((i + 2) * pow(2 * x[i] - x[i + 1], 2));
  16. }
  17. return sum;
  18. }
  19.  
  20. double quartic(double x[], int dim) {
  21. int i;
  22. double sum = 0;
  23. for (i = 0; i < dim; i++) {
  24. sum += (double)(i + 1) * pow(x[i], 2);
  25. }
  26. return pow(sum, 2);
  27. }
  28.  
  29. void createShannoGradient(double x[], double g[], int dim, int threads) {
  30. int i;
  31. for (i = 0; i < dim; i++) {
  32. if (i == 0) {
  33. g[i] = 24 * x[0] - 8 * x[1] - 4;
  34. } else if (i < dim - 1) {
  35. g[i] = (-4 * i - 4) * x[i-1] + (10 * (i + 1) + 8) * x[i] - (i + 2) * 4 * x[i +1];
  36. } else {
  37. g[i] = (-4 * i - 4) * x[i - 1] + (i * 2 + 2) * x[i];
  38. }
  39. }
  40. }
  41.  
  42. void createQuarticGradient(double x[], double g[], int dim, int threads) {
  43. #pragma omp parallel num_threads(threads)
  44. {
  45. int i;
  46. #pragma omp for
  47. for (i = 0; i < dim; i++) {
  48. g[i] = 2 * sqrt(quartic(x, dim)) * 2 * (i + 1) * x[i];
  49. }
  50. }
  51. }
  52.  
  53. int main(int argc, char *argv[]) {
  54. if (argc > 8 || argc < 7) {
  55. printf("\Program params:\n \
  56. 1. tested function (shanno or quartic)\n \
  57. 2. dimensions\n \
  58. 3. accuracy \n \
  59. 4. gamma coefficient (0 - 1)\n \
  60. 5. number of threads taking part in calculating step size\n \
  61. 6. number of threads taking part in calculating gradient\n\n");
  62. }
  63.  
  64. int dim = atoi(argv[2]);
  65. double accuracy = atof(argv[3]);
  66. double *x = (double *) malloc(dim * sizeof(double));
  67. double *d = (double *) malloc(dim * sizeof(double));
  68. double *g = (double *) malloc(dim * sizeof(double));
  69. double *newG = (double *) malloc(dim * sizeof(double));
  70. double (*func)(double x[], int dim);
  71. void (*createGradient)(double x[], double g[], int dim, int threads);
  72. double initialValue;
  73. if (strcmp(argv[1], "quartic") == 0) {
  74. func = quartic;
  75. createGradient = createQuarticGradient;
  76. initialValue = 1;
  77. } else if (strcmp(argv[1], "shanno") == 0) {
  78. func = shanno;
  79. createGradient = createShannoGradient;
  80. initialValue = -1;
  81. }
  82. bool minimumFound = false;
  83. double alfa, betaNumerator, betaDenominator, norm, beta;
  84. double gamma = atof(argv[4]);
  85. double delta = 0.3;
  86. int iter = 1;
  87. double alfaStart, totalAlfaTime, gradientCreatingStart, totalGradientCreatingTime;
  88. int alfaThreads = atoi(argv[5]);
  89. int gradientThreads = atoi(argv[6]);
  90. int i;
  91.  
  92. // starting point - initial values
  93. for (i = 0; i < dim; i++) {
  94. x[i] = initialValue;
  95. }
  96. createGradient(x, g, dim, gradientThreads);
  97. for (i = 0; i < dim; i++) {
  98. d[i] = g[i];
  99. }
  100.  
  101. double start = omp_get_wtime();
  102.  
  103. // main loop
  104. while(!minimumFound) {
  105. double b = 0;
  106.  
  107. for (i = 0; i < dim; i++) {
  108. b += d[i] * g[i];
  109. }
  110.  
  111. double oldFunc = func(x, dim);
  112. alfaStart = omp_get_wtime();
  113. printf("============ step search nr %d ===========\n", iter );
  114. // parallel section for findding step size
  115. bool alfaSet = false;
  116. #pragma omp parallel num_threads(alfaThreads)
  117. {
  118.  
  119. int alfaIter = omp_get_thread_num();
  120. int step = omp_get_num_threads();
  121. double localAlfa = alfa;
  122. double *testX = (double *) malloc(dim * sizeof(double));
  123.  
  124. printf("--------------- searching step on thread nr %d --------------\n", omp_get_thread_num() );
  125.  
  126. while (!alfaSet) {
  127. alfaIter += step;
  128. printf("** step iteration nr %d **\n", alfaIter );
  129. localAlfa = pow(gamma, alfaIter - 1);
  130. for (i = 0; i < dim; i++) {
  131. testX[i] = x[i] + localAlfa * d[i];
  132. }
  133. if (func(testX, dim) - delta * localAlfa * b <= oldFunc) {
  134. #pragma omp critical
  135. {
  136. if (!alfaSet) {
  137. alfaSet = true;
  138. alfaIter = 0;
  139. alfa = localAlfa;
  140. }
  141. }
  142. }
  143. }
  144. free(testX);
  145. }
  146.  
  147. totalAlfaTime += omp_get_wtime() - alfaStart;
  148.  
  149. betaNumerator = 0;
  150. betaDenominator = 0;
  151. norm = 0;
  152.  
  153. for (i = 0; i < dim; i++) {
  154. x[i] += alfa * d[i];
  155. }
  156.  
  157. gradientCreatingStart = omp_get_wtime();
  158. createGradient(x, newG, dim, gradientThreads);
  159. totalGradientCreatingTime += omp_get_wtime() - gradientCreatingStart;
  160.  
  161. for (i = 0; i < dim; i++) {
  162. betaNumerator += newG[i] * (newG[i] - g[i]);
  163. betaDenominator += pow(g[i], 2);
  164. d[i] = -1 * newG[i] + beta * d[i];
  165. norm += pow(newG[i], 2);
  166. }
  167.  
  168. beta = betaNumerator / betaDenominator;
  169. norm = sqrt(norm);
  170.  
  171.  
  172. // outputting to terminal
  173. if (argv[7]) {
  174. if (iter % atoi(argv[7]) == 0 ) {
  175. printf("x0 = %.10lf\n", x[0]);
  176. }
  177. }
  178.  
  179.  
  180. // convergence
  181. if (norm < accuracy) {
  182. minimumFound = true;
  183. double time = omp_get_wtime() - start;
  184. printf("\n");
  185. printf("Solution time: %lf\n", time);
  186. printf("Step size calculation share: %.2lf\n", totalAlfaTime / time);
  187. printf("Gradient calculation share: %.2lf\n", totalGradientCreatingTime / time);
  188. printf("Minimum:");
  189. printf("Number of iterations: %d\n", iter);
  190. printf("x0 = %f\n", x[0]);
  191. printf("\n");
  192. }
  193.  
  194. for (i = 0; i < dim; i++) {
  195. x[i] = x[i];
  196. g[i] = newG[i];
  197. }
  198.  
  199. iter++;
  200. }
  201. return 0;
  202. }
Add Comment
Please, Sign In to add comment