Skip to content

Commit

Permalink
Add some docstrings for the exponential Euler integrator and an example
Browse files Browse the repository at this point in the history
for a Hodgkin-Huxley neuron. Closes #14
  • Loading branch information
Marcel Stimberg committed Jun 13, 2013
1 parent 4edb549 commit 16e7e7e
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 4 deletions.
39 changes: 36 additions & 3 deletions brian2/stateupdaters/exponential_euler.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import sympy as sp

from brian2.stateupdaters.base import StateUpdateMethod
from .base import StateUpdateMethod

__all__ = ['exponential_euler']


def get_conditionally_linear_system(eqs):
'''
Convert equations into a linear system using sympy.
Expand All @@ -15,12 +16,28 @@ def get_conditionally_linear_system(eqs):
Returns
-------
coefficients : dict of (sympy expression, sympy expression) tuples
For every variable x, a tuple (M, B) containing the coefficients M and
B (as sympy expressions) for M * x + B
Raises
------
ValueError
If the equations cannot be converted into an M * X + B form.
If one of the equations cannot be converted into a M * x + B form.
Examples
--------
>>> from brian2 import Equations
>>> eqs = Equations("""
... dv/dt = (-v + w**2) / tau : 1
... dw/dt = -w / tau : 1
... """)
>>> system = get_conditionally_linear_system(eqs)
>>> print(system['v'])
(-1/tau, w**2/tau)
>>> print(system['w'])
(-1/tau, 0)
'''
diff_eqs = eqs.substituted_expressions

Expand Down Expand Up @@ -48,8 +65,22 @@ def get_conditionally_linear_system(eqs):

return coefficients


class ExponentialEulerStateUpdater(StateUpdateMethod):
'''
A state updater for conditionally linear equations, i.e. equations where
each variable only depends linearly on itself (but possibly non-linearly
on other variables). Typical Hodgkin-Huxley equations fall into this
category, it is therefore the default integration method used in the
GENESIS simulator, for example.
'''
def can_integrate(self, equations, namespace, specifiers):
'''
Return whether the given equations can be integrated using this
state updater. This method tests for conditional linearity by
executing `get_conditionally_linear_system` and returns ``True`` in
case this call succeeds.
'''
if equations.is_stochastic:
return False

Expand Down Expand Up @@ -87,5 +118,7 @@ def __call__(self, equations, namespace=None, specifiers=None):
code += ['{var} = _{var}'.format(var=var)]

return '\n'.join(code)
# Copy doc from parent class
__call__.__doc__ = StateUpdateMethod.__call__.__doc__

exponential_euler = ExponentialEulerStateUpdater()
52 changes: 52 additions & 0 deletions examples/I-F_curve_Hodgkin_Huxley.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'''
Input-Frequency curve of a HH model
Network: 100 unconnected Hodgin-Huxley neurons with an input current I.
The input is set differently for each neuron.
This simulation should use exponential Euler integration
'''
from pylab import *
from brian2 import *

BrianLogger.log_level_info()

language = PythonLanguage()
#language = CPPLanguage()

N = 100

# Parameters
area = 20000 * umetre ** 2
Cm = (1 * ufarad * cm ** -2) * area
gl = (5e-5 * siemens * cm ** -2) * area
El = -65 * mV
EK = -90 * mV
ENa = 50 * mV
g_na = (100 * msiemens * cm ** -2) * area
g_kd = (30 * msiemens * cm ** -2) * area
VT = -63 * mV

# The model
eqs = Equations('''
dv/dt = (gl*(El-v) - g_na*(m*m*m)*h*(v-ENa) - g_kd*(n*n*n*n)*(v-EK) + I)/Cm : volt
dm/dt = 0.32*(mV**-1)*(13.*mV-v+VT)/
(exp((13.*mV-v+VT)/(4.*mV))-1.)/ms*(1-m)-0.28*(mV**-1)*(v-VT-40.*mV)/
(exp((v-VT-40.*mV)/(5.*mV))-1.)/ms*m : 1
dn/dt = 0.032*(mV**-1)*(15.*mV-v+VT)/
(exp((15.*mV-v+VT)/(5.*mV))-1.)/ms*(1.-n)-.5*exp((10.*mV-v+VT)/(40.*mV))/ms*n : 1
dh/dt = 0.128*exp((17.*mV-v+VT)/(18.*mV))/ms*(1.-h)-4./(1+exp((40.*mV-v+VT)/(5.*mV)))/ms*h : 1
I : amp
''')
# Threshold and refractoriness are only used for spike counting
group = NeuronGroup(N, equations=eqs, threshold='is_active * (v > -40*mV)',
language=language)
group.refractory = 1*ms
group.v = El
group.I = linspace(0 * nA, 0.7 * nA, N)

monitor = SpikeMonitor(group)

duration = 2 * second
run(duration)
plot(group.I / nA, monitor.count / duration)
show()
2 changes: 1 addition & 1 deletion examples/I-F_curve.py → examples/I-F_curve_LIF.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

monitor = SpikeMonitor(group)

duration = 5 * second
duration = 1 * second
run(duration)
plot(group.v0 / mV, monitor.count / duration)
show()

0 comments on commit 16e7e7e

Please sign in to comment.