-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmeth.c
133 lines (115 loc) · 2.79 KB
/
meth.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
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "structs.h"
#include "meth.h"
// multiply two matrices
Matrix * dot(Matrix * a, Matrix * b) {
if (a->cols == b->rows){
Matrix * c = initMatrix(a->rows, b->cols);
for (int i = 0; i < a->rows; i++){
for (int j = 0; j < b->cols; j++){
c->at[i][j] = 0;
for (int n = 0; n < a->cols; n++){
c->at[i][j] += a->at[i][n] * b->at[n][j];
}
}
}
return c;
} else {
perror("Cannot multiply (meth.c:dot)"), exit(1);
}
}
// multiply matrices element-wise
Matrix * hadamard(Matrix * a, Matrix * b) {
// check same dimensions
if (a->rows == b->rows && a->cols == b->cols) {
Matrix * c = initMatrix(a->rows, a->cols);
// multiply elementwise
for (int i = 0; i < c->rows; i++) {
for (int j = 0; j < c->cols; j++) {
c->at[i][j] = a->at[i][j] * b->at[i][j];
}
}
return c;
} else {
perror("Cannot hadamard matrices (meth.c:hadamard)"), exit(1);
}
}
// transpose a matrix
Matrix * transpose(Matrix * m){
Matrix * a = initMatrix(m->cols, m->rows);
for (int i = 0; i < m->cols; i++){
for (int j =0; j < m->rows; j++){
a->at[i][j] = m->at[j][i];
}
}
return a;
}
// add two matrices together
Matrix * add(Matrix * a, Matrix * b) {
if (a->rows == b->rows && a->cols == b->cols) {
Matrix * c = initMatrix(a->rows, a->cols);
for (int i = 0; i < a->rows; i++) {
for (int j = 0; j < a->cols;j++){
c->at[i][j] = a->at[i][j] + b->at[i][j];
}
}
return c;
} else {
perror("Cannot add (meth.c:add)"), exit(1);
}
}
// multiply a matrix by a scalar
Matrix * scale(float scalar, Matrix * m) {
Matrix * a = initMatrix(m->rows, m->cols);
for (int i = 0; i < a->rows; i++) {
for (int j = 0; j < a->cols; j++) {
a->at[i][j] = scalar * m->at[i][j];
}
}
return a;
}
// activation function
float sigmoid(float x) {
return (1 / (1 + exp(-x)));
}
// derivative of activation function
float sigmoidPrime(float x) {
// return exp(-x) / powf(1 + exp(-x), 2);
return sigmoid(x) * (1 - sigmoid(x));
}
// apply activation function element-wise
Matrix * sig(Matrix * m) {
Matrix * a = initMatrix(m->rows, m->cols);
for (int i = 0; i < a->rows; i++) {
for (int j = 0; j < a->cols; j++) {
a->at[i][j] = sigmoid(m->at[i][j]);
}
}
return a;
}
// apply activation derivative element-wise
Matrix * sigP(Matrix * m) {
Matrix * a = initMatrix(m->rows, m->cols);
for (int i = 0; i < a->rows; i++) {
for (int j = 0; j < a->cols; j++) {
a->at[i][j] = sigmoidPrime(m->at[i][j]);
}
}
return a;
}
// compute last layer activation with softmax
Matrix * softMax(Matrix * z) {
Matrix * a = initMatrix(z->rows, 1);
float sum = 0.0f;
int i;
for (i = 0; i < z->rows; i++) {
sum += exp(z->at[i][0]);
}
for (i = 0; i < z->rows; i++) {
a->at[i][0] = exp(z->at[i][0]) / sum;
}
return a;
}