-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathomp.c
142 lines (117 loc) · 3.11 KB
/
omp.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <omp.h>
// f(x1, x2, x3, ..., xM) = theta0 * x0 + theta1 * x1 + theta2 * x2 + ... + thetaM * xM
#define M 10
#define N 1000
#define MAX_ITERATIONS 1000
#define ALPHA 0.3
#define ACCURACY_TORLERANCE 0.00
/// @brief The function we are trying to find coefficients for
double f(double *x, double *theta)
{
double result = 0;
for (int i = 0; i < M; i++)
{
result += theta[i] * x[i];
}
return result;
}
void init(double inputs[N][M], double outputs[N], double theta[M])
{
srand(time(NULL));
for (int i = 0; i < M; i++)
theta[i] = (double)rand() / RAND_MAX;
for (int i = 0; i < N; i++)
{
for (int k = 0; k < M; k++)
{
// i th data point, k th variable
inputs[i][k] = (double)rand() / RAND_MAX;
}
outputs[i] = f(inputs[i], theta);
}
}
void checkThetaAccuracy(double *theta, double *actualTheta)
{
int thetasAreAccurate = 1;
for (int i = 0; i < M; i++)
{
if (abs(theta[i] - actualTheta[i]) > ACCURACY_TORLERANCE)
{
thetasAreAccurate = 0;
break;
}
}
if (thetasAreAccurate)
printf("Thetas are accurate\n");
else
printf("Thetas are not accurate\n");
}
void printError(double inputs[N][M], double outputs[N], double *theta)
{
double error = 0;
for (int n = 0; n < N; n++)
{
double h = f(inputs[n], theta);
error += abs(h - outputs[n]);
}
error /= N;
printf("error: %lf\n", error);
}
void printThetaMapping(double *expectedTheta, double *calculatedTheta)
{
puts("Expected Thetas vs Computed Thetas");
for (int i = 0; i < M; i++)
{
printf("%lf -> %lf\n", expectedTheta[i], calculatedTheta[i]);
}
}
int main()
{
double inputs[N][M];
double outputs[N];
double actualTheta[M];
init(inputs, outputs, actualTheta);
// theta are the coefficients we are trying to find
double theta[M];
for (int i = 0; i < M; i++)
theta[i] = 0;
double tstart = omp_get_wtime();
for (int i = 0; i < MAX_ITERATIONS; i++)
{
double newTheta[M];
#pragma omp parallel for
for (int k = 0; k < M; k++)
{
double t = 0;
#pragma omp parallel for reduction(+ : t) schedule(guided, 100)
for (int n = 0; n < N; n++)
{
double h = 0;
for (int i = 0; i < M; i++)
{
h += inputs[n][i] * theta[i];
}
t += (h - outputs[n]) * inputs[n][k];
}
t = theta[k] - ALPHA * t / N;
newTheta[k] = t;
}
#pragma omp parallel for
for (int i = 0; i < M; i++)
theta[i] = newTheta[i];
}
double tend = omp_get_wtime();
double ttime = tend - tstart;
printf("Time taken = %lf\n", ttime);
// print mapping
printThetaMapping(actualTheta, theta);
// check if thetas are accurate
checkThetaAccuracy(theta, actualTheta);
// check error
printError(inputs, outputs, theta);
return 0;
}