CX/src/neural.c

94 lines
2.6 KiB
C

#include <cx.h>
static Neural_Layer *
nl_new(size_t layer_size, size_t layer_size_next) {
Neural_Layer *self;
self = malloc(sizeof(Neural_Layer));
self->neurons = calloc(layer_size, sizeof(Neuron));
for (int i = 0; i < layer_size; i++) {
self->neurons[i].synapses = calloc(layer_size_next, sizeof(float));
}
self->layer_size = layer_size;
self->layer_size_next = layer_size_next;
return self;
}
static void
nl_free(Neural_Layer *self) {
free(self->neurons);
free(self);
}
Neural_Network *
neural_new(size_t input_size, size_t output_size, size_t layer_count) {
Neural_Network *self = malloc(sizeof(Neural_Network));
if (!self) {
// Failed to allocate.
return NULL;
}
// The difference between layer sizes, hidden layers step between the two
// sizes in linear fashion.
ssize_t layer_diff;
ssize_t layer_step;
self->layer_count = layer_count;
self->layers = malloc(layer_count * sizeof(Neural_Layer *));
layer_diff = (ssize_t) output_size - input_size;
// Calculate sizes of individual layers and allocate them.
for (int i = 0; i < layer_count; i++) {
self->layers[i] = nl_new(input_size
+ (layer_diff * i / ((ssize_t)layer_count-1)),
i < (layer_count-1) ?
(input_size + (layer_diff * (i+1)
/ ((ssize_t)layer_count-1)))
: 0);
}
return self;
}
void
neural_randomize(Neural_Network *self) {
FILE *f;
Neural_Layer *nl;
f = fopen("/dev/urandom", "r");
for (int i = 0; i < self->layer_count; i++) {
nl = self->layers[i];
for (int j = 0; j < nl->layer_size; j++) {
fread(nl->neurons[j].synapses, sizeof(float), nl->layer_size_next, f);
}
}
}
float *
neural_process(Neural_Network *self, float *input) {
float *retval = NULL;
Neural_Layer *nl = self->layers[0];
for (int i = 0; i < self->layers[0]->layer_size; i++) {
nl->neurons[i].value = input[i];
}
for (int i = 0; i < self->layer_count; i++) {
nl = self->layers[i];
float dot_prod = 0;
for (int j = 0; j < nl->layer_size; j++) {
// MATH GOES BRRRRRRRR
dot_prod += nl->neurons[j].value
* nl->neurons[j].synapses[j];
}
}
retval = malloc(nl->layer_size * sizeof(float));
for (int i = 0; i < nl->layer_size; i++) {
retval[i] = nl->neurons[i].value;
}
return retval;
}