accessing low-pass filtered population firing rate in a synaptic equation

26 views
Skip to first unread message

Katharina Wilmes

unread,
Dec 17, 2019, 10:11:37 AM12/17/19
to Brian
What is the best way to store a low-pass filtered version of the population firing rate? 

I want to add 1/tau_P to the variable P every time one of the neurons in my NeuronGroup spikes.
I tried to add this update to the reset statement of the NeuronGroup:

reset='v_s=el ; ; P+=1/tau_P'

and define a differential equation in the equation for the Neurongroup:

dP/dt = -P/tau_P : Hz (shared) 

which should be shared among all neurons in the group. But differential equations cannot be shared.

In the end, I would like to access the variable P in my Synapses objects to make synaptic plasticity dependent on the population firing rate.

Marcel Stimberg

unread,
Dec 18, 2019, 6:01:31 AM12/18/19
to brians...@googlegroups.com
Hi Katharina,

yes, for technical reasons you cannot have a shared variable defined by
a differential equation, and you cannot update it in a reset statement
either. The latter is also because of semantic ambiguity: in a
run_regularly operation, a shared variable will only updated once, so in
a reset statement it is unclear whether it should be updated once or
once per neuron that spiked.

So, the solution here is to use a Synapses object: you create a dummy
group of size 1 just to store the population firing rate and to
implement its differential equation. Instead of updating P via the reset
statement, you connect all neurons to this dummy group and use
on_pre='P+=1/tau_P'.

Unfortunately, this means that you cannot directly access the P variable
from your original NeuronGroup and the synapses. Normally, the linked
variable mechanism would be the thing to use here, but unfortunately
that works only in a limited way with Synapses (because potentially, it
could mean that we'd have to use a lot of indirect indexing to get to
the values we need). It would work if P were a shared variable, but then
we'd be back at the problem from the start. There's a way to make this
work with a fix in Brian by considering all variables in a group of size
1 as "effectively shared", but right now this is not implemented. The
only solution I am seeing at the moment is to manually use the mechanism
that linked variables use behind the scenes. To do this, in your
Synapses object where you need access to the P variable, do:

synapses.variables.add_reference('P', dummy_group, 'P', index='0')

This way, you'll have access to the variable 'P' from the dummy_group
which tracks the population firing rate in your synaptic equations and
on_pre/on_post calls (the first 'P' stands for the name you want to use
in the Synapses object, and the second 'P' is the name of the variable
in the dummy group).

Hope that works for you, best

  Marcel

Katharina Wilmes

unread,
Dec 18, 2019, 9:26:55 AM12/18/19
to Brian
Dear Marcel,

that works perfectly! Thank you very much :).

Best,
Katha
Reply all
Reply to author
Forward
0 new messages