Increased computational accuracy in multi-compartmental cable models (Lindsay et al. 2005)

 Download zip file   Auto-launch 
Help downloading and running models
Accession:129149
Compartmental models of dendrites are the most widely used tool for investigating their electrical behaviour. Traditional models assign a single potential to a compartment. This potential is associated with the membrane potential at the centre of the segment represented by the compartment. All input to that segment, independent of its location on the segment, is assumed to act at the centre of the segment with the potential of the compartment. By contrast, the compartmental model introduced in this article assigns a potential to each end of a segment, and takes into account the location of input to a segment on the model solution by partitioning the effect of this input between the axial currents at the proximal and distal boundaries of segments. For a given neuron, the new and traditional approaches to compartmental modelling use the same number of locations at which the membrane potential is to be determined, and lead to ordinary differential equations that are structurally identical. However, the solution achieved by the new approach gives an order of magnitude better accuracy and precision than that achieved by the latter in the presence of point process input.
Reference:
1 . Lindsay AE, Lindsay KA, Rosenberg JR (2005) Increased computational accuracy in multi-compartmental cable models by a novel approach for precise point process localization. J Comput Neurosci 19:21-38 [PubMed]
Model Information (Click on a link to find other models with that property)
Model Type: Neuron or other electrically excitable cell;
Brain Region(s)/Organism:
Cell Type(s):
Channel(s): I Na,t; I K;
Gap Junctions:
Receptor(s):
Gene(s):
Transmitter(s):
Simulation Environment: NEURON; C or C++ program;
Model Concept(s): Methods;
Implementer(s):
Search NeuronDB for information about:  I Na,t; I K;
/
LindsayEtAl2005
readme.txt
03-192.pdf
AnalyseResults.c
BitsAndPieces.c
CellData.dat
CompareSpikeTrain.c
Ed04.tex
ExactSolution.dat
GammaCode
Gen.tex
Gen1.tex
Gen2.tex
Gen3.tex
Gen4.tex
Gen5.tex
Gen6.tex
GenCom.c
GenCom1.c
GenCom2.c
GenComExactSoln.c
GenerateInput.c
GenerateInputText.c
GenRan.ran
GetNodeNumbers.c
Info100.dat
Info20.dat
Info200.dat
Info30.dat
Info300.dat
Info40.dat
Info400.dat
Info50.dat
Info500.dat
Info60.dat
Info70.dat
Info80.dat
Info90.dat
InputCurrents.dat
InputDendrite.dat
JaySpikeTrain.c
JayTest1.dat
JayTest100.dat
KenSpikeTrain.c
KenTest1.dat *
KenTest10.dat
KenTest100.dat *
KenTest10p.dat
KenTest1p.dat *
KenTest2.dat
KenTest2p.dat
KenTest3.dat
KenTest3p.dat
KenTest4.dat
KenTest4p.dat
KenTest5.dat
KenTest5p.dat
KenTest6.dat
KenTest6p.dat
KenTest7.dat
KenTest7p.dat
KenTest8.dat
KenTest8p.dat
KenTest9.dat
KenTest9p.dat
LU.c
Mean50.dat
Mean500.dat
mosinit.hoc
NC.pdf
NC.tex
NC1.tex
NC2.tex
NC3.tex
NC4.tex
NC5.tex
NC6.tex
NCFig2.eps *
NCFig3.eps *
NCFig4.eps *
NCFig5a.eps *
NCFig5b.eps *
NCFig6.eps *
NCPics.tex
NeuronDriver.hoc
NewComExactSoln.c
NewComp.pdf
NewComp.ps
NewComp.tex
NewComp.toc
NewComp1.tex
NewComp2.tex
NewComp3.tex
NewComp4.tex
NewComp5.tex
NewComp6.tex
NewCompFig1.eps
NewCompFig2.eps *
NewCompFig3.eps *
NewCompFig4.eps *
NewCompFig5a.eps *
NewCompFig5b.eps *
NewCompFig6.eps *
NewCompPics.tex
NewComSpikeTrain.c
NewRes.dat
NewRes60.dat
NewRes70.dat
NewRes80.dat
NewSynRes40.dat
NewTestCell.d3
NResults.res
OldComExactSoln.c
out.res
principles_01.tex
rand
Ratio.dat
RelErr.dat
ReviewOfSpines.pdf
SpikeTimes.dat
TestCell.d3
TestCell1.d3
TestCell2.d3
TestCell3.d3
TestCell4.d3
testcellnew2.hoc
TestCGS.c
TestGen1.c
TestSim.hoc
TestSim020.hoc
TestSim030.hoc
TestSim040.hoc
TestSim050.hoc
TestSim060.hoc
TestSim070.hoc
TestSim080.hoc
TestSim090.hoc
TestSim1.hoc
TestSim100.hoc
TestSim200.hoc
TestSim300.hoc
TestSim400.hoc
TestSim500
TestSim500.hoc
                            
typedef struct cond_t {
        int n;               /* No. timesteps in conductance profile */
        double dt;           /* Integration time step (msecs) */
        double *g;           /* Conductance profile for prescribed dt (mu a) */
        double tol;          /* Determines off-threshold for synapse */
        double tau;          /* Rise time for synapse (msecs) */
        double gmax;         /* Peak conductance per synapse (mu) */
} cond;

typedef struct synapse_t
{
        cond *cp;            /* Pointer to profile of synaptic conductance */
        int ind;             /* Indicator of status of synapse */
        int max;             /* Maximum value of status counter */
        double gold;         /* Previous synaptic conductance */
        double vsyn;         /* Reversal potential of synapse (mV) */
} synapse;

void cgs(int, sparse_mat *, double *, double *, double *, double),
     FreeConductanceProfile( cond *),
     UpdateSynapticConductance( synapse *syn);
cond *ConductanceProfile( double, double, double, double);
synapse *SynapticProfile( int, int, double, double, double, cond * );
double c_in(synapse *, long int);

/* Declaration of HH coefficient functions */
double alfa_h( double );
double alfa_m( double );
double alfa_n( double );
double beta_h( double );
double beta_m( double );
double beta_n( double );

double temperature_correction;


 /********************************************
        Computes a conductance profile
  ********************************************/
cond *ConductanceProfile( double dt,   /* Integration time step */
                          double tau,  /* Synaptic time constant */
                          double tol,  /* Determines off-threshold for synapse */
                          double gmax  /* Maximum conductance (mS) */ )
{
    int k;
    cond *con;
    double tmp, told, tnew;

    con = (cond *) malloc( sizeof(cond) );
    con->dt = dt;
    con->tau = tau;
    con->tol = tol;
    con->gmax = gmax;

/* Iterate to find duration of pulse */
    tmp = 1.0-log(tol);
    tnew = tmp;
    do {
        told = tnew;
        tnew = tmp+log(told);
    } while ( fabs(tnew-told)>5.e-11 );
    con->n = ((int) ceil(tau*tnew/dt));
    con->g = (double *) malloc( (con->n)*sizeof(double) );
    con->g[0] = 0.0;
    for ( k=1 ; k<(con->n) ; k++ ) {
        tmp = dt*((double) k)/tau;
        con->g[k] = gmax*tmp*exp(1.0-tmp);
    }
    return con;
}


 /********************************************
     Function to free a conductance profile
  ********************************************/
void FreeConductanceProfile( cond *con)
{
    free(con->g);
    free(con);
    return;
}


 /*******************************************************
    Function to initialise and update synaptic activity
  *******************************************************/
void UpdateSynapticConductance( synapse *syn)
{
    extern unsigned long int ix, iy, iz;
    static double RealRate;
    static int start=1;
    int j, k;
    double deadtime, dt, interval;

/*  Step 1. - Initialise synapse */
    if ( start ) {
        if ( syn->cp ) {
            dt = (syn->cp->dt);
            syn->max = syn->cp->n;
            syn->gold = 0.0;
            deadtime = ((double) syn->cp->n)*dt;
            RealRate = (1000.0/RATE)-deadtime;
            if ( RealRate <= 0.0 ) {
                printf("\nImpossible firing rate requested\n");
                fflush(stdout);
                return NULL;
            }
            interval = -RATE*log(ran( &ix, &iy, &iz))/dt;
            if ( fmod(interval,1.0) <= 0.5 ) {
               syn->ind = -((int) floor(interval));
            } else {
               syn->ind = -((int) ceil(interval));
            }
        } else {
            printf("\nSynapse has no conductance profile!\n");
            return NULL;
        }
        start =0;
    } else {
        (syn->ind)++;
        if ( syn->ind == syn->max ) {
            dt = (syn->cp->dt);
            syn->gold = 0.0;
            interval = -RealRate*log(ran( &ix, &iy, &iz))/dt;
            if ( fmod(interval,1.0) <= 0.5 ) {
               syn->ind = -((int) floor(interval));
            } else {
               syn->ind = -((int) ceil(interval));
            }
        }
    }
    return;
}



 /********************************************************************
                    ALPHA for ACTIVATION OF SODIUM
  *******************************************************************/
double alfa_m( double volt )
{
    extern double temperature_correction;
    double tmp;

    tmp = 2.5-0.1*volt;
    if ( fabs(tmp)<0.001 ) {
        tmp = 1.0/(((tmp/24.0+1.0/6.0)*tmp+0.5)*tmp+1.0);
    } else {
        tmp = tmp/(exp(tmp)-1.0);
    }
    return tmp*temperature_correction;
}


 /********************************************************************
                    BETA for ACTIVATION OF SODIUM
  ********************************************************************/
double beta_m( double volt )
{
    extern double temperature_correction;
    double tmp;

    tmp = volt/18.0;
    return 4.0*temperature_correction*exp(-tmp);
}


 /********************************************************************
                    ALPHA for INACTIVATION OF SODIUM
  ********************************************************************/
double alfa_h( double volt )
{
    extern double temperature_correction;
    double tmp;

    tmp = 0.05*volt;
    return 0.07*temperature_correction*exp(-tmp);
}


 /********************************************************************
                    BETA for INACTIVATION OF SODIUM
  ********************************************************************/
double beta_h( double volt )
{
    extern double temperature_correction;
    double tmp;

    tmp = 3.0-0.1*volt;
    return temperature_correction/(exp(tmp)+1.0);
}


 /********************************************************************
                    ALPHA for ACTIVATION OF POTASSIUM
  ********************************************************************/
double alfa_n( double volt )
{
    extern double temperature_correction;
    double tmp;

    tmp = 1.0-0.1*volt;
    if ( fabs(tmp)<0.001 ) {
        tmp = 0.1/(((tmp/24.0+1.0/6.0)*tmp+0.5)*tmp+1.0);
    } else {
        tmp = 0.1*tmp/(exp(tmp)-1.0);
    }
    return tmp*temperature_correction;
}


 /********************************************************************
                    BETA for ACTIVATION OF POTASSIUM
  ********************************************************************/
double beta_n( double volt )
{
    extern double temperature_correction;
    double tmp;

    tmp = 0.0125*volt;
    return 0.125*temperature_correction*exp(-tmp);
}



void cgs(int getmem, sparse_mat *a, double *b, double *x0, double *x, double tol)
{
    long int i, k, n, finish;
    static int start=1;
    double rho_old, rho_new, alpha, beta, sigma, err;
    static double *p, *q, *u, *v, *r, *rb, *y;

/* Step 1 - Check memory status */
    n = a->n;
    if ( start ) {
        r = (double *) malloc( n*sizeof(double) );
        rb = (double *) malloc( n*sizeof(double) );
        p = (double *) malloc( n*sizeof(double) );
        q = (double *) malloc( n*sizeof(double) );
        u = (double *) malloc( n*sizeof(double) );
        v = (double *) malloc( n*sizeof(double) );
        y = (double *) malloc( n*sizeof(double) );
        start = 0;
    }

/* Step 2 - Initialise residual, p[ ] and q[ ] */
    mat_vec_mult( a, x0, r);
    for ( rho_old=0.0,i=0 ; i<n ; i++ ) {
        r[i] = b[i]-r[i];
        rho_old += r[i]*r[i];
        rb[i] = r[i];
        p[i] = 0.0;
        q[i] = 0.0;
    }
    if ( rho_old<tol*((double) n) ) {
        for ( i=0 ; i<n ; i++ ) x[i] = x0[i];
        return;
    }
    rho_old = 1.0;
    finish = 0;

/* The main loop */
    while ( !finish ) {

/* Compute scale parameter for solution update */
        for ( rho_new=0.0,i=0 ; i<n ; i++ ) rho_new += r[i]*rb[i];
        beta = rho_new/rho_old;

/* Update u[ ] and p[ ] */
        for ( i=0 ; i<n ; i++ ) {
            u[i] = r[i]+beta*q[i];
            p[i] = u[i]+beta*(q[i]+beta*p[i]);
        }

/* Update v[ ] and compute sigma */
        mat_vec_mult( a, p, v);
        for ( sigma=0.0,i=0 ; i<n ; i++ ) sigma += rb[i]*v[i];

/* Compute alpha and update q[ ], v[ ] and x[ ] */
        alpha = rho_new/sigma;
        for ( i=0 ; i<n ; i++ ) {
            q[i] = u[i]-alpha*v[i];
            v[i] = alpha*(u[i]+q[i]);
            x[i] += v[i];
        }

 /* Update r[ ] and estimate error */
        mat_vec_mult( a, v, y);
        for ( err=0.0,i=0 ; i<n ; i++ ) {
            r[i] -= y[i];
            err += r[i]*r[i];
        }
        rho_old = rho_new;
        if ( err<tol*((double) n) ) finish = 1;
    }

/* Check memory status */
    if ( getmem<=0 ) start = 1;
    if ( start ) {
        free(r);
        free(rb);
        free(p);
        free(q);
        free(u);
        free(v);
        free(y);
    }
    return;
}

/**********************************************************
                Returns Gaussian deviate
  **********************************************************/
double normal( double mean, double sigma)
{
    static int start=1;
    long int n;
    static double g1, g2;
    double v1, v2, w, ran(long int *);

    if ( start ) {
        n = 1;
        do {
            v1 = 2.0*ran(&n)-1.0;
            v2 = 2.0*ran(&n)-1.0;
            w = v1*v1+v2*v2;
        } while ( w==0.0 || w>=1.0 );
        w = log(w)/w;
        w = sqrt(-w-w);
        g1 = v1*w;
        g2 = v2*w;
        start = !start;
        return (mean+sigma*g1);
    } else {
        start = !start;
        return (mean+sigma*g2);
    }
}

 /**********************************************************
         Order integers in ascending order by heapsort
  **********************************************************/
void heapsort( long int n, long int *x)
{
    int finish;
    long int i, ir, j, k, tmp;

    if ( n<2 ) return;
    k = n/2;
    ir = n-1;
    finish = 0;
    while ( !finish ) {
        if ( k>0 ) {
            tmp = x[--k];
        } else {
            tmp = x[ir];
            x[ir] = x[0];
            if ( --ir==0 ) {
                x[0] = tmp;
                finish = 1;
            }
        }
        i = k;
        j = 2*k+1;
        while ( j<=ir ) {
            if ( j<ir && x[j]<x[j+1] ) j++;
            if ( tmp<x[j] ) {
                x[i] = x[j];
                i = j;
                j = 2*j+1;
            } else {
                j = ir+1;
            }
        }
        x[i] = tmp;
    }
    return;
}

Loading data, please wait...