Cerebellar Model for the Optokinetic Response (Kim and Lim 2021)

 Download zip file 
Help downloading and running models
Accession:267334
We consider a cerebellar spiking neural network for the optokinetic response (OKR). Individual granule (GR) cells exhibit diverse spiking patterns which are in-phase, anti-phase, or complex out-of-phase with respect to their population-averaged firing activity. Then, these diversely-recoded signals via parallel fibers (PFs) from GR cells are effectively depressed by the error-teaching signals via climbing fibers from the inferior olive which are also in-phase ones. Synaptic weights at in-phase PF-Purkinje cell (PC) synapses of active GR cells are strongly depressed via strong long-term depression (LTD), while those at anti-phase and complex out-of-phase PF-PC synapses are weakly depressed through weak LTD. This kind of ‘‘effective’’ depression at the PF-PC synapses causes a big modulation in firings of PCs, which then exert effective inhibitory coordination on the vestibular nucleus (VN) neuron (which evokes OKR). For the firing of the VN neuron, the learning gain degree, corresponding to the modulation gain ratio, increases with increasing the learning cycle, and it saturates.
Reference:
1 . Kim SY, Lim W (2021) Effect of Diverse Recoding of Granule Cells on Optokinetic Response in A Cerebellar Ring Network with Synaptic Plasticity Neural Networks 134:173-204
Citations  Citation Browser
Model Information (Click on a link to find other models with that property)
Model Type: Realistic Network; Spiking neural network;
Brain Region(s)/Organism: Cerebellum;
Cell Type(s): Cerebellum interneuron granule GLU cell; Cerebellum interneuron Golgi GABA cell; Cerebellum Purkinje GABA cell; Inferior olive neuron; Vestibular nucleus neuron;
Channel(s):
Gap Junctions:
Receptor(s): AMPA; NMDA; Gaba;
Gene(s):
Transmitter(s): Glutamate; Gaba;
Simulation Environment: C or C++ program;
Model Concept(s): Learning; Sensory processing; Effective Optokinetic Response (OKR);
Implementer(s): Kim, Sang-Yoon; Lim, Woochang;
Search NeuronDB for information about:  Cerebellum Purkinje GABA cell; Cerebellum interneuron granule GLU cell; Cerebellum interneuron Golgi GABA cell; AMPA; NMDA; Gaba; Gaba; Glutamate;
/
OKR
README.txt
CI.c
IPSR.c
raster_plot.c
                            
/* 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;
}