242 lines
5.1 KiB
C
242 lines
5.1 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/time.h>
|
|
#include <time.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <stdbool.h>
|
|
#include <limits.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
|
|
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 <N> [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;
|
|
}
|
|
|