/* A code to get the raster plots of spikes for the constituent cells */
#include <stdio.h> /* Standard header file for the Input and Output */
#include <stdlib.h> /* Standard library header file */
#include <math.h> /* Math header file */
#include <conio.h> /* Header file for the IO on the console */
#include <time.h> /* Header file for initializing the random number generator */
unsigned long int RKCNT; /* No. of calling the Runge-Kutta intergration routine FLOW() to avoid the calculation error in time */
#define NC 1024 /* No. of GR cluster */
#define NGR 50 /* No. of GR cells in each GR cluster */
#define NPC 16 /* NPC: No. of PCs */
#define NMFVN 100
#define MaxSPIKECount 1000 /* Maximum No. of spikes used to calculate the synaptic conductance for each neuron to save the computational memory
--> The size of array for the spike time is N+1 x MaxSPIKECount+1 */
int SN,TN,PN,NCycle;
int NOSPIKEGR[NC+1][NGR+1],NOSPIKEMF[NC+1][NGR+1],NOSPIKEGO[NC+1],NOSPIKEBC[NPC+1],NOSPIKEPC[NPC+1];
int NOSPIKEVN,NOSPIKEMFVN[NMFVN+1],NOSPIKEIO,NOSPIKEES;
int NoPreGOGR[NC+1],IPreGOGR[NC+1][10*NC],iPreGOGR[NC+1][10*NC];
int NoPreGLGO[NC+1],IPreGLGO[NC+1][10*NC];
float t,h,vGR[NC+1][NGR+1],vGO[NC+1],vBC[NPC+1],vPC[NPC+1],vVN,vIO;
float fvGR[NC+1][NGR+1],fvGO[NC+1],fvBC[NPC+1],fvPC[NPC+1],fvVN,fvIO;
float CGR,gLGR,VLGR,gAHPGR,tauAHPGR,VAHPGR,VthGR;
float CGO,gLGO,VLGO,gAHPGO,tauAHPGO,VAHPGO,VthGO;
float CBC,gLBC,VLBC,gAHPBC,tauAHPBC,VAHPBC,VthBC;
float CPC,gLPC,VLPC,gAHPPC,tauAHPPC,VAHPPC,VthPC;
float CVN,gLVN,VLVN,gAHPVN,tauAHPVN,VAHPVN,VthVN;
float CIO,gLIO,VLIO,gAHPIO,tauAHPIO,VAHPIO,VthIO;
float SPTIMEGR[NC+1][NGR+1][MaxSPIKECount+1],SPTIMEMF[NC+1][NGR+1][MaxSPIKECount+1];
float SPTIMEGO[NC+1][MaxSPIKECount+1],SPTIMEBC[NPC+1][MaxSPIKECount+1];
float SPTIMEPC[NPC+1][MaxSPIKECount+1],SPTIMEVN[MaxSPIKECount+1];
float SPTIMEMFVN[NMFVN+1][MaxSPIKECount+1],SPTIMEIO[MaxSPIKECount+1],SPTIMEES[MaxSPIKECount+1];
float fAVGMF,fT,fAVGES;
float IdcPC,IdcVN;
float ALPHAbound,CutOffTimebound;
/* DEbound: Bound for the double exponential function,
CutOffTimebound: Error bound for the cut-off time (ms). */
float CutOffTimeGRMFAMPA,CutOffTimeGRMFNMDA,VGRMFSyn;
float CutOffTimeGOGRAMPA,CutOffTimeGOGRNMDA,VGOGRSyn;
float CutOffTimeGRGOGABA,VGRGOSyn;
float CutOffTimeBCGRAMPA,VBCGRSyn;
float CutOffTimePCGRAMPA,CutOffTimePCIOAMPA,CutOffTimePCBCGABA,VPCGRSyn,VPCIOSyn,VPCBCSyn;
float CutOffTimeVNMFAMPA,CutOffTimeVNMFNMDA,VVNMFSyn;
float CutOffTimeVNPCGABA,VVNPCSyn;
float CutOffTimeIOESAMPA,VIOESSyn,CutOffTimeIOVNGABA,VIOVNSyn;
float tauGRMFAMPA,tauGRMFNMDA,gGRMFAMPA,gGRMFNMDA,JGRMF;
float tauGOGRAMPA,tauGOGRNMDA1,tauGOGRNMDA2,AGOGRNMDA1,AGOGRNMDA2,gGOGRAMPA,gGOGRNMDA,JGOGR;
float tauGRGOGABA1,tauGRGOGABA2,AGRGOGABA1,AGRGOGABA2,gGRGOGABA,JGRGO;
float tauBCGRAMPA,gBCGRAMPA,JBCGR;
float tauPCGRAMPA,gPCGRAMPA,JPCGR[NPC+1][NC+1][NGR+1],JPCGR0,tauPCBCGABA,gPCBCGABA,JPCBC;
float tauPCIOAMPA,gPCIOAMPA,JPCIO;
float tauVNMFAMPA,tauVNMFNMDA,gVNMFAMPA,gVNMFNMDA,JVNMF,tauVNPCGABA,gVNPCGABA,JVNPC;
float tauIOESAMPA,gIOESAMPA,JIOES,tauIOVNGABA,gIOVNGABA,JIOVN;
float PGOGR,PGLGO;
float deltaLTD,deltaLTP,CutOffTimeLTD,dTl,dTr,A,B,t0,sigma;
char FOUTN1[20],FOUTN2[20],FOUTN3[20],FOUTN4[20],FOUTN5[20],FOUTN6[20],FOUTN7[20];
FILE *FOUT1,*FOUT2,*FOUT3,*FOUT4,*FOUT5,*FOUT6,*FOUT7;
/* General Routines */
void TS(); /* A routine to obtain the global and individual outputs
and the raster plot of spikings */
void FLOW(); /* A routine to integrate the differential equations */
float CutOff1(float tau); /* A Routine to find the cut-off time of the alpha
function for the local synapse by using the bisection method */
float CutOff2(float A1, float A2, float tau1, float tau2); /* A Routine to find the cut-off time of the alpha
function for the local synapse by using the bisection method */
float ALPHA1(float t, float tau); /* A Routine to return the value of the alpha
function for the local synaptic current */
float ALPHA2(float t, float A1, float A2, float tau1, float tau2); /* A Routine to return the value of the alpha
function for the local synaptic current */
float UniRandom(); /* A routine to generate a uniform random number on (0,1)
using the C-supplied rand function */
/* Routines dependent on the system */
void F(); /* A routine to return the function values in the
differential equations */
/* Cerebellar network in Yamazaki & Nagao (2012) */
void main()
{
int i,j,k,l,m;
int Idx;
float eta;
time_t ttt;
/* Initialize the random number generator */
srand((unsigned) time(&ttt));
/* Parameters for the each cell */
CGR=3.1; gLGR=0.43; VLGR=-58.0; gAHPGR=1.0; tauAHPGR=5.0; VAHPGR=-82.0; VthGR=-35.0; /* GR */
CGO=28.0; gLGO=2.3; VLGO=-55.0; gAHPGO=20.0; tauAHPGO=5.0; VAHPGO=-72.7; VthGO=-52.0; /* GO */
CBC=107.0; gLBC=2.32; VLBC=-68.0; gAHPBC=100.0; tauAHPBC=2.5; VAHPBC=-70.0; VthBC=-55.0; /* BC */
CPC=107.0; gLPC=2.32; VLPC=-68.0; gAHPPC=100.0; tauAHPPC=5.0; VAHPPC=-70.0; VthPC=-55.0; /* PC */
CVN=122.3; gLVN=1.63; VLVN=-56.0; gAHPVN=50.0; tauAHPVN=2.5; VAHPVN=-70.0; VthVN=-38.8; /* VN */
CIO=10.; gLIO=0.67; VLIO=-60.0; gAHPIO=1.0; tauAHPIO=10.; VAHPIO=-75.0; VthIO=-50.; /* IO */
/* Parameters for the synaptic currents */
tauGRMFAMPA=1.2; gGRMFAMPA=0.18; VGRMFSyn=0.; tauGRMFNMDA=52.0; gGRMFNMDA=0.025; JGRMF=8.; /* MF to GR */
tauGOGRAMPA=1.5; gGOGRAMPA=45.5; VGOGRSyn=0.; tauGOGRNMDA1=31.0; tauGOGRNMDA2=170.0;
AGOGRNMDA1=0.33; AGOGRNMDA2=(1.-AGOGRNMDA1); gGOGRNMDA=30.0; JGOGR=0.00004; /* GR to GO */
tauGRGOGABA1=7.0; tauGRGOGABA2=59.0; gGRGOGABA=0.028; VGRGOSyn=-82.0;
AGRGOGABA1=0.43; AGRGOGABA2=(1.-AGRGOGABA1); JGRGO=10.0; /* GO to GR */
tauBCGRAMPA=8.3; gBCGRAMPA=0.7; VBCGRSyn=0.; JBCGR=0.006; /* GR to BC (PF) */
tauPCGRAMPA=8.3; gPCGRAMPA=0.7; VPCGRSyn=0.; JPCGR0=0.006; /* GR to PC (PF) */
for(i=1;i<=NPC;i++) {
for(j=1;j<=NC;j++) {
for(k=1;k<=NGR;k++) JPCGR[i][j][k]=JPCGR0;
}
}
tauPCIOAMPA=8.3; gPCIOAMPA=0.7; VPCIOSyn=0.; JPCIO=1.0; /* IO to PC */
tauPCBCGABA=10.0; gPCBCGABA=1.0; VPCBCSyn=-75.0; JPCBC=5.3; /* BC to PC */
tauVNMFAMPA=9.9; gVNMFAMPA=50.0; VVNMFSyn=0.; tauVNMFNMDA=30.6; gVNMFNMDA=25.8; JVNMF=0.002; /* MF to VN */
tauVNPCGABA=42.3; gVNPCGABA=30.0; VVNPCSyn=-88.0; JVNPC=0.008; /* PC to VN */
tauIOESAMPA=10.0; gIOESAMPA=1.0; VIOESSyn=0.; tauIOVNGABA=10.0; gIOVNGABA=0.18; JIOVN=5.0; /* VN to IO */
JIOES=1.0;
/* Parameters for the synaptic plasticity rule */
deltaLTD=0.005; deltaLTP=0.0005; CutOffTimeLTD=50.;
dTl=-117.5; dTr=277.5;
A=-0.09; B=0.31; t0=80.0; sigma=180.;
/* Constant stimuli for PC and VN */
IdcPC=250.;
IdcVN=700.;
/* ALPHAbound: Bound for the alpha function,
CutOffTimebound: Error bound for the cut-off time (ms). */
ALPHAbound=1.e-5; CutOffTimebound=1.e-5;
CutOffTimeGRMFAMPA=CutOff1(tauGRMFAMPA); /* Find the cut-off time for the local synaptic current */
CutOffTimeGRMFNMDA=CutOff1(tauGRMFNMDA); /* Find the cut-off time for the local synaptic current */
CutOffTimeGOGRAMPA=CutOff1(tauGOGRAMPA); /* Find the cut-off time for the local synaptic current */
CutOffTimeGOGRNMDA=CutOff2(AGOGRNMDA1,AGOGRNMDA2,tauGOGRNMDA1,tauGOGRNMDA2); /* Find the cut-off time for the local synaptic current */
CutOffTimeGRGOGABA=CutOff2(AGRGOGABA1,AGRGOGABA2,tauGRGOGABA1,tauGRGOGABA2); /* Find the cut-off time for the local synaptic current */
CutOffTimeBCGRAMPA=CutOff1(tauBCGRAMPA); /* Find the cut-off time for the local synaptic current */
CutOffTimePCGRAMPA=CutOff1(tauPCGRAMPA); /* Find the cut-off time for the local synaptic current */
CutOffTimePCIOAMPA=CutOff1(tauPCIOAMPA); /* Find the cut-off time for the local synaptic current */
CutOffTimePCBCGABA=CutOff1(tauPCBCGABA); /* Find the cut-off time for the local synaptic current */
CutOffTimeVNMFAMPA=CutOff1(tauVNMFAMPA); /* Find the cut-off time for the local synaptic current */
CutOffTimeVNMFNMDA=CutOff1(tauVNMFNMDA); /* Find the cut-off time for the local synaptic current */
CutOffTimeVNPCGABA=CutOff1(tauVNPCGABA); /* Find the cut-off time for the local synaptic current */
CutOffTimeIOESAMPA=CutOff1(tauIOESAMPA); /* Find the cut-off time for the local synaptic current */
CutOffTimeIOVNGABA=CutOff1(tauIOVNGABA); /* Find the cut-off time for the local synaptic current */
/* Parameters of the Poisson spike train generator tor for the post-movement
sensory signal via MF
fT (kHz): Frequency of the post-movement sensory signal,
fAVGMF (kHz): Mean firing rate of sensory signal of MF */
fAVGMF=15./1000.;fT=0.5/1000.; fAVGES=1.5/1000.;
/* Connection probability */
PGOGR=0.1; /* GR to GO */
PGLGO=0.06; /* GO to GR */
/* Calculation Conditions:
SN: No. of Runge-Kutta (RK) steps per unit time (1ms),
h: RK time interval,
TN: Transient time to eliminate the transient behavior,
PN: Plotting time. */
SN=1; h=1./SN; TN=0; PN=2000;
/* Input names of output files, and open them */
printf("\n INPUT THE NAME OF THE OUTPUT FILE 1 (Raster plot for GR) \n");scanf("%s",FOUTN1);
if((FOUT1 = fopen(FOUTN1,"w"))==NULL){printf("FILE OPEN ERROR...\n");exit(-1);}
printf("\n INPUT THE NAME OF THE OUTPUT FILE 2 (Raster plot for GO) \n");scanf("%s",FOUTN2);
if((FOUT2 = fopen(FOUTN2,"w"))==NULL){printf("FILE OPEN ERROR...\n");exit(-1);}
printf("\n INPUT THE NAME OF THE OUTPUT FILE 3 (Raster plot for PC) \n");scanf("%s",FOUTN3);
if((FOUT3 = fopen(FOUTN3,"w"))==NULL){printf("FILE OPEN ERROR...\n");exit(-1);}
printf("\n INPUT THE NAME OF THE OUTPUT FILE 4 (Raster plot for BC) \n");scanf("%s",FOUTN4);
if((FOUT4 = fopen(FOUTN4,"w"))==NULL){printf("FILE OPEN ERROR...\n");exit(-1);}
printf("\n INPUT THE NAME OF THE OUTPUT FILE 5 (Raster plot for VN) \n");scanf("%s",FOUTN5);
if((FOUT5 = fopen(FOUTN5,"w"))==NULL){printf("FILE OPEN ERROR...\n");exit(-1);}
printf("\n INPUT THE NAME OF THE OUTPUT FILE 6 (Raster plot for IO) \n");scanf("%s",FOUTN6);
if((FOUT6 = fopen(FOUTN6,"w"))==NULL){printf("FILE OPEN ERROR...\n");exit(-1);}
printf("\n INPUT THE NAME OF THE OUTPUT FILE 7 (Active PF-PC synaptic weight) \n");scanf("%s",FOUTN7);
if((FOUT7 = fopen(FOUTN7,"w"))==NULL){printf("FILE OPEN ERROR...\n");exit(-1);}
/* Gerenation of connection from GR to GO */
for(i=1;i<=NC;i++) {
NoPreGOGR[i]=0;
for(j=i-24;j<=i+24;j++) {
if(j<1) Idx=j+NC;
if(j>NC) Idx=j-NC;
for(k=1;k<=NGR;k++) {
eta=UniRandom();
if(eta<PGOGR) {
NoPreGOGR[i]=NoPreGOGR[i]+1;
IPreGOGR[i][NoPreGOGR[i]]=Idx;
iPreGOGR[i][NoPreGOGR[i]]=k;
}
}
}
}
/* Gerenation of connection from GO to GR for GL */
for(i=1;i<=NC;i++) {
NoPreGLGO[i]=0;
for(j=i-40;j<=i+40;j++) {
if(j<1) Idx=j+NC;
if(j>NC) Idx=j-NC;
eta=UniRandom();
if(eta<PGLGO) {
NoPreGLGO[i]=NoPreGLGO[i]+1;
IPreGLGO[i][NoPreGLGO[i]]=Idx;
}
}
}
/* Initialize variables */
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) vGR[i][j]=VLGR+10.*(UniRandom()-0.5);
}
for(i=1;i<=NC;i++) vGO[i]=VLGO+10.*(UniRandom()-0.5);
for(i=1;i<=NPC;i++) vBC[i]=VLBC+10.*(UniRandom()-0.5);
for(i=1;i<=NPC;i++) vPC[i]=VLPC+10.*(UniRandom()-0.5);
vVN=VLVN+10.*(UniRandom()-0.5);
vIO=VLIO+10.*(UniRandom()-0.5);
/* Begin the Main Calculation */
for(NCycle=1;NCycle<=400;NCycle++) TS();
fclose(FOUT1);fclose(FOUT2);fclose(FOUT3);fclose(FOUT4);fclose(FOUT5);fclose(FOUT6);fclose(FOUT7);
printf("<***** End *****>\n");
getche();
}
/* A routine to obtain the global and individual outputs and the raster plot
of spikings */
void TS()
{
int i,j,k,l,m,Idx;
int CF[NPC+1],PF[NC+1][NGR+1],DF;
float fPoissonMF,pr,eta,fPoissonES,prES;
float tCFeff,tPFeff,dT,dWJ;
/* Initialize variables */
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) NOSPIKEMF[i][j]=0;
}
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) {
NOSPIKEGR[i][j]=0; SPTIMEGR[i][j][1]=-10.;
}
}
for(i=1;i<=NC;i++) {
NOSPIKEGO[i]=0; SPTIMEGO[i][1]=-10.;
}
for(i=1;i<=NPC;i++) {
NOSPIKEBC[i]=0; SPTIMEBC[i][1]=-10.;
}
for(i=1;i<=NPC;i++) {
NOSPIKEPC[i]=0; SPTIMEPC[i][1]=-10.;
}
for(i=1;i<=NMFVN;i++) {NOSPIKEMFVN[i]=0;}
NOSPIKEVN=0; SPTIMEVN[1]=-10.;
NOSPIKEES=0;
NOSPIKEIO=0; SPTIMEIO[1]=-10.;
/* Initialize the No. of call the Runge-Kutta intergration routine FLOW() */
RKCNT=0; t=0.;
for(i=1;i<=PN*SN;i++) {
FLOW();
/* Initialize */
for(j=1;j<=NPC;j++) CF[j]=0;
for(j=1;j<=NC;j++) {
for(k=1;k<=NGR;k++) PF[j][k]=0;
}
/* Generation of MF sensory signal */
fPoissonMF=-fAVGMF*cos(2.*M_PI*fT*t)+fAVGMF;
pr=fPoissonMF*h;
for(j=1;j<=NC;j++) {
for(k=1;k<=NGR;k++) {
eta=UniRandom();
if(eta<pr) {
/* Increase in the number of spikes of MF */
NOSPIKEMF[j][k]=NOSPIKEMF[j][k]+1;
if(NOSPIKEMF[j][k]>MaxSPIKECount) NOSPIKEMF[j][k]=MaxSPIKECount;
for(l=NOSPIKEMF[j][k];l>1;l--) {SPTIMEMF[j][k][l]=SPTIMEMF[j][k][l-1];}
SPTIMEMF[j][k][1]=t;
}
}
}
/* Find a spike in GR cell */
for(j=1;j<=NC;j++) {
for(k=1;k<=NGR;k++) {
if(vGR[j][k]>=VthGR) {
fprintf(FOUT1,"%4d %12.8f %4d %4d\n",NCycle,t,j,k);
for(l=1;l<=NPC;l++) fprintf(FOUT7,"%4d %12.8f %12.8f %4d %4d %4d\n",NCycle,t,JPCGR[j][k][l],j,k,l);
NOSPIKEGR[j][k]=NOSPIKEGR[j][k]+1;
if(NOSPIKEGR[j][k]>MaxSPIKECount) NOSPIKEGR[j][k]=MaxSPIKECount;
for(l=NOSPIKEGR[j][k];l>1;l--) {SPTIMEGR[j][k][l]=SPTIMEGR[j][k][l-1];}
SPTIMEGR[j][k][1]=t;
PF[j][k]=1;
}
}
}
/* Find a spike in GO cell */
for(j=1;j<=NC;j++) {
if(vGO[j]>=VthGO) {
fprintf(FOUT2,"%4d %12.8f %4d\n",NCycle,t,j);
NOSPIKEGO[j]=NOSPIKEGO[j]+1;
if(NOSPIKEGO[j]>MaxSPIKECount) NOSPIKEGO[j]=MaxSPIKECount;
for(k=NOSPIKEGO[j];k>1;k--) {SPTIMEGO[j][k]=SPTIMEGO[j][k-1];}
SPTIMEGO[j][1]=t;
}
}
/* Find a spike in BC */
for(j=1;j<=NPC;j++) {
if(vBC[j]>=VthBC) {
fprintf(FOUT4,"%4d %12.8f %4d\n",NCycle,t,j);
NOSPIKEBC[j]=NOSPIKEBC[j]+1;
if(NOSPIKEBC[j]>MaxSPIKECount) NOSPIKEBC[j]=MaxSPIKECount;
for(k=NOSPIKEBC[j];k>1;k--) {SPTIMEBC[j][k]=SPTIMEBC[j][k-1];}
SPTIMEBC[j][1]=t;
}
}
/* Find a spike in PC */
for(j=1;j<=NPC;j++) {
if(vPC[j]>=VthPC) {
fprintf(FOUT3,"%4d %12.8f %4d\n",NCycle,t,j);
NOSPIKEPC[j]=NOSPIKEPC[j]+1;
if(NOSPIKEPC[j]>MaxSPIKECount) NOSPIKEPC[j]=MaxSPIKECount;
for(k=NOSPIKEPC[j];k>1;k--) {SPTIMEPC[j][k]=SPTIMEPC[j][k-1];}
SPTIMEPC[j][1]=t;
CF[j]=1;
}
}
/* Generation of MF sensory signal into the VN */
for(j=1;j<=NMFVN;j++) {
eta=UniRandom();
if(eta<pr) {
/* Increase in the number of spikes of MF */
NOSPIKEMFVN[j]=NOSPIKEMFVN[j]+1;
if(NOSPIKEMFVN[j]>MaxSPIKECount) NOSPIKEMFVN[j]=MaxSPIKECount;
for(k=NOSPIKEMFVN[j];k>1;k--) {SPTIMEMFVN[j][k]=SPTIMEMFVN[j][k-1];}
SPTIMEMFVN[j][1]=t;
}
}
/* Find a spike in VN */
if(vVN>=VthVN) {
fprintf(FOUT5,"%4d %12.8f %4d\n",NCycle,t,1);
NOSPIKEVN=NOSPIKEVN+1;
if(NOSPIKEVN>MaxSPIKECount) NOSPIKEVN=MaxSPIKECount;
for(j=NOSPIKEVN;j>1;j--) {SPTIMEVN[j]=SPTIMEVN[j-1];}
SPTIMEVN[1]=t;
}
/* Generation of MF sensory signal into the VN */
fPoissonES=-fAVGES*cos(2.*M_PI*fT*t)+fAVGES;
prES=fPoissonES*h;
eta=UniRandom();
if(eta<prES) {
/* Increase in the number of spikes of MF */
NOSPIKEES=NOSPIKEES+1;
if(NOSPIKEES>MaxSPIKECount) NOSPIKEES=MaxSPIKECount;
for(j=NOSPIKEES;j>1;j--) {SPTIMEES[j]=SPTIMEES[j-1];}
SPTIMEES[1]=t;
}
/* Find a spike in IO */
if(vIO>=VthIO) {
fprintf(FOUT6,"%4d %12.8f %4d\n",NCycle,t,1);
NOSPIKEIO=NOSPIKEIO+1;
if(NOSPIKEIO>MaxSPIKECount) NOSPIKEIO=MaxSPIKECount;
for(j=NOSPIKEIO;j>1;j--) {SPTIMEIO[j]=SPTIMEIO[j-1];}
SPTIMEIO[1]=t;
for(j=1;j<=NPC;j++) CF[j]=1;
}
/* Plasticity rule */
for(j=1;j<=NPC;j++) {
if(CF[j]==1) { /* CF firing --> LTD */
/* Calculate the effective range */
tCFeff=t-dTr;
if(tCFeff<0.) tCFeff=0.;
for(k=(NC-143)+(j-1)*64;k<=(NC-143)+(j-1)*64+287;k++) { /* Find the PF firing of pre-synaptic GR cells in the effective range */
if(k<1) Idx=k+NC;
if(k>NC) Idx=k-NC;
for(l=1;l<=NGR;l++) {
for(m=1;m<=NOSPIKEGR[k][l];m++) {
if(SPTIMEGR[k][l][m] < tCFeff) break;
dT=t-SPTIMEGR[k][l][m];
dWJ=A+B*exp(-pow((dT-t0)/sigma,2.));
JPCGR[j][k][l]=JPCGR[j][k][l]-deltaLTD*JPCGR[j][k][l]*dWJ;
}
}
}
}
else {
for(k=(NC-143)+(j-1)*64;k<=(NC-143)+(j-1)*64+287;k++) { /* Find the PF firing of pre-synaptic GR cells */
if(k<1) Idx=k+NC;
if(k>NC) Idx=k-NC;
for(l=1;l<=NGR;l++) {
if(PF[k][l]==1) { /* PF firing */
DF=0;
/* Calculate the effective range */
tPFeff=t+dTl;
if(tPFeff<0.) tPFeff=0.;
for(m=1;m<=NOSPIKEPC[j];m++) {
if(SPTIMEPC[j][m] < tPFeff) break;
dT=t-SPTIMEPC[j][m];
dWJ=A+B*exp(-pow((dT-t0)/sigma,2.));
JPCGR[j][k][l]=JPCGR[j][k][l]-deltaLTD*JPCGR[j][k][l]*dWJ;
DF=1;
}
if(DF==0) {
JPCGR[j][k][l]=JPCGR[j][k][l]+deltaLTP*(JPCGR0-JPCGR[j][k][l]);
}
}
/* No PF firing --> No Plasticity */
}
}
}
}
}
}
/* A routine to integrate the differential equations */
void FLOW()
{
int i,j;
float t0,vGR0[NC+1][NGR+1],vGO0[NC+1],vBC0[NPC+1],vPC0[NPC+1],vVN0,vIO0;
float fvGR1[NC+1][NGR+1],fvGR2[NC+1][NGR+1],fvGO1[NC+1],fvGO2[NC+1];
float fvBC1[NPC+1],fvBC2[NPC+1],fvPC1[NPC+1],fvPC2[NPC+1];
float fvVN1,fvVN2,fvIO1,fvIO2;
t0=(float)RKCNT/SN;
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) vGR0[i][j]=vGR[i][j];
}
for(i=1;i<=NC;i++) vGO0[i]=vGO[i];
for(i=1;i<=NPC;i++) vBC0[i]=vBC[i];
for(i=1;i<=NPC;i++) vPC0[i]=vPC[i];
vVN0=vVN; vIO0=vIO;
t=t0;
F();
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) {
fvGR1[i][j]=fvGR[i][j];
vGR[i][j]=vGR0[i][j]+h*fvGR1[i][j];
}
}
for(i=1;i<=NC;i++) {
fvGO1[i]=fvGO[i];
vGO[i]=vGO0[i]+h*fvGO1[i];
}
for(i=1;i<=NPC;i++) {
fvBC1[i]=fvBC[i];
vBC[i]=vBC0[i]+h*fvBC1[i];
}
for(i=1;i<=NPC;i++) {
fvPC1[i]=fvPC[i];
vPC[i]=vPC0[i]+h*fvPC1[i];
}
fvVN1=fvVN; vVN=vVN0+h*fvVN1;
fvIO1=fvIO; vIO=vIO0+h*fvIO1;
t=t0+h; RKCNT++;
F();
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) {
fvGR2[i][j]=fvGR[i][j];
vGR[i][j]=vGR0[i][j]+h*(fvGR1[i][j]+fvGR2[i][j])/2.;
}
}
for(i=1;i<=NC;i++) {
fvGO2[i]=fvGO[i];
vGO[i]=vGO0[i]+h*(fvGO1[i]+fvGO2[i])/2.;
}
for(i=1;i<=NPC;i++) {
fvBC2[i]=fvBC[i];
vBC[i]=vBC0[i]+h*(fvBC1[i]+fvBC2[i])/2.;
}
for(i=1;i<=NPC;i++) {
fvPC2[i]=fvPC[i];
vPC[i]=vPC0[i]+h*(fvPC1[i]+fvPC2[i])/2.;
}
fvVN2=fvVN; vVN=vVN0+h*(fvVN1+fvVN2)/2.;
fvIO2=fvIO; vIO=vIO0+h*(fvIO1+fvIO2)/2.;
}
/* A routine to return the function values in the differential equations */
void F()
{
int i,j,k,l,m,Idx;
float ILGR,IAHPGR,ILGO,IAHPGO,ILBC,IAHPBC,ILPC,IAHPPC,ILVN,IAHPVN,ILIO,IAHPIO;
float SGRMFAMPA[NC+1][NGR+1],SGRMFNMDA[NC+1][NGR+1],gGRMFAMPASyn,gGRMFNMDASyn,IGRMFAMPASyn,IGRMFNMDASyn;
float SGOGRAMPA[NC+1][NGR+1],SGOGRNMDA[NC+1][NGR+1],gGOGRAMPASyn,gGOGRNMDASyn,IGOGRAMPASyn,IGOGRNMDASyn;
float SGRGOGABA[NC+1],gGRGOGABASyn,IGRGOGABASyn;
float SBCGRAMPA[NC+1][NGR+1],gBCGRAMPASyn,IBCGRAMPASyn;
float SPCGRAMPA[NC+1][NGR+1],gPCGRAMPASyn,IPCGRAMPASyn;
float SPCIOAMPA,gPCIOAMPASyn,IPCIOAMPASyn;
float SPCBCGABA[NPC+1],gPCBCGABASyn,IPCBCGABASyn;
float SVNMFAMPA[NMFVN+1],SVNMFNMDA[NMFVN+1],gVNMFAMPASyn,gVNMFNMDASyn,IVNMFAMPASyn,IVNMFNMDASyn;
float SVNPCGABA[NPC+1],gVNPCGABASyn,IVNPCGABASyn;
float SIOESAMPA,gIOESAMPASyn,IIOESAMPASyn,SIOVNGABA,gIOVNGABASyn,IIOVNGABASyn;
/* Calculate the summation of s[i][j] for MF to GR */
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) {
SGRMFAMPA[i][j]=0.;
for(k=1;k<=NOSPIKEMF[i][j];k++) {
if((t-SPTIMEMF[i][j][k]) > CutOffTimeGRMFAMPA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SGRMFAMPA[i][j]=SGRMFAMPA[i][j]+ALPHA1(t-SPTIMEMF[i][j][k],tauGRMFAMPA);
}
}
}
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) {
SGRMFNMDA[i][j]=0.;
for(k=1;k<=NOSPIKEMF[i][j];k++) {
if((t-SPTIMEMF[i][j][k]) > CutOffTimeGRMFNMDA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SGRMFNMDA[i][j]=SGRMFNMDA[i][j]+ALPHA1(t-SPTIMEMF[i][j][k],tauGRMFNMDA);
}
}
}
/* Calculate the summation of s[i][j] for GR to GO */
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) {
SGOGRAMPA[i][j]=0.;
for(k=1;k<=NOSPIKEGR[i][j];k++) {
if((t-SPTIMEGR[i][j][k]) > CutOffTimeGOGRAMPA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SGOGRAMPA[i][j]=SGOGRAMPA[i][j]+ALPHA1(t-SPTIMEGR[i][j][k],tauGOGRAMPA);
}
}
}
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) {
SGOGRNMDA[i][j]=0.;
for(k=1;k<=NOSPIKEGR[i][j];k++) {
if((t-SPTIMEGR[i][j][k]) > CutOffTimeGOGRNMDA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SGOGRNMDA[i][j]=SGOGRNMDA[i][j]+ALPHA2(t-SPTIMEGR[i][j][k],AGOGRNMDA1,AGOGRNMDA2,tauGOGRNMDA1,tauGOGRNMDA2);
}
}
}
/* Calculate the summation of s[i][j] for GO to GR */
for(i=1;i<=NC;i++) {
SGRGOGABA[i]=0.;
for(j=1;j<=NOSPIKEGO[i];j++) {
if((t-SPTIMEGO[i][j]) > CutOffTimeGRGOGABA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SGRGOGABA[i]=SGRGOGABA[i]+ALPHA2(t-SPTIMEGO[i][j],AGRGOGABA1,AGRGOGABA2,tauGRGOGABA1,tauGRGOGABA2);
}
}
/* Calculate the summation of s[i][j] for GR to BC */
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) {
SBCGRAMPA[i][j]=0.;
for(k=1;k<=NOSPIKEGR[i][j];k++) {
if((t-SPTIMEGR[i][j][k]) > CutOffTimeBCGRAMPA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SBCGRAMPA[i][j]=SBCGRAMPA[i][j]+ALPHA1(t-SPTIMEGR[i][j][k],tauBCGRAMPA);
}
}
}
/* Calculate the summation of s[i][j] for GR to PC */
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) {
SPCGRAMPA[i][j]=0.;
for(k=1;k<=NOSPIKEGR[i][j];k++) {
if((t-SPTIMEGR[i][j][k]) > CutOffTimePCGRAMPA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SPCGRAMPA[i][j]=SPCGRAMPA[i][j]+ALPHA1(t-SPTIMEGR[i][j][l],tauPCGRAMPA);
}
}
}
/* Calculate the summation of s[i][j] for CF to PC */
SPCIOAMPA=0.;
for(i=1;i<=NOSPIKEIO;i++) {
if((t-SPTIMEIO[i]) > CutOffTimePCIOAMPA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SPCIOAMPA=SPCIOAMPA+ALPHA1(t-SPTIMEIO[i],tauPCIOAMPA);
}
/* Calculate the summation of s[i][j] for BC to PC */
for(i=1;i<=NPC;i++) {
SPCBCGABA[i]=0.;
for(j=1;j<=NOSPIKEBC[i];j++) {
if((t-SPTIMEBC[i][j]) > CutOffTimePCBCGABA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SPCBCGABA[i]=SPCBCGABA[i]+ALPHA1(t-SPTIMEBC[i][j],tauPCBCGABA);
}
}
/* Calculate the summation of s[i][j] for MF to VN */
for(i=1;i<=NMFVN;i++) {
SVNMFAMPA[i]=0.;
for(j=1;j<=NOSPIKEMFVN[i];j++) {
if((t-SPTIMEMFVN[i][j]) > CutOffTimeVNMFAMPA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SVNMFAMPA[i]=SVNMFAMPA[i]+ALPHA1(t-SPTIMEMFVN[i][j],tauVNMFAMPA);
}
}
for(i=1;i<=NMFVN;i++) {
SVNMFNMDA[i]=0.;
for(j=1;j<=NOSPIKEMFVN[i];j++) {
if((t-SPTIMEMFVN[i][j]) > CutOffTimeVNMFNMDA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SVNMFNMDA[i]=SVNMFNMDA[i]+ALPHA1(t-SPTIMEMFVN[i][j],tauVNMFNMDA);
}
}
/* Calculate the summation of s[i][j] for PC to VN */
for(i=1;i<=NPC;i++) {
SVNPCGABA[i]=0.;
for(j=1;j<=NOSPIKEPC[i];j++) {
if((t-SPTIMEPC[i][j]) > CutOffTimeVNPCGABA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SVNPCGABA[i]=SVNPCGABA[i]+ALPHA1(t-SPTIMEPC[i][j],tauVNPCGABA);
}
}
/* Calculate the summation of s[i][j] for ES to IO */
SIOESAMPA=0.;
for(i=1;i<=NOSPIKEES;i++) {
if((t-SPTIMEES[i]) > CutOffTimeIOESAMPA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SIOESAMPA=SIOESAMPA+ALPHA1(t-SPTIMEES[i],tauIOESAMPA);
}
/* Calculate the summation of s[i][j] for VN to IO */
SIOVNGABA=0.;
for(i=1;i<=NOSPIKEVN;i++) {
if((t-SPTIMEVN[i]) > CutOffTimeIOVNGABA) break;
/* Spikes in (t-tau_l-CutOffTime)<SPTIME[i][j]<t-tau_l are
considered for the synaptic current. */
SIOVNGABA=SIOVNGABA+ALPHA1(t-SPTIMEVN[i],tauIOVNGABA);
}
/* Governing Eqs. for GR cells */
for(i=1;i<=NC;i++) {
for(j=1;j<=NGR;j++) {
ILGR=gLGR*(vGR[i][j]-VLGR);
if(SPTIMEGR[i][j][1]>0.) IAHPGR=gAHPGR*exp(-(t-SPTIMEGR[i][j][1])/tauAHPGR)*(vGR[i][j]-VAHPGR);
else IAHPGR=0.;
gGRMFAMPASyn=0.;
for(k=i;k<=(i+1);k++) gGRMFAMPASyn=gGRMFAMPASyn+SGRMFAMPA[k][j];
gGRMFAMPASyn=gGRMFAMPA*JGRMF*gGRMFAMPASyn;
IGRMFAMPASyn=gGRMFAMPASyn*(vGR[i][j]-VGRMFSyn);
gGRMFNMDASyn=0.;
for(k=i;k<=(i+1);k++) gGRMFNMDASyn=gGRMFNMDASyn+SGRMFNMDA[k][j];
gGRMFNMDASyn=gGRMFNMDA*JGRMF*gGRMFNMDASyn;
IGRMFNMDASyn=gGRMFNMDASyn*(vGR[i][j]-VGRMFSyn);
gGRGOGABASyn=0.;
for(k=i;k<=(i+1);k++) {
for(l=1;l<=NoPreGLGO[k];m++) {
gGRGOGABASyn=gGRGOGABASyn+SGRGOGABA[IPreGLGO[k][m]];
}
}
gGRGOGABASyn=gGRGOGABA*JGRGO*gGRGOGABASyn;
IGRGOGABASyn=gGRGOGABASyn*(vGR[i][j]-VGRGOSyn);
fvGR[i][j]=(-ILGR-IAHPGR-IGRMFAMPASyn-IGRMFNMDASyn-IGRGOGABASyn)/CGR; /* Note the (1/CGR) coefficient */
}
}
/* Governing Eqs. for GO cells */
for(i=1;i<=NC;i++) {
ILGO=gLGO*(vGO[i]-VLGO);
if(SPTIMEGO[i][1]>0.) IAHPGO=gAHPGO*exp(-(t-SPTIMEGO[i][1])/tauAHPGO)*(vGO[i]-VAHPGO);
else IAHPGO=0.;
gGOGRAMPASyn=0.;
for(j=1;j<=NoPreGOGR[i];j++) {
gGOGRAMPASyn=gGOGRAMPASyn+SGOGRAMPA[IPreGOGR[i][j]][iPreGOGR[i][j]];
}
gGOGRAMPASyn=gGOGRAMPA*JGOGR*gGOGRAMPASyn;
IGOGRAMPASyn=gGOGRAMPASyn*(vGO[i]-VGOGRSyn);
gGOGRNMDASyn=0.;
for(j=1;j<=NoPreGOGR[i];j++) {
gGOGRNMDASyn=gGOGRNMDASyn+SGOGRNMDA[IPreGOGR[i][j]][iPreGOGR[i][j]];
}
gGOGRNMDASyn=gGOGRNMDA*JGOGR*gGOGRNMDASyn;
IGOGRNMDASyn=gGOGRNMDASyn*(vGO[i]-VGOGRSyn);
fvGO[i]=(-ILGO-IAHPGO-IGOGRAMPASyn-IGOGRNMDASyn)/CGO; /* Note the (1/CGO) coefficient */
}
/* Governing Eqs. for BCs */
for(i=1;i<=NPC;i++) {
ILBC=gLBC*(vBC[i]-VLBC);
if(SPTIMEBC[i][1]>0.) IAHPBC=gAHPBC*exp(-(t-SPTIMEBC[i][1])/tauAHPBC)*(vBC[i]-VAHPBC);
else IAHPBC=0.;
gBCGRAMPASyn=0.;
for(j=(NC-143)+(i-1)*64;j<=(NC-143)+(i-1)*64+287;j++) {
if(j<1) Idx=j+NC;
if(j>NC) Idx=j-NC;
for(k=1;k<=NGR;k++) {
gBCGRAMPASyn=gBCGRAMPASyn+SBCGRAMPA[Idx][k];
}
}
gBCGRAMPASyn=gBCGRAMPA*JBCGR*gBCGRAMPASyn;
IBCGRAMPASyn=gBCGRAMPASyn*(vBC[i]-VBCGRSyn);
fvBC[i]=(-ILBC-IAHPBC-IBCGRAMPASyn)/CBC; /* Note the (1/CBC) coefficient */
}
/* Governing Eqs. for PCs */
for(i=1;i<=NPC;i++) {
ILPC=gLPC*(vPC[i]-VLPC);
if(SPTIMEPC[i][1]>0.) IAHPPC=gAHPPC*exp(-(t-SPTIMEPC[i][1])/tauAHPPC)*(vPC[i]-VAHPPC);
else IAHPPC=0.;
gPCGRAMPASyn=0.;
for(j=(NC-143)+(i-1)*64;j<=(NC-143)+(i-1)*64+287;j++) {
if(j<1) Idx=j+NC;
if(j>NC) Idx=j-NC;
for(k=1;k<=NGR;k++) {
gPCGRAMPASyn=gPCGRAMPASyn+SPCGRAMPA[Idx][k];
}
}
gPCGRAMPASyn=gPCGRAMPA*gPCGRAMPASyn;
IPCGRAMPASyn=gPCGRAMPASyn*(vPC[i]-VPCGRSyn);
gPCIOAMPASyn=gPCIOAMPA*JPCIO*SPCIOAMPA;
IPCIOAMPASyn=gPCIOAMPASyn*(vPC[i]-VPCIOSyn);
gPCBCGABASyn=0.;
for(j=(i-1);j<=(i+1);j++) {
if(j<1) Idx=j+NC;
if(j>NC) Idx=j-NC;
gPCBCGABASyn=gPCBCGABASyn+SPCBCGABA[Idx];
}
gPCBCGABASyn=gPCBCGABA*JPCBC*gPCBCGABASyn;
IPCBCGABASyn=gPCBCGABASyn*(vPC[i]-VPCBCSyn);
fvPC[i]=(-ILPC-IAHPPC+IdcPC-IPCGRAMPASyn-IPCIOAMPASyn-IPCBCGABASyn)/CPC; /* Note the (1/CPC) coefficient */
}
/* Governing Eqs. for VN */
ILVN=gLVN*(vVN-VLVN);
if(SPTIMEVN[1]>0.) IAHPVN=gAHPVN*exp(-(t-SPTIMEVN[1])/tauAHPVN)*(vVN-VAHPVN);
else IAHPVN=0.;
gVNMFAMPASyn=0.;
for(i=1;i<=NMFVN;i++) gVNMFAMPASyn=gVNMFAMPASyn+SVNMFAMPA[i];
gVNMFAMPASyn=gVNMFAMPA*JVNMF*gVNMFAMPASyn;
IVNMFAMPASyn=gVNMFAMPASyn*(vVN-VVNMFSyn);
gVNPCGABASyn=0.;
for(i=1;i<=NPC;i++) gVNPCGABASyn=gVNPCGABASyn+SVNPCGABA[i];
gVNPCGABASyn=gVNPCGABA*JVNPC*gVNPCGABASyn;
IVNPCGABASyn=gVNPCGABASyn*(vVN-VVNPCSyn);
fvVN=(-ILVN-IAHPVN+IdcVN-IVNMFAMPASyn-IVNMFNMDASyn-IVNPCGABASyn)/CVN; /* Note the (1/CVN) coefficient */
/* Governing Eqs. for IO */
ILIO=gLIO*(vIO-VLIO);
if(SPTIMEIO[1]>0.) IAHPIO=gAHPIO*exp(-(t-SPTIMEIO[1])/tauAHPIO)*(vIO-VAHPIO);
else IAHPIO=0.;
gIOESAMPASyn=gIOESAMPA*JIOES*SIOESAMPA;
IIOESAMPASyn=gIOESAMPASyn*(vIO-VIOESSyn);
gIOVNGABASyn=gIOVNGABA*JIOVN*SIOVNGABA;
IIOVNGABASyn=gIOVNGABASyn*(vIO-VIOVNSyn);
fvIO=(-ILIO-IAHPIO-IIOESAMPASyn-IIOVNGABASyn)/CIO; /* Note the (1/CIO) coefficient */
}
/* A Routine to find the cut-off time of the alpha function
for the local synapse by using the bisection method */
float CutOff1(float tau)
{
float XT,XL,XC,XR,FTN,FTNC;
XT=0.;
do{
XT=XT+0.01;
FTN=ALPHA1(XT,tau);
}while(FTN>ALPHAbound);
/* For t=XL (or t=XR), the double exponential function > (or <) DEbound. */
XL=XT-0.1; XR=XT;
/* Find the cut-off time by using bisection method */
do{
XC=(XL+XR)/2.;
FTNC=ALPHA1(XC,tau)-ALPHAbound;
if(FTNC>0.) XL=XC;
else XR=XC;
}while((XR-XL)>CutOffTimebound);
XC=XT;
return XC;
}
/* A Routine to find the cut-off time of the alpha function
for the local synapse by using the bisection method */
float CutOff2(float A1, float A2, float tau1, float tau2)
{
float XT,XL,XC,XR,FTN,FTNC;
XT=0.;
do{
XT=XT+0.01;
FTN=ALPHA2(XT,A1,A2,tau1,tau2);
}while(FTN>ALPHAbound);
/* For t=XL (or t=XR), the double exponential function > (or <) DEbound. */
XL=XT-0.1; XR=XT;
/* Find the cut-off time by using bisection method */
do{
XC=(XL+XR)/2.;
FTNC=ALPHA2(XC,A1,A2,tau1,tau2)-ALPHAbound;
if(FTNC>0.) XL=XC;
else XR=XC;
}while((XR-XL)>CutOffTimebound);
XC=XT;
return XC;
}
/* A Routine to return the value of the alpha function for the local synaptic current */
float ALPHA1(float t, float tau)
{
float alp1;
alp1=exp(-t/tau);
return alp1;
}
/* A Routine to return the value of the alpha function for the local synaptic current */
float ALPHA2(float t, float A1, float A2, float tau1, float tau2)
{
float alp1;
alp1=A1*exp(-t/tau1)+A2*exp(-t/tau2);
return alp1;
}
/* A routine to generate a uniform random number on (0,1)
using the C-supplied rand function */
float UniRandom()
{
float R;
R=((float) rand()+1.)/((float) RAND_MAX+2.);
return R;
}