-
Notifications
You must be signed in to change notification settings - Fork 0
/
serial.c
132 lines (113 loc) · 2.93 KB
/
serial.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
// this is the serial implementation of Gradient Descent algorithm
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.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.001
/// @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++)
{
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 = 0;
for (int i = 0; i < M; i++)
{
h += inputs[n][i] * theta[i];
}
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;
for (int i = 0; i < MAX_ITERATIONS; i++)
{
double newTheta[M];
for (int k = 0; k < M; k++)
{
double t = 0;
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;
}
for (int i = 0; i < M; i++)
theta[i] = newTheta[i];
}
// print mapping
printThetaMapping(actualTheta, theta);
// check if thetas are accurate
checkThetaAccuracy(theta, actualTheta);
// check error
printError(inputs, outputs, theta);
return 0;
}