Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions examples/stdp_example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "../src/cbrain.h"
#include <unistd.h>

int main()
{
srand((unsigned int)time(NULL));
struct brain* b = brain_init(2, 0.1f);
neuron_set_type(b->neurons[0], sensory);
neuron_set_type(b->neurons[1], motor);
neuron_link(b->neurons[0], b->neurons[1], 5);

for (int t = 0; t < 10; t++) {
if (t == 1) neuron_fire(b->neurons[0]);
if (t == 3) neuron_fire(b->neurons[1]);
neuron_update_range(0, 1, b);
printf("step %u weight=%d\n", b->step, b->neurons[0]->wts[0]);
usleep(100000);
}
return 0;
}

4 changes: 2 additions & 2 deletions examples/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ make uninstall
make clean
make -j15 install
cd examples
gcc tem_test.c -o tem_test -lSDL2 -lcbrain
gcc stdp_example.c -o stdp_example -lSDL2 -lcbrain
echo
./tem_test
./stdp_example
106 changes: 71 additions & 35 deletions src/brain.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ SOFTWARE.

#include "cbrain.h"

pthread_mutex_t lock;

/* initialize new neuron */
struct neuron* neuron_init(uint id, float decay)
{
Expand All @@ -37,10 +39,11 @@ struct neuron* neuron_init(uint id, float decay)
n->thisstate = 0.0;
n->nextstate = 0.0;
n->state_decay = decay;
n->fired = 0;
n->n_fired = 0;
n->n_type = undefined;
return n;
n->fired = 0;
n->n_fired = 0;
n->n_type = undefined;
n->last_fired = -STDP_WINDOW;
return n;
}

/* link neuron 'n' to neuron 'src' with given weight 'wt' */
Expand Down Expand Up @@ -111,10 +114,37 @@ void neuron_unlink(struct neuron* src, struct neuron* n)
/* accumulate passed weight to neuron's nextstate */
void neuron_accum(struct neuron* n, uint wt)
{
cbrain_print(2, "accumulating neuron %d with weight %d\n", n->id, wt);
pthread_mutex_lock(&lock);
n->nextstate += wt;
pthread_mutex_unlock(&lock);
cbrain_print(2, "accumulating neuron %d with weight %d\n", n->id, wt);
pthread_mutex_lock(&lock);
n->nextstate += wt;
pthread_mutex_unlock(&lock);
}

void neuron_stdp(struct brain* b, struct neuron* n)
{
/* potentiation for recently active presynaptic neurons */
for (int i = 0; i < n->inc; i++) {
int pre_id = n->incoming[i];
struct neuron* pre = b->neurons[pre_id];
int dt = b->step - pre->last_fired;
if (dt > 0 && dt <= STDP_WINDOW) {
int idx = checkexist(n->id, pre->links, pre->lc);
if (idx != -1) {
pre->wts[idx] += STDP_INC;
if (pre->wts[idx] > WEIGHT_MAX) pre->wts[idx] = WEIGHT_MAX;
}
}
}

/* depression for synapses where postsynaptic neuron fired recently */
for (int i = 0; i < n->lc; i++) {
struct neuron* post = b->neurons[n->links[i]];
int dt = b->step - post->last_fired;
if (dt > 0 && dt <= STDP_WINDOW) {
n->wts[i] -= STDP_DEC;
if (n->wts[i] < -WEIGHT_MAX) n->wts[i] = -WEIGHT_MAX;
}
}
}

/* check if neuron's thisstate exceeds the threshold,
Expand All @@ -126,17 +156,19 @@ int neuron_update(struct neuron* n, struct brain* b)
assert(n->id <= (b->nc - 1));

// fire neuron if thisstate exceeds THRESHOLD
if (n->thisstate >= THRESHOLD) {
n->f_type = self;
for (int i = 0; i < n->lc; i++) {
cbrain_print(4, "sending %d from %d to %d\n", n->wts[i], n->id, n->links[i]);
b->neurons[n->links[i]]->nextstate += n->wts[i];
}
n->fired = 1;
n->thisstate = 0;
n->nextstate = 0;
n->n_fired += 1;
} else {
if (n->thisstate >= THRESHOLD) {
n->f_type = self;
for (int i = 0; i < n->lc; i++) {
cbrain_print(4, "sending %d from %d to %d\n", n->wts[i], n->id, n->links[i]);
b->neurons[n->links[i]]->nextstate += n->wts[i];
}
n->fired = 1;
n->thisstate = 0;
n->nextstate = 0;
n->n_fired += 1;
neuron_stdp(b, n);
n->last_fired = b->step;
} else {
n->thisstate += n->nextstate;

// thisstate decay if next state is zero
Expand All @@ -154,14 +186,15 @@ int neuron_update(struct neuron* n, struct brain* b)

int neuron_update_range(uint s, uint e, struct brain* b)
{
int nf = 0;
for (int i = s; i <= e; i++) {
int fired = neuron_update(b->neurons[i], b);
if (fired == 1) {
nf += 1;
}
}
return nf;
int nf = 0;
for (int i = s; i <= e; i++) {
int fired = neuron_update(b->neurons[i], b);
if (fired == 1) {
nf += 1;
}
}
b->step += 1;
return nf;
}

void neuron_set_type(struct neuron* n, type t)
Expand Down Expand Up @@ -207,9 +240,10 @@ struct brain* brain_init(int s, float decay)
struct brain* b = (struct brain*)malloc(sizeof(struct brain));
b->neurons = (struct neuron**)malloc(sizeof(struct neuron) * s);
b->nc = s;
b->nmax = s;
b->fitness = 0.0;
b->state_decay = decay;
b->nmax = s;
b->fitness = 0.0;
b->state_decay = decay;
b->step = 0;

// make neurons
for (int i = 0; i < s; i++) {
Expand All @@ -220,11 +254,13 @@ struct brain* brain_init(int s, float decay)

void brain_reset(struct brain* b)
{
for (int i = 0; i < b->nc; i++) {
b->neurons[i]->thisstate = 0;
b->neurons[i]->nextstate = 0;
b->neurons[i]->fired = 0;
}
for (int i = 0; i < b->nc; i++) {
b->neurons[i]->thisstate = 0;
b->neurons[i]->nextstate = 0;
b->neurons[i]->fired = 0;
b->neurons[i]->last_fired = -STDP_WINDOW;
}
b->step = 0;
}

void brain_neuron_type(struct brain* b, type t)
Expand Down
61 changes: 34 additions & 27 deletions src/cbrain.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ SOFTWARE.
#define MUTATE_PROB 0.00001
#define WEIGHT_MIN 1
#define WEIGHT_MAX 20
/* STDP parameters */
#define STDP_WINDOW 5
#define STDP_INC 1
#define STDP_DEC 1
#define WIN_WIDTH 800
#define WIN_HEIGHT 400
#define E 2.71828182
Expand All @@ -51,9 +55,9 @@ typedef unsigned int uint;
typedef enum { undefined, sensory, intermediate, motor } type;
typedef enum { user, self } fire_type;

pthread_mutex_t lock;
extern pthread_mutex_t lock;

struct neuron {
typedef struct neuron {
int id;
int *links;
int *incoming;
Expand All @@ -68,53 +72,55 @@ struct neuron {
float thisstate;
float nextstate;
float state_decay;
uint fired;
uint n_fired;
uint fired;
uint n_fired;
int last_fired;
} neuron;

struct brain {
typedef struct brain {
uint nc;
uint nmax;
float state_decay;
float fitness;
struct neuron** neurons;
float fitness;
struct neuron** neurons;
uint step;
} brain;

struct nthread {
typedef struct nthread {
pthread_t tid;
uint s;
uint e;
uint status;
} nthread;

struct thread_bank {
typedef struct thread_bank {
uint tc;
uint tmax;

struct nthread** threads;
struct nthread** threads;
} thread_bank;

struct sdlctx {
SDL_Window* win;
SDL_Renderer* ren;
SDL_Event event;
typedef struct sdlctx {
SDL_Window* win;
SDL_Renderer* ren;
SDL_Event event;
} sdlctx;

struct vect {
float x;
float y;
typedef struct vect {
float x;
float y;
} vect;

struct entityctx {
int mlstart;
int mrstart;
int mlend;
int mrend;
int width;
int height;
float rot;
float x;
float y;
typedef struct entityctx {
int mlstart;
int mrstart;
int mlend;
int mrend;
int width;
int height;
float rot;
float x;
float y;
} entityctx;

/* src/brain.c */
Expand All @@ -129,6 +135,7 @@ void neuron_accum(struct neuron*, uint);
void neuron_fire(struct neuron*);
int neuron_update(struct neuron*, struct brain*);
int neuron_update_range(uint, uint, struct brain*);
void neuron_stdp(struct brain*, struct neuron*);
void neuron_set_type(struct neuron*, type);
void neuron_add(struct brain*);
void neuron_show_stat(struct neuron*);
Expand Down