#] #] ********************* #] loaddefs link d_MindCode 'basics - neurons, clusters.ndf' - optrs to [create, connect, test] various neuron types # www.BillHowell.ca 10Sep2020 initial # approaches to symbolic representation in MindCode # "multiple conflicting hypothesis" # see also "$d_MindCode""neurons/logic gates.ndf" # view this file in a text editor, with [constant width font, tab = 3 spaces], no line-wrap f_neurons := 'basics - neurons, clusters.ndf' ; loaddefs_start f_neurons ; #**************************** # List of operators, generated with : # $ cat "$d_Qndfs""MindCode/basics - neurons, clusters.ndf" | grep "^#]" | sed 's/^#\]/ /' # ********************* loaddefs link d_MindCode 'basics - neurons, clusters.ndf' - optrs to [create, connect, test] various neuron types Initialize globals +-----+ neurons neurSize_increment - expand the list (including non-assigned) of neurons neurIdent_get - get neurIdent for new neuron, increment the lastNeuronPointer neur_create IS OP classPhr - generic optr for adding neuron neur_copy IS OP neurIdent - create a new neuron by copying an existing, keep connections neur_delete IS OP neurIdent - delete a neuron, don't remove [list, connection, etc]s, just re-class +-----+ clusters clusSize_increment - expand the list (including non-assigned) of clusters clusIdent_get - get clusIdent for new cluster, increment the lastClusterPointer clus_create IS OP classPhr - generic optr for adding clusters clusNeurs_create IS OP n_neurons - create neurons for a cluster #08********08 # Quick explanations # Base tools for MideCode - [0,1,2,3,burst] spiking, http://www.scholarpedia.org/article/Bursting Bursts encode different features of sensory input than single spikes (Gabbiani et al. 1996, Oswald et al. 2004). For example, neurons in the electrosensory lateral-line lobe (ELL) of weakly electric fish fire network induced-bursts in response to communication signals and single spikes in response to prey signals (Doiron et al. 2003). # 0-spiking = non-spiking neurons https://en.wikipedia.org/wiki/Non-spiking_neuron Through studying these complex spiking networks in animals, a neuron that did not exhibit characteristic spiking behavior was discovered. These neurons use a graded potential to transmit data as they lack the membrane potential that spiking neurons possess. #08********08 # Setup (kind of like header info) # set the output format of reals to 2 digit accuracy setformat '%.2f' ; #08********08 #] +-----+ #] Initialize globals neurList_increment := 1000 ; % maximum number of neurons (array size initial - can be increased) ; n_neur := 1000 ; neur_last := -1 ; % points to last-created neuron ; nullList := neurList_increment reshape [null] ; neurIdentL := nullList ; neurClassL := nullList ; % neurClass is a PHRASE!! ; neurStateL := nullList ; dendIdentL := nullList ; dendDelayL := nullList ; dendInhibL := nullList ; % connects to soma, 15Apr2021 perhaps astrocyte-powered? ; axonIdentL := nullList ; axonDelayL := nullList ; axonInhibL := nullList ; % connects to soma ; IF flag_debug THEN write 'loading neurDisplay' ; ENDIF ; #] neurDisplay IS OP neurIdentStart neruIdentEnd - show a range of neuron typeValues neurDisplay IS OP neurIdentStart neurIdentEnd { LOCAL iList ; NONLOCAL neurIdentL neurClassL dendIdentL dendDelayL dendInhibL axonIdentL axonDelayL axonInhibL ; iList := neurIdentStart + (tell (neurIdentEnd - neurIdentStart)) ; transpose mix (iList EACHRIGHT choose neurIdentL neurClassL dendIdentL dendDelayL dendInhibL axonIdentL axonDelayL axonInhibL) } # for full list of defined neurons : neurDisplay 0 neur_last # for first 10 : neurDisplay 0 10 clusList_increment := 100 ; % maximum number of clusters (array size initial - can be increased) ; n_clus := 100 ; clus_last := -1 ; % points to last-created cluster ; nullList := clusList_increment reshape [null] ; clusIdentL := nullList ; clusClassL := nullList ; % clusClass is a PHRASE!! ; clusNeurnL := nullList ; IF flag_debug THEN write 'loading clusDisplay' ; ENDIF ; #] clusDisplay IS OP clusIdentStart clusIdentEnd - show a range of cluson typeValues clusDisplay IS OP clusIdentStart clusIdentEnd { LOCAL iList ; NONLOCAL clusIdentL clusClassL clusNeurnL ; iList := clusIdentStart + (tell (clusIdentEnd - clusIdentStart)) ; transpose mix (iList EACHRIGHT choose clusIdentL clusClassL clusNeurnL) } # for full list of defined clusters : clusDisplay 0 clus_last # for first 10 : clusDisplay 0 10 IF flag_debug THEN write 'loading clusNeurDisplay' ; ENDIF ; #] clusNeurDisplay IS OP clusIdentStart clusIdentEnd - show a range of cluson typeValues clusNeurDisplay IS OP clusIdent { LOCAL iList ; NONLOCAL neurIdentL neurClassL dendIdentL dendDelayL dendInhibL axonIdentL axonDelayL axonInhibL ; transpose mix (clusNeurnL@clusIdent EACHRIGHT choose neurIdentL neurClassL dendIdentL dendDelayL dendInhibL axonIdentL axonDelayL axonInhibL) } # for full list of defined clusters : clusDisplay 0 clus_last # for first 10 : clusDisplay 0 10 #08********08 #] +-----+ #] neurons IF flag_debug THEN write '+-----+' ; ENDIF ; IF flag_debug THEN write 'neurons' ; ENDIF ; IF flag_debug THEN write 'loading neurSize_increment' ; ENDIF ; #] neurSize_increment - expand the list (including non-assigned) of neurons neurSize_increment IS { NONLOCAL n_neur neurList_increment neurIdentL neurClassL neurStateL dendIdentL dendDelayL dendInhibL axonIdentL axonDelayL axonInhibL ; nullList := neurList_increment reshape null ; n_neur := n_neur + neurList_increment ; neurIdentL := neurIdentL link nullList ; neurClassL := neurClassL link nullList ; neurStateL := neurStateL link nullList ; dendIdentL := dendIdentL link nullList ; dendDelayL := dendDelayL link nullList ; dendInhibL := dendInhibL link nullList ; axonIdentL := axonIdentL link nullList ; axonDelayL := axonDelayL link nullList ; axonInhibL := axonInhibL link nullList ; } IF flag_debug THEN write 'loading neurIdent_get' ; ENDIF ; #] neurIdent_get - get neurIdent for new neuron, increment the lastNeuronPointer neurIdent_get IS { NONLOCAL n_neur neur_last neurIdentL ; neur_last := neur_last + 1 ; IF (n_neur = neur_last) THEN neurSize_increment ; ENDIF ; update "neurIdentL neur_last neur_last ; neur_last } IF flag_debug THEN write 'loading neur_create' ; ENDIF ; #] neur_create IS OP classPhr - generic optr for adding neuron # 10Sep2020 initial, [23Mar,01Apr]2021 major revamps # Easiest to pre-specify [neuron, cluster]s eg [,epi-]genetics # Create neuron ID (simple increment of existing list) & add to [global, local, etc] lists # can have MORE THAN ONE synapse between two specific neurons, each with different delay (eg addressable?) ; # neurIdentL neuronclasL axonIdentL dendIdentL must have same sequencing!!! # DON'T use if intended neuron already exists in [axon, dend]IDL!! # [dendIdents axonIdents] = structured-cables used to connect the new cluster # how do I bootstrap before other neurons are set up? - don't create new neurons # usually set as null initially : [dendIdents dendDelays axonIdents axonDelays] # This might become standard - which would simplify the calls, clusters would define (or free connects) # 01Apr2021 each needs a "fire line" to compel it to fire without other inputs! neur_create IS OP classPhr { LOCAL errmsg neurIdent ; NONLOCAL neurIdentL neurClassL neurStateL dendIdentL dendDelayL dendInhibL axonIdentL axonDelayL axonInhibL ; neurIdent := neurIdent_get ; update "neurClassL neurIdent classPhr ; update "neurStateL neurIdent 0 ; neurIdent } # loaddefs link d_MindCode 'basics - neurons, clusters.ndf' IF flag_debug THEN write 'loading neur_connectStd' ; ENDIF ; #] neur_connectStd IS OP neurIdent neurClassPhr dendIdents axonIdents - #] standard setup of connections for neuron # 03Apr2021 initial neur_connectStd IS OP neurIdent neurClassPhr dendIdents axonIdents { LOCAL clusNeurns i ; NONLOCAL clusNeurnL ; i := neurIdent ; update "neurClassL i neurClassPhr ; update "dendIdentL i (dendIdentL@i link (i - 1) ) ; % update "dendDelayL i (dendDelayL@i link (1 + random 2) ) ; % update "dendInhibL i (dendInhibL@i link null ) ; update "axonIdentL i (axonIdentL@i link (i + 1) ) ; % update "axonDelayL i (axonDelayL@i link (1 + random 2) ) ; % update "axonInhibL i (axonInhibL@i link neur1 ) ; } IF flag_debug THEN write 'loading neur_copy' ; ENDIF ; #] neur_copy IS OP neurIdent - create a new neuron by copying an existing, keep connections # 23Mar2021 initial # might be handy to keep some pre-existing connections # it would be more efficient to pre-create large lists with lastCreatedIndex neur_copy IS OP neurIdent { LOCAL i neurIdentNew ; NONLOCAL neurIdentL neurClassL neurStateL dendIdentL dendDelayL dendInhibL axonIdentL axonDelayL axonInhibL ; i := neur_create neurClassL@neurIdent ; j := neurIdent ; update "dendIdentL i dendIdentL@j ; update "dendDelayL i dendDelayL@j ; update "dendInhibL i dendInhibL@j ; update "axonIdentL i axonIdentL@j ; update "axonDelayL i axonDelayL@j ; update "axonInhibL i axonInhibL@j ; i } # I want to do this - ??? neurClassL@i dendIdentL@i dendDelayL@i axonIdentL@i axonDelayL@i neurStateL@i EACHBOTH := neurClassL@j dendIdentL@j dendDelayL@j axonIdentL@j axonDelayL@j neurStateL@j ; IF flag_debug THEN write 'loading neur_delete' ; ENDIF ; #] neur_delete IS OP neurIdent - delete a neuron, don't remove [list, connection, etc]s, just re-class # 23Mar2021 initial # handy for neuron [attrition, kill] etc # for now - just change class to "dead # don't do "garbage collection" here, leave that for a whole-network cleanup? # must remove [axon, dend] connects in "related" neurons neur_delete IS OP neurIdent { update "neurClassL neurIdent "dead ; } #08********08 #] +-----+ #] clusters # cluster of [cluster,neuron]s -> may need [super-cluster, system]s etc? probably redundant? # treats conections as bundles of neurons, with connections to other clusters ?and individual neurons? # some neurons are "captive" with connections ONLY within the cluster # other neurons connect to external [cluster, neuron]s # servers as a "state" machine [receive, hold, send]ing an integer value # initial neuron states = 0 # intra-cluster connections : NONE initially, added by connect optrs IF flag_debug THEN write '+-----+' ; ENDIF ; IF flag_debug THEN write 'Cluster primitives' ; ENDIF ; IF flag_debug THEN write 'loading clusSize_increment' ; ENDIF ; #] clusSize_increment - expand the list (including non-assigned) of clusters clusSize_increment IS { NONLOCAL n_clus clusList_increment clusIdentL clusClassL clusNeurnL ; nullList := clusList_increment reshape null ; clusIdentL := clusIdentL link nullList ; clusClassL := clusClassL link nullList ; clusNeurnL := clusNeurnL link nullList ; n_clus := n_clus + clusList_increment ; } IF flag_debug THEN write 'loading clusIdent_get' ; ENDIF ; #] clusIdent_get - get clusIdent for new cluster, increment the lastClusterPointer clusIdent_get IS { NONLOCAL n_clus clus_last clusIdentL ; clus_last := clus_last + 1 ; IF (n_clus = clus_last) THEN clusSize_increment ; ENDIF ; update "clusIdentL clus_last clus_last ; clus_last } IF flag_debug THEN write 'loading clus_create' ; ENDIF ; #] clus_create IS OP classPhr - generic optr for adding clusters # 03Apr2021 initial clus_create IS OP classPhr { LOCAL errmsg clusIdent ; NONLOCAL clusIdentL clusClassL ; clusIdent := clusIdent_get ; update "clusClassL clusIdent classPhr ; clusIdent } # loaddefs link d_MindCode 'basics - neurons, clusters.ndf' IF flag_debug THEN write 'loading clusNeurs_create' ; ENDIF ; #] clusNeurs_create IS OP clusIdent n_neurons - create neurons for a cluster # 03Apr2021 initial clusNeurs_create IS OP clusIdent n_neurons { LOCAL clusNeurns i ; NONLOCAL clusNeurnL ; IF flag_break THEN BREAK ; ENDIF ; clusNeurns := null ; FOR i WITH (tell n_neurons) DO clusNeurns := clusNeurns link (neur_create "unknown) ; ENDFOR ; update "clusNeurnL clusIdent clusNeurns ; clusNeurns } #08********08 #] +-----+ #] examples IF flag_debug THEN write '+-----+' ; ENDIF ; IF flag_debug THEN write 'examples' ; ENDIF ; # neurIdent0 := neur_create ; neurIdent1 := neur_create ; neurIdent2 := neur_create ; # loaddefs link d_MindCode 'basics - neurons, clusters.ndf' loaddefs_ended f_neurons ; # enddoc