#include #include #include #include #include #include #include #include #include #include int A = (float)(7 * 6 * 8); // -------------------------- // Functions // -------------------------- bool debug = false; // Function for get out debug information if debug mode enabled void debugPrint(const char *format, ...) { if (debug) { va_list args; va_start(args, format); vprintf(format, args); va_end(args); } } // Random float from min to max float randFloat(int min, int max, unsigned int *seed) { float scale = rand_r(seed) / (float) RAND_MAX; return min + scale * (max - min); } void printNum(double *num) { if (*num > 10000) { debugPrint("%.3e ", *num); // 0.000 } else { debugPrint("%.3f ", *num); // 0.000e+0 } } void outM(double *M1_ptr, int M1_N, double *M2_ptr, int M2_N) { debugPrint("M1:\n"); for (int i = 0; i < M1_N; i++) { printNum(&M1_ptr[i]); } debugPrint("\nM2:\n"); for (int i = 0; i < M2_N; i++) { printNum(&M2_ptr[i]); } } // ---------- END------------ // -------------------------- // STEP 1 - Generation // -------------------------- unsigned int seed; void gen_M1(double *M_ptr, int N) { float min = 1.0f; float max = A; for (int i = 0; i < N; i++) { M_ptr[i] = randFloat(min, max, &seed); } } void gen_M2(double *M_ptr, int N) { float min = A; float max = A*10; for (int i = 0; i < N; i++) { M_ptr[i] = randFloat(min, max, &seed); } } // ---------- END------------ // -------------------------- // STEP 2 - Map // -------------------------- void applyMapM1(double *M_ptr, int N) { for (int i = 0; i < N; i++) { M_ptr[i] = cosh(M_ptr[i]); } } void applyMapM2(double *M_ptr, int N) { bool first = true; double M[N]; for (int i = 0; i < N; i++) { if (first) { M[i] = fabs(sin(M_ptr[i])); } else { M[i] = fabs(sin(M_ptr[i] + M[i-1])); } } // Write changes for (int i = 0; i < N; i++) { M_ptr[i] = M[i]; } } // ---------- END------------ // -------------------------- // STEP 3 - Merge // -------------------------- void applyMerge(double *M1_ptr, double *M2_ptr, int M2_N) { for (int i = 0; i < M2_N; i++) { M2_ptr[i] = M1_ptr[i]*M2_ptr[i]; } } // ---------- END------------ // -------------------------- // STEP 4 - Sort // -------------------------- void selectionSort(double *M_ptr, int N) { double max = 0; int max_it = 0; int it = N; for (int n = 0; n < N; n++) { max = NAN; for (int i = 0; i < it; i++) { if (isnan(max) || M_ptr[i] > max) { max = M_ptr[i]; max_it = i; } } M_ptr[max_it] = M_ptr[it - 1]; M_ptr[it - 1] = max; it--; } } // ---------- END------------ // -------------------------- // STEP 5 - Reduce // -------------------------- void applyReduce(double *M_ptr, int N) { float sum = 0; int min = INT_MIN; // Find min non-zero for (int i = 0; i < N; i++) { if (min == INT_MIN || trunc(M_ptr[i]) < min) { if (trunc(M_ptr[i]) != 0) { min = (int)trunc(M_ptr[i]); } } } // Sum of all sin(i) where i%min == 0 for (int i = 0; i < N; i++) { if ((int)trunc(M_ptr[i]) % min == 0) { sum += sin( (int)trunc(M_ptr[i]) ); debugPrint("sum: %f\n", sum); } } } // ---------- END------------ int main(int argc, char* argv[]) { if (argc < 2) { debugPrint("Usage: %s [debug]\n", argv[0]); exit(1); } if (argc >= 3 && strcmp(argv[2], "debug") == 0) { debug = true; } // Number of numbers int N; N = atoi(argv[1]); // Set custom seed, because need to check different progs //seed = time(0); seed = 10; // First array double* M1_ptr; M1_ptr = (double*)malloc(N * sizeof(double)); int M1_N = N; // Second array double* M2_ptr; M2_ptr = (double*)malloc(N/2 * sizeof(double)); int M2_N = N/2; // Remember start time struct timeval T1, T2; long delta_ms; gettimeofday(&T1, NULL); // STEP 1 - generate gen_M1(M1_ptr, M1_N); gen_M2(M2_ptr, M2_N); debugPrint("---------- Generated arrays ----------\n"); outM(M1_ptr, M1_N, M2_ptr, M2_N); debugPrint("\n---------------- END -----------------\n"); // STEP 2 - map applyMapM1(M1_ptr, M1_N); applyMapM2(M2_ptr, M2_N); debugPrint("\n--------------- STEP 2 ---------------\n"); outM(M1_ptr, M1_N, M2_ptr, M2_N); debugPrint("\n---------------- END -----------------\n"); // STEP 3 - merge applyMerge(M1_ptr, M2_ptr, M2_N); debugPrint("\n--------------- STEP 3 ---------------\n"); outM(M1_ptr, M1_N, M2_ptr, M2_N); debugPrint("\n---------------- END -----------------\n"); // STEP 4 - sort selectionSort(M1_ptr, M1_N); selectionSort(M2_ptr, M2_N); debugPrint("\n--------------- STEP 4 ---------------\n"); outM(M1_ptr, M1_N, M2_ptr, M2_N); debugPrint("\n---------------- END -----------------\n"); // STEP 5 - reduce debugPrint("\n--------------- STEP 5 ---------------\n"); applyReduce(M2_ptr, M2_N); debugPrint("\n---------------- END -----------------\n"); // Remember time of end and get out it gettimeofday(&T2, NULL); delta_ms = (T2.tv_sec - T1.tv_sec) * 1000 + (T2.tv_usec - T1.tv_usec) / 1000; printf("\nN=%d. Milliseconds passed: %ld\n", N, delta_ms); free(M1_ptr); free(M2_ptr); return 0; }