From 69c1561f8f05f3e78299484e5309c4ed0a04cbda Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Thu, 13 Oct 2022 14:37:13 +0200 Subject: [PATCH] Discuss q10 pattern in NMODL docs. (#1995) * Discuss q10 pattern in NMODL docs. --- doc/fileformat/nmodl.rst | 45 +++++++++++++++++++++++++++++++++++++++ mechanisms/default/hh.mod | 26 +++++++++------------- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/doc/fileformat/nmodl.rst b/doc/fileformat/nmodl.rst index 3ebf3d3d..b975fc59 100644 --- a/doc/fileformat/nmodl.rst +++ b/doc/fileformat/nmodl.rst @@ -374,6 +374,51 @@ Note that we do not lose accuracy here, since Arbor does not support higher-order ODEs and thus will treat ``g`` as a constant across a single timestep even if ``g`` actually depends on ``v``. +Using Memory versus Computation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Commonly ion channels need to correct for temperature differences, which yields +a term similar to + +.. code:: + + q = 3^(0.1*celsius - 0.63) + +Here, we find that the cost of the exponential when computing ``q`` in the +``DERIVATIVE`` block is high enough to make pre-computing ``q`` in ``INITIAL`` +and loading the value later an optimisation. Shown below is a simplified version +of this pattern from ``hh.mod`` in the Arbor sources + +.. code:: + + NEURON { + ... + RANGE ..., q + } + + ASSIGNED { q } + + PARAMETER { + ... + celsius (degC) + } + + STATE { ... } + + BREAKPOINT { + SOLVE dS METHOD cnexp + ... + } + + INITIAL { + q = 3^(0.1*celsius - 0.63) + ... + } + + DERIVATIVE states { + ... : uses q + } + Specialised Functions ~~~~~~~~~~~~~~~~~~~~~ diff --git a/mechanisms/default/hh.mod b/mechanisms/default/hh.mod index 9c64142f..88c28346 100644 --- a/mechanisms/default/hh.mod +++ b/mechanisms/default/hh.mod @@ -38,7 +38,7 @@ BREAKPOINT { INITIAL { LOCAL alpha, beta - q10 = 3^((celsius - 6.3)/10.0) + q10 = 3^(0.1*celsius - 0.63) : sodium activation system alpha = m_alpha(v) @@ -53,38 +53,32 @@ INITIAL { : potassium activation system alpha = n_alpha(v) beta = n_beta(v) - n = alpha/(alpha + beta) } DERIVATIVE states { - LOCAL alpha, beta, sum + LOCAL alpha, beta : sodium activation system alpha = m_alpha(v) beta = m_beta(v) - sum = alpha + beta - m' = (alpha - m*sum)*q10 + m' = (alpha - m*(alpha + beta))*q10 : sodium inactivation system alpha = h_alpha(v) beta = h_beta(v) - sum = alpha + beta - h' = (alpha - h*sum)*q10 + h' = (alpha - h*(alpha + beta))*q10 : potassium activation system alpha = n_alpha(v) beta = n_beta(v) - sum = alpha + beta - n' = (alpha - n*sum)*q10 + n' = (alpha - n*(alpha + beta))*q10 } -FUNCTION vtrap(x,y) { vtrap = y*exprelr(x/y) } - -FUNCTION m_alpha(v) { m_alpha = 0.1*vtrap(-(v + 40.0), 10.0) } -FUNCTION h_alpha(v) { h_alpha = 0.07*exp(-(v + 65.0)/20.0) } -FUNCTION n_alpha(v) { n_alpha = 0.01*vtrap(-(v + 55.0), 10.0) } +FUNCTION m_alpha(v) { m_alpha = exprelr(-0.1*v - 4.0) } +FUNCTION h_alpha(v) { h_alpha = 0.07*exp(-0.05*v - 3.25) } +FUNCTION n_alpha(v) { n_alpha = 0.1*exprelr(-0.1*v - 5.5) } FUNCTION m_beta(v) { m_beta = 4.0*exp(-(v + 65.0)/18.0) } -FUNCTION h_beta(v) { h_beta = 1.0/(exp(-(v + 35.0)/10.0) + 1.0) } -FUNCTION n_beta(v) { n_beta = 0.125*exp(-(v + 65.0)/80.0) } +FUNCTION h_beta(v) { h_beta = 1.0/(exp(-0.1*v - 3.5) + 1.0) } +FUNCTION n_beta(v) { n_beta = 0.125*exp(-0.0125*v - 0.8125) } -- GitLab