Feedforward heteroassociative network with HH dynamics (Lytton 1998)

 Download zip file   Auto-launch 
Help downloading and running models
Accession:7399
Using the original McCulloch-Pitts notion of simple on and off spike coding in lieu of rate coding, an Anderson-Kohonen artificial neural network (ANN) associative memory model was ported to a neuronal network with Hodgkin-Huxley dynamics.
Reference:
1 . Lytton WW (1998) Adapting a feedforward heteroassociative network to Hodgkin-Huxley dynamics. J Comput Neurosci 5:353-64 [PubMed]
Model Information (Click on a link to find other models with that property)
Model Type: Realistic Network;
Brain Region(s)/Organism: Hippocampus;
Cell Type(s):
Channel(s): I Na,t; I K;
Gap Junctions:
Receptor(s): GabaA; AMPA;
Gene(s):
Transmitter(s):
Simulation Environment: NEURON;
Model Concept(s): Pattern Recognition; Temporal Pattern Generation; Spatio-temporal Activity Patterns; Simplified Models; Attractor Neural Network;
Implementer(s): Lytton, William [billl at neurosim.downstate.edu];
Search NeuronDB for information about:  GabaA; AMPA; I Na,t; I K;
/
lytton98
README
AMPA.mod
GABAA.mod
kdr.mod
matrix.mod *
misc.mod.orig
naf.mod *
passiv.mod *
precall.mod
pregen.mod *
pregencv.mod
pulsecv.mod
sinstim.mod *
vecst.mod
bg.inc *
boxes.hoc *
declist.hoc *
decvec.hoc *
default.hoc *
directory
fig5.gif
grvec.hoc
init.hoc
labels.hoc
loadr.hoc *
local.hoc *
mosinit.hoc *
net.hoc
nrnoc.hoc *
params.hoc
presyn.inc
proc.hoc
run.hoc
simctrl.hoc *
sns.inc *
snsarr.inc
snscode.hoc
snshead.inc *
spkts.hoc
tmpl.hoc
xtmp
                            
// $Id: snscode.hoc,v 1.42 2002/04/22 14:17:48 billl Exp $
// handles coding, syn assignment and syn graphics

// load_file("declist.hoc","declist")
load_proc("declist")
objref prelist  // list of all presynaptic mechanisms
prelist = new List("PRESYN")

//* CODE GENERATION AND RECOVERY 

objref snsgrlist
snsgrlist = new List()

chainlen = 1    // allow the user to change this as needed for synfind or connmat
maxflds = 4     // maximum number of codefields
cdflds = 4      // number of 'code fields'
double cdsep[maxflds+1] // code column separators
// default values see mkfields() call below
// cdsep[0] = 1e9  col 9 - 9
// cdsep[1] = 1e8  col 8 - 7
// cdsep[2] = 1e6  col 6 - 4
// cdsep[3] = 1e3  col 3 - 1
// cdsep[4] = 1e0

// labels can be entered for each of 4 fields, up to 8 labels in each
objref cdlbls[cdflds][8]
for ii=0,cdflds-1 for jj=0,7 cdlbls[ii][jj]=new String("")

//** mkfields() creates up to 4 fields (5 args: # fields, f1,f2,f3,f4)
// eg mkfields(4,1,2,3,3) to recreate the defaults
proc mkfields() { local sum,i
  cdflds = $1
  cdsep[4] = 1
  sum = $5
  cdsep[3] = 10 ^ sum
  sum = sum + $4
  cdsep[2] = 10 ^ sum
  sum = sum + $3
  cdsep[1] = 10 ^ sum
  sum = sum + $2
  cdsep[0] = 10 ^ sum
}

mkfields(4,1,2,3,3)

//** mkmkcode(): create the mkcode routine
// no arguments, should follow mkfields()
// not reliable if used under xopen()
proc mkmkcode() { local i
  printf("!{!\n")  
  printf("func mkcode() { \nreturn ")
  for (i=1;i<=cdflds;i=i+1) {
    printf("$%d*cdsep[%d] + ",i,i+maxflds-cdflds)
  }
  printf("0 \n}\n")
  printf("!}!\n")  
}

//** mkcode() creates a code of 9 cols in 4 fields, sized 1,2,3,3
func mkcode() { 
  // standard 9 cols
  // divide into 4 fields of size 1,2,3,3
  //col           8           7,6         5,4,3         2,1,0
  return $1*cdsep[1] + $2*cdsep[2] + $3*cdsep[3] + $4*cdsep[4]
}

//** cd(i,code) returns field i (1-4) from code
// $1 field number (from 1), $2 code
func cd() { local temp
  temp = ($2%cdsep[$1+(maxflds-cdflds)-1]) // remove the left side
  return int(temp/cdsep[$1+(maxflds-cdflds)])  // remove the right side
}

//** setcd(i,code,new) replaces field i (1-4) from code with new
// $1 field number (1 offset), $2 code, $3 new value
func setcd() { local temp, old
  temp = ($2%cdsep[$1+(maxflds-cdflds)-1]) // remove the left side
  old = cdsep[$1+(maxflds-cdflds)]* int(temp/cdsep[$1+(maxflds-cdflds)])
  return $2 - old + $3* cdsep[$1+(maxflds-cdflds)]
}

//** prcode(code) prints a code in readable form
// print a code of 9 cols in 4 fields, sized 1,2,3,3
proc prcode() { local i
  for (i=(maxflds-cdflds+1);i<maxflds;i=i+1) {
    printf("%d,",cd(i,$1))
  }
  printf("%d\n",cd(maxflds,$1))
}

//** prlbls(code) uses cdlbls to print out strings instead of numbers
//   when possible
proc prlbls() { local k,cde
  for (k=(maxflds-cdflds+1);k<=maxflds;k=k+1) {
    cde = cd(k,$1)
    if (k < cdflds && cde < 8) {
      if (strcmp(cdlbls[k][cde].s,"") == 0) {
        printf("%d,",cde)
      } else {
        printf("%s,",cdlbls[k][cde].s)
      }
    } else {
      printf("%d,",cde)
    }
  }
  print ""
}

//** chkpre(OBJ,CODE) searches through a syn OBJECT for this CODE
// check whether a code to be included has already been used
// 2 arguments: syn obj, comparison
// returns 1 if found, 0 if not
func chkpre () { local i
  for(i=0; i<$o1.nsyn; i=i+1) {     
    if ($o1.pre(i) == $2){ 
       return 1 } } 
  return 0 
} 

//** synfind list1 cd2 fld3 val4 cd5 fld6 val7
// print out codes on all the synapses that criteria
// cd2, cd5 are "pre" or "post" or "code"
// fld3, fld6 is the field
// val4, val7 are the values to look for matching
proc synfind () { local cdx,cdy,i,j,start
  if ((cdx = connmat_findstr($s2)) == -1) { printf("unknown string %s",$s2) return }
  if ((cdy = connmat_findstr($s5)) == -1) { printf("unknown string %s",$s5) return }
  for i=0,$o1.count-1 {
    for (j=0;j<$o1.object(i).nsyn-1;j=j+chainlen) {
      if (synmatch($o1.object(i),j,cdx,$3,$4,cdy,$6,$7)) {
        sprint(temp_string_,"pr = %s.pre(%d)",$o1.object(i),j)
        execute(temp_string_)
        printf("%s syn# %d: pre==",$o1.object(i),j)
        prlbls(pr)
        sprint(temp_string_,"pr = %s.post(%d)",$o1.object(i),j)
        execute(temp_string_)
        printf(" post==")
        prlbls(pr)
        print ""
      }
    }
  }
}

//*** synmatch obj1 ind2 cf3 fld4 val5 cf6 fld7 val8
// check object fields for matches to values given
func synmatch () { local cdd, cde, i, j
  cdd = connmat_newpt($o1,$3,$4,$2,0)
  cde = connmat_newpt($o1,$6,$7,$2,0)
  if (cdd == $5 && cde == $8) { return 1 } else { return 0 }
}

// parse the strings and return a number telling which it is
// 0:code, 1:pre, 2:post, 3:increment
func connmat_findstr () {
         if (strcmp($s1,"code") == 0) { return 0
  } else if (strcmp($s1,"pre")  == 0) { return 1
  } else if (strcmp($s1,"post") == 0) { return 2
  } else if (strcmp($s1,"inc")  == 0) { return 3
  } else {                              return -1 }
}

// look at return the field needed from the correct word
// word indication as returned by connmat_findstr()
// args: object, word, field, synnum, ind
func connmat_newpt () { local code
         if ($2==0) { code = $o1.code($4)
  } else if ($2==1) { code = $o1.pre($4)
  } else if ($2==2) { code = $o1.post($4)
  } else if ($2==3) { return $5 }
  if (code >= 0) {
    return cd($3,code)
  } else {
    return -1   // error
  }
}

//* FUNCTIONS OPERATING ACROSS ALL PRESYNS 

//** checksyns() goes through prelist and prints out divergence value
proc checksyns() { local i
  for i=0, prelist.count()-1 {
    printf("%d ",prelist.object(i).check())
  }
}

//** cleansyns() goes through prelist and collapses the synapse list
proc cleansyns() { local i
  for i=0, prelist.count()-1 {
    prelist.object(i).clean()
  }
}

//** clearsyns() goes through postsyn list and reinitializes everything
proc clearsyns() { local i,j
  tmplist.remove_all
  tmplist = new List("POSTSYN")
  for i=0, tmplist.count()-1 {
    for j=0, tmplist.object(i).mech_num - 1 {
      if (tmplist.object(i).mech[j].maxsyn > 0) {
        tmplist.object(i).mech[j].init_arrays(tmplist.object(i).mech[j].maxsyn)
      }
    }
  }
  cleansyns()
}

//* SYNAPSE ASSIGNMENT CODE 
// con=absolute convergence number, div=absolute div number
// con = %con * pre
// div * pre = con * post = S (total synapses)
// %div = div/post = S/(pre*post) = con/pre = %con
// div = %con * post
// maxdiv = int((1 + var) * div)

//** ranverge() produces randomized convergence
// used for convergence, rancon (randomized convergence) is given by 
//     ranverge(%conv,numpre,variance)
// returns a convergence number (number of syns onto a cell)
// that is randomly chosen from (%conv +/- variance)*pre
// if random not wanted just do int(pcon * numpre) instead
func ranverge () { local min, max, ran, pcon, numpre, var
  pcon = $1  numpre = $2  var = $3
  if (pcon == 1) { return numpre } // fully connected
  if (pcon == 0) { return 0 }      // no connection
  if (var != 0) {
    ran = pcon - var + (u_rand() * 2 * var)
  } else { ran = pcon }           // no variability
  return int(ran * numpre + u_rand())  // con * pre or div * post rounded up or down
}

//** pickpre() tries to reduce divergence variance
// pickpre(MECH_NUM,TEMP_PRELIST,MAXDIV)
// may want to create TEMP_PRELIST from PRELIST using sublist()
// maxdiv == -1 means to ignore divergence
// MUST do divvec.resize() and divvec.fill(0) before using
objref divvec,divvec1  // vectors to count how much div is from each nrn
divvec = new Vector(100)
divvec1 = new Vector(100) // a scratch vector

func pickpre () { local ran, maxdiv, maxpre, min, indx, mechnum
  mechnum = $1
  maxdiv = $3  // max divergence to be allowed
  maxpre = $o2.count-1 // number of presyn choices
  if (maxdiv == -1) { // just choose one randomly
    ran = fran(0,maxpre) // all possible synapses
    return ran
  }
  maxdiv *= mechnum  // need space for mult mechs together
  // if (divvec.size != prelist.size) { 
  //   printf("Pickpre full ERROR: divvec not sized properly\n") }
  min = divvec.min  // divvec should start all 0's
  if (min >= maxdiv) { // all full up
    printf("Pickpre full WARNING: %d %d\n",min,maxdiv)
    divvec.printf
  }
  divvec1.indvwhere(divvec,"==",min)  // look for all the smallest to fill up first
  ran = fran(0,divvec1.size-1) // pick index of one of these randomly
  indx = divvec1.x[ran]  // index is the randomly chosen entry in vec of ptrs.
  divvec.x[indx] += mechnum  // record that this one has been chosen
  return indx
}

// check that divergence in individual divvecs is same as divergence in PRESYN structure
// chkdiv(vec,PRELISTmin,PRELISTmax,num_mechs)
// vec is specific divergence vector
// PRELISTmin,max give the entries in prelist to compare
// num gives the number of mechanisms in a single post from this cell
proc chkdiv () { local min,max,num
  min = $2 max = $3
  if ($o1.size != max-min+1) { 
    printf("ERROR: divvec size must = # of prelist items: %d %d\n",$o1.size,max-min+1)
    return
  }
  for vtr(&x,$o1) {
    if (x != prelist.object(min+i1).nsyn) {
      printf("ERROR: %d in %s != nsyn %d\n",x,$o1,prelist.object(min+i1).nsyn)
    }
  }
}

//* template POSTSYN 

proc callback () {}

begintemplate POSTSYN
  public mech, mech_num, post
  public init_arrays, augment_array, conn
  public up
  external pickpre, callback
  objref mech[1],this,up	// to be resized later 

//** init() args are syn objects
  proc init() { 
    mech_num = numarg()
    objectvar mech[mech_num]
    if (mech_num >= 4) { mech[3] = $o4 }
    if (mech_num >= 3) { mech[2] = $o3 }
    if (mech_num >= 2) { mech[1] = $o2 }
    if (mech_num >= 1) { mech[0] = $o1 }
  }

//** augment_array() add $1 to current number of synapses
  func augment_array() { 
    num = $1
    for k=0,mech_num-1 {
      newmax = mech[k].maxsyn + num
      mech[k].init_arrays(newmax)
    }
    return newmax
  }
    

//** init_arrays() initialize all mechs to maxsyn = $1
  func init_arrays() { 
    num = $1
    for k=0,mech_num-1 {
      mech[k].init_arrays(num)
    }
    return num
  }

//** conn() find some places in a list to connect to
  // (list, con, maxdiv, [delay, gmax])
  // maxdiv == -1 means to ignore divergence
  func conn () {
    con = $2 maxdiv = $3
    numpre = $o1.count
    if (numarg()>3) {delay = $4  gmax = $5 setall=1 
    } else { setall = 0 }
    for j=0,con-1 { 
      if (con == numpre) {  // do all of them in order
        rannum = j
      } else {
        rannum = pickpre(mech_num,$o1,maxdiv)
        if (rannum==-1) { printf(": %d/%d done\n",j,con)
          return -1 }
      }
      for k=0,mech_num-1 {
        // post, pre, listcnt, syncnt, mechcnt, precnt
        mech[k].setlink($o1.object(rannum).link)
        if (setall) {
          mech[k].delay(-1,delay) // set most recent (index nsyn-1)
          mech[k].gmax(-1,gmax)
        } else {
          callback(mech[k],k,rannum)
        }
      }
    } 
    return 0
  }

endtemplate POSTSYN

Lytton WW (1998) Adapting a feedforward heteroassociative network to Hodgkin-Huxley dynamics. J Comput Neurosci 5:353-64[PubMed]

References and models cited by this paper

References and models that cite this paper

Anderson JA (1972) A simple neural network generating an interactive memory Math Biosci 14:197-220

Anderson JA, Rosenfeld E (1988) Neurocomputing: Foundations Of Research

Barkai E, Bergman RE, Horwitz G, Hasselmo ME (1994) Modulation of associative memory function in a biophysical simulation of rat piriform cortex. J Neurophysiol 72:659-77 [Journal] [PubMed]

Borg-graham L (1991) Modelling the non-linear conductances of excitable membranes Cellular Neurobiology: A Practical Approach, Wheal CHADJ&HV, ed. pp.247

Buckmaster PS, Schwartzkroin PA (1995) Interneurons and inhibition in the dentate gyrus of the rat in vivo. J Neurosci 15:774-89 [PubMed]

Bullock TH (1993) Integrative systems research on the brain: resurgence and new opportunities. Annu Rev Neurosci 16:1-15 [PubMed]

Bullock TH (1997) Signals and signs in the nervous system: the dynamic anatomy of electrical activity is probably information-rich. Proc Natl Acad Sci U S A 94:1-6 [PubMed]

Celebrini S, Thorpe S, Trotter Y, Imbert M (2001) Dynamics of orientation coding in area V1 of the awake primate. Vis Neurosci 10:811-25 [PubMed]

Damasio AR (1990) Category-related recognition defects as a clue to the neural substrates of knowledge. Trends Neurosci 13:95-8 [PubMed]

deCharms RC, Merzenich MM (1996) Primary cortical representation of sounds by the coordination of action-potential timing. Nature 381:610-3 [PubMed]

Destexhe A, Mainen Z, Sejnowski TJ (1994) An efficient method for computing synaptic conductances based on a kinetic model of receptor binding Neural Comput 6:14-18 [Journal]

   Efficient Method for Computing Synaptic Conductance (Destexhe et al 1994) [Model]
   Kinetic synaptic models applicable to building networks (Destexhe et al 1998) [Model]
   Application of a common kinetic formalism for synaptic models (Destexhe et al 1994) [Model]

Destexhe A, Mainen ZF, Sejnowski TJ (1994) Synthesis of models for excitable membranes, synaptic transmission and neuromodulation using a common kinetic formalism. J Comput Neurosci 1:195-230 [Journal] [PubMed]

   Application of a common kinetic formalism for synaptic models (Destexhe et al 1994) [Model]
   Kinetic synaptic models applicable to building networks (Destexhe et al 1998) [Model]

Essen VANDC, Maunsell JHR (1983) Hierarchical organization and functional streams in the visual cortex Trends Neurosci 6:370-375

Fransen E, Lansner A (1995) Low spiking rates in a population of mutually exciting pyramidal cells Network:Comput Neural Systems 6:271-288

Fricke RA, Prince DA (1984) Electrophysiology of dentate gyrus granule cells. J Neurophysiol 51:195-209 [Journal] [PubMed]

Fukai T (1996) Competition in the temporal domain among neural activities phase-locked to subthreshold oscillations. Biol Cybern 75:453-61 [PubMed]

Gardner-Medwin AR (1976) The recall of events through the learning of associations between their parts. Proc R Soc Lond B Biol Sci 194:375-402 [PubMed]

Gray CM (1994) Synchronous oscillations in neuronal systems: mechanisms and functions. J Comput Neurosci 1:11-38 [Journal] [PubMed]

Gray CM, Konig P, Engel AK, Singer W (1989) Oscillatory responses in cat visual cortex exhibit inter-columnar synchronization which reflects global stimulus properties. Nature 338:334-7 [PubMed]

Gray CM, Singer W (1989) Stimulus-specific neuronal oscillations in orientation columns of cat visual cortex. Proc Natl Acad Sci U S A 86:1698-702 [PubMed]

Hines M (1993) NEURON--a program for simulation of nerve equations. Neural Systems: Analysis And Modeling, Eeckman F, ed. pp.127

Hopfield JJ (1982) Neural networks and physical systems with emergent collective computational abilities. Proc Natl Acad Sci U S A 79:2554-8 [PubMed]

Hopfield JJ (1984) Neurons with graded response have collective computational properties like those of two-state neurons. Proc Natl Acad Sci U S A 81:3088-92 [PubMed]

Hopfield JJ (1995) Pattern recognition computation using action potential timing for stimulus representation. Nature 376:33-6 [PubMed]

Kapur A, Lytton WW, Ketchum KL, Haberly LB (1997) Regulation of the NMDA component of EPSPs by different components of postsynaptic GABAergic inhibition: computer simulation analysis in piriform cortex. J Neurophysiol 78:2546-59 [Journal] [PubMed]

Kapur A, Pearce RA, Lytton WW, Haberly LB (1997) GABAA-mediated IPSCs in piriform cortex have fast and slow components with different properties and locations on pyramidal cells. J Neurophysiol 78:2531-45 [Journal] [PubMed]

Kohonen T (1972) Correlation matrix memories. IEEE Trans. on Computers 21:353-359

Lansner A, Fransen E (1992) Modelling hebbian cell assemblies comprised of cortical neurons Network 3:105-119

Lansner A, Fransen E (1995) Improving the realism of attractor models by using cortical columns as functional units The Neurobiology Of Computation: Proceedings Of The 3rd Annual Computation And Neural Systems Conference, Bower J, ed.

Lisman JE, Idiart MA (1995) Storage of 7 +/- 2 short-term memories in oscillatory subcycles. Science 267:1512-5 [PubMed]

Lytton WW (1997) Brain organization: from molecules to parallel processing Contemporary Behavioral Neurology, Trimble M:Cummings J, ed. pp.5

Lytton WW, Destexhe A, Sejnowski TJ (1996) Control of slow oscillations in the thalamocortical neuron: a computer model. Neuroscience 70:673-84 [PubMed]

Lytton WW, Hellman KM, Sutula TP (1998) Computer models of hippocampal circuit changes of the kindling model of epilepsy. Artif Intell Med 13:81-97 [PubMed]

Lytton WW, Sejnowski TJ (1991) Simulations of cortical pyramidal neurons synchronized by inhibitory interneurons. J Neurophysiol 66:1059-79 [Journal] [PubMed]

Maass W (1997) Fast sigmoidal networks via spiking neurons. Neural Comput 9:279-304 [PubMed]

Marr D (1971) Simple memory: a theory for archicortex. Philos Trans R Soc Lond B Biol Sci 262:23-81 [PubMed]

Marr D (1982) Vision: A Computational Investigation into the Human Representation and Processing of Visual Information

McCulloch WS, Pitts W (1990) A logical calculus of the ideas immanent in nervous activity. 1943. Bull Math Biol 52:99-115; discussion 73-97 [PubMed]

Menschik ED, Finkel LH (1998) Neuromodulatory control of hippocampal function: towards a model of Alzheimer's disease. Artif Intell Med 13:99-121 [PubMed]

Murthy VN, Fetz EE (1992) Coherent 25- to 35-Hz oscillations in the sensorimotor cortex of awake behaving monkeys. Proc Natl Acad Sci U S A 89:5670-4 [PubMed]

O'Reilly RC, McClelland JL (1994) Hippocampal conjunctive encoding, storage, and recall: avoiding a trade-off. Hippocampus 4:661-82 [PubMed]

Parodi O, Combe P, Ducom JC (1996) Temporal coding in vision: coding by the spike arrival times leads to oscillations in the case of moving targets. Biol Cybern 74:497-509 [PubMed]

Pribram KH (1969) The neurophysiology of remembering. Sci Am 220:73-86 [PubMed]

Scharfman HE (1994) Evidence from simultaneous intracellular recordings in rat hippocampal slices that area CA3 pyramidal cells innervate dentate hilar mossy cells. J Neurophysiol 72:2167-80 [Journal] [PubMed]

Stemmler M (1996) A single spike suffices - the simplest form of stochastic resonance in model neurons Network-computation In Neural Systems 7:687-716

Teyler TJ, DiScenna P (1986) The hippocampal memory indexing theory. Behav Neurosci 100:147-54 [PubMed]

Thorpe S, Fize D, Marlot C (1996) Speed of processing in the human visual system. Nature 381:520-2 [PubMed]

Tovee MJ (1994) Neuronal processing. How fast is the speed of thought? Curr Biol 4:1125-7 [PubMed]

Tovee MJ, Rolls ET, Treves A, Bellis RP (1993) Information encoding and the responses of single neurons in the primate temporal visual cortex. J Neurophysiol 70:640-54 [Journal] [PubMed]

Treves A, Rolls ET (1994) Computational analysis of the role of the hippocampus in memory. Hippocampus 4:374-91 [PubMed]

Willshaw DJ, Buneman OP, Longuet-Higgins HC (1969) Non-holographic associative memory. Nature 222:960-2 [PubMed]

Hines ML, Carnevale NT (2003) Personal Communication of NEURON bibliography

Lytton WW, Hellman KM, Sutula TP (1998) Computer models of hippocampal circuit changes of the kindling model of epilepsy. Artif Intell Med 13:81-97 [PubMed]

Lytton WW, Lipton P (1999) Can the hippocampus tell time? The temporo-septal engram shift model. Neuroreport 10:2301-6 [Journal] [PubMed]

   Hippocampus temporo-septal engram shift model (Lytton 1999) [Model]

Neymotin SA, Jacobs KM, Fenton AA, Lytton WW (2011) Synaptic information transfer in computer models of neocortical columns. J Comput Neurosci. 30(1):69-84 [Journal] [PubMed]

   Synaptic information transfer in computer models of neocortical columns (Neymotin et al. 2010) [Model]

(55 refs)