/* ########### Exact simulation of integrate-and-fire models with synaptic conductances ######################
This code is associated with the paper :
"Brette Romain (2006) , Exact simulation of integrate-and-fire models with synaptic conductances" :
http://www.di.ens.fr/~brette/papers/Brette2005NC.htm
*************************
*************************
*************************
Cohen Benjamin
benjamin.cohen _AT_ ens-lyon.fr
Last updated : Jul 2006
If you modify the source file, please don't delete this header
***********************************************************************************************************
*/
#include "network.h"
double log_e(double a){
return(log(a)*2.30258509299);
}
double gauss(double m, double et){
double x1 = (((double)rand()+1.)/(double)(RAND_MAX+1));
double x2 = (((double)rand()+1.)/(double)(RAND_MAX+1));
//x1 , x2 != 0.!!
if (x1 < 0.) x1 = -1.*x1;
if (x2 < 0.) x2 = -1.*x2;
double y1 = sqrt(-2.*log_e(x1)) * cos(2*3.1416*x2);
double y2 = sqrt(-2.*log_e(x1)) * sin(2*3.1416*x2);
return(m+y2*et);
}
//return true 1 time per c times
bool proba(double c){
return(std::rand()<=((double)RAND_MAX)/c);
}
/*--------------------------Network CLASS-------------------------------------*/
/*CONSTRUCTOR*/
Network::Network(int nb_neurons_){
#define IFSC_PREC 1e-4
//To compute rho
IFSC_Init(Taui);
time_t timer1;
time(&timer1);
srand(localtime(&timer1)->tm_min + localtime(&timer1)->tm_hour+400*localtime(&timer1)->tm_sec);
nb_neurons = nb_neurons_;
q = new Ncq(SIM_LENGTH);
table = (Neurone **)malloc(nb_neurons*sizeof(Neurone *));
//initalization of neurons : 4/5 are inhibitor, 1/5 excitator.
int i;
for (i =0;i<INHIBITORY_NEURONS;i++){
table[i] = new Neurone(table,q,gauss(-5.,5.),Vr_,Vt_,El_,Ee_,Ei_,gauss(4.,1.5), gauss(20.,12.),Taui,Taum,Dgi_,Dge_,true,i);
}
for (i =INHIBITORY_NEURONS;i<nb_neurons;i++){
table[i] = new Neurone(table,q,gauss(-5.,5.),Vr_,Vt_,El_,Ee_,Ei_,gauss(4.,1.5), gauss(20.,12.),Taui,Taum,Dgi_,Dge_,false,i);
}
//initialization of synapses
for (i=0;i<nb_neurons;i++){
int j;
for (j=0;j<nb_neurons;j++){
if (i!=j){
if (proba(SYNAPSES_)) { table[i]->voisins.push_back(table[j]); }
}
}
}
};
/*-----DESTRUCTOR-----*/
Network::~Network(){
delete q;
int i;
for (i=0;i<nb_neurons;i++){
delete table[i];
}
free(table);
IFSC_Done();
};
/*--------------Network::START()--------------------*/
void Network::start(){
double t = 0.;
while(t<=SIM_LENGTH && !(q->empty())) {
Spike *s = q->pop(); //s = Next spike
#ifdef WITH_LOWER_BOUND
if (!(s->computed)) {
table[s->sender]->upgrade();
}
else { //the time is exact
#endif //WITH_LOWER_BOUND
#ifndef NO_TERM
printf("%d %f\n",s->sender,s->t*Taum); //id time
#endif //NO_TERM
t = s->t;
backup.push(*s);
(table[s->sender])->pulse(); //Pulse the "owner" of the spike
#ifdef WITH_LOWER_BOUND
}
#endif
}
};