GithubHelp home page GithubHelp logo

Comments (17)

tclose avatar tclose commented on August 18, 2024

This is particularly relevant for math-inline expressions, as there would be no easy way of specifying the units. Even for MathML, it would be a little bit clunky because we would have to specify namespaces to add a β€œunits” attribute to the tag (this is how SBML does it). It would also make the code much more readable if constants are named.

from nineml-spec.

apdavison avatar apdavison commented on August 18, 2024

I can see arguments both ways here. I think Mike Hull has a proposal for specifying units in math-inline expressions. Perhaps we should support both named constants and units in MathML.

from nineml-spec.

tclose avatar tclose commented on August 18, 2024

Following on from our discussion in the latest Google Hangout and an issue that has arisen with the version of the Izhikevich model used in the 9ML paper, I think that constants should perhaps be included in v1.

Padraig pointed out that the dimensions of Izhikevich model in the paper (and the catalog) are not consistent, something that is apparently very common in abstract mathematical models of neurons. Arbitrary Constant elements would be a good way to solve this problem by scaling mismatch between dimensions that need to be accounted for (this is how Padraig solves it in NeuroML). So perhaps arbitrary Constant tags should get bumped up to version 1 to allow us to implement the Izhikevich model correctly, since the only real concern was abuse of constants in place of parameters.

One alternative might be to add an explicit DimensionCorrection element or similar but this probably has got quite a bit of room for abuse as well.

from nineml-spec.

apdavison avatar apdavison commented on August 18, 2024

I think that constants should perhaps be included in v1.

ok with me.

from nineml-spec.

tclose avatar tclose commented on August 18, 2024

Although maybe a bit too late for version 1.0, I have thought that if we didn't want to allow user-defined constants to handle dimension conversions (I think it is a bit ugly having units in the user layer and will be prone to misuse), we could just allow the use of dimension names in mathinline expressions, e.g. in the Izhikevich example from the paper that has been causing us problems

...
      <Alias name="dV">
        <MathInline>(k * (V - Vr) * (V - Vt) - U * currentDimension + iSyn + iExt) / Cm</MathInline>
      </Alias>
...

the only downsides I can think of would be that we would have to check that they are only used in multiplication or divisions and having to be a bit careful with dimension names cluttering up your namespace (especially ones like voltage). Although the namespace issue could be avoided with a naming convention of voltageDimension, per_currentDimension, etc.., which probably wouldn't be a bad thing.

Actual constants like pi, AvogandrosNumber and the like could then be referenced by name from a standard library (all non-standard constants would have to be passed as parameters, which would hopefully discourage their use).

from nineml-spec.

robclewley avatar robclewley commented on August 18, 2024

Hi,

I'm not at all averse to the principle of having dimensions be expressable.

On Sun, Mar 8, 2015 at 9:48 AM, Tom Close [email protected] wrote:

Although maybe a bit too late for version 1.0, I have thought that if we
didn't want to allow user-defined constants to handle dimension conversions
(I think it is a bit ugly having units in the user layer and will be prone
to misuse), we could just allow the use of dimension names in mathinline
expressions, e.g. in the Izhikevich example from the paper that has been
causing us problems

...

(k * (V - Vr) * (V - Vt) - U * currentDimension + iSyn + iExt) / Cm

...

the only downsides I can think of would be that we would have to check
that they are only used in multiplication or divisions and having to be a
bit careful with dimension names cluttering up your namespace (especially
ones like voltage). Although the namespace issue could be avoided with a
naming convention of voltageDimension, per_currentDimension, etc.., which
probably wouldn't be a bad thing.

I agree that a special namespace convention like this would help. But I'm
not convinced that the in-line dimension "correction" through
multiplication is the right way to handle it. Reading it mathematically, it
doesn't make sense, and to me that's troubling for people expecting to
intuit how to apply this. I don't recall the specifics of how to interpret
the dimensions of the Izhikevich model components, and I'm not sure one can
properly but, hypothetically, let me demonstrate a potential source of
confusion: from dU/dt, U appears to have the same units as V^3. Multiplying
by currentDimension in this case merely implies to me that the units are
now voltageDimension^3*currentDimension. The 'a' parameter could also have
dimensions, depending on its derivation.

For the first term, k is a parameter that probably holds all the relevant
dimension conversions, and multiplying by a unit-like quantity is not the
same as coercing a whole group of quantities to have one particular unit.
That's more like a function call: coerce(k_(V-Vr)_(V-Vr),
currentDimension). This, however, would make the marked up code difficult
to export and parse for use in other symbolic manipulations and analyses.

At least, I would suggest a different symbol than * to indicate the
coercion of dimension. Not sure what to suggest, what about @ or #, like a
tag?

That's my immediate reaction to that idea, anyway. What do others think?
Cheers,
Rob

from nineml-spec.

tclose avatar tclose commented on August 18, 2024

Hi Rob,

Thanks for the feedback.

Sorry, I forgot to mentioned that I was working from my latest version of the Izhikevich model in which I have refactored U to be dimensionless and tried to push as many of dimensionality corrections into the parameters as I can (such as k as you mention). Doing this leaves only one expression in the model where the dimensions are inconsistent (the one I referenced above), which I handle by multiplying U by unit current constant unitI.

<NineML xmlns="http://nineml.net/9ML/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://nineml.net/9ML/1.0/schema/NineML_v1.0.xsd">
  <ComponentClass name="IzhikevichClass">
    <Parameter name="a" dimension="dimensionless"/>
    <Parameter name="b" dimension="per_voltage3"/>
    <Parameter name="c" dimension="voltage"/>
    <Parameter name="k" dimension="conductance_per_voltage"/>
    <Parameter name="Vr" dimension="voltage"/>
    <Parameter name="Vt" dimension="voltage"/>
    <Parameter name="Vb" dimension="voltage"/>
    <Parameter name="Vpeak" dimension="voltage"/>
    <Parameter name="Cm" dimension="specificCapacitance"/>
    <AnalogReducePort name="iSyn" dimension="current" operator="+"/>
    <AnalogReceivePort name="iExt" dimension="current"/>
    <AnalogSendPort name="U" dimension="dimensionless"/>
    <AnalogSendPort name="V" dimension="voltage"/>
    <EventSendPort name="spikeOutput"/>
    <Dynamics>
      <StateVariable name="V" dimension="voltage"/>
      <StateVariable name="U" dimension="dimensionless"/>
      <Regime name="subthreshold">
        <TimeDerivative variable="U">
          <MathInline>a * (b * (V - Vb) ^ 3 - U)</MathInline>
        </TimeDerivative>
        <TimeDerivative variable="V">
          <MathInline>dV</MathInline>
        </TimeDerivative>
        <OnCondition>
          <Trigger>
            <MathInline>V &gt; Vpeak</MathInline>
          </Trigger>
          <StateAssignment variable="V">
            <MathInline>c</MathInline>
          </StateAssignment>
          <StateAssignment variable="U">
            <MathInline>U</MathInline>
          </StateAssignment>
          <OutputEvent port="spikeOutput"/>
        </OnCondition>
        <OnCondition target_regime="subVb">
          <Trigger>
            <MathInline>V &lt; Vb</MathInline>
          </Trigger>
        </OnCondition>
      </Regime>
      <Regime name="subVb">
        <TimeDerivative variable="U">
          <MathInline>- U * a</MathInline>
        </TimeDerivative>
        <TimeDerivative variable="V">
          <MathInline>dV</MathInline>
        </TimeDerivative>
        <OnCondition target_regime="subthreshold">
          <Trigger>
            <MathInline>V &gt; Vb</MathInline>
          </Trigger>
        </OnCondition>
      </Regime>
      <Alias name="dV">
        <MathInline>(k * (V - Vr) * (V - Vt) - U * unitI + iSyn + iExt) / Cm</MathInline>
      </Alias>
      <Constant name="unitI" units="A">1</Constant>
    </Dynamics>
  </ComponentClass>
  <Dimension name="dimensionless"/>
  <Dimension name="voltage" m="1" l="2" t="-3" i="-1"/>
  <Dimension name="per_voltage3" m="-3" l="-6" t="9" i="3"/>
  <Dimension name="conductance_per_voltage" m="-2" l="-4" t="6" i="3"/>
  <Dimension name="specificCapacitance" m="-1" l="-4" t="4" i="2"/>
  <Dimension name="current" i="1"/>
  <Unit symbol="A" dimension="current" power="0"/>
</NineML>

For both this version and the original Izhikevich model I found myself using this strategy of multiplying by unit current/voltage/resistance, etc... so this is what led me to think that we could just get rid of the unitI constant in this case and basically interpret multiplication/division of a dimension as multiplication by the base unit of that dimension. However, I agree that using dimensions in this manner is probably a bit confusing.

When we discussed using non-ANSI C terms in mathinline expresssions recently (namely the '^' exponent), Paul and Alex were very strongly opposed to it as you lose the ability to simply translate them to code generation templates. I would tend to think that introducing non-standard operators could be a little confusing for someone reading through the model as well. So perhaps I am being a little idealogical trying to get rid of units from the user layer and what we have now (using unitI, etc...) is the simplest and most readily understandable solution.

from nineml-spec.

tclose avatar tclose commented on August 18, 2024

On further consideration, I don't think that multiplying U by 1 Amp would even be correct as it should be in the same units as iSyn and iExt. However, thinking about this some more if we change U to dimension "current" then this removes the problem doesn't it, i.e.

 <ComponentClass name="IzhikevichClass">
    <Parameter name="a" dimension="dimensionless"/>
    <Parameter name="b" dimension="conductance_per_voltage2"/>
    <Parameter name="c" dimension="voltage"/>
    <Parameter name="k" dimension="conductance_per_voltage"/>
    <Parameter name="Vr" dimension="voltage"/>
    <Parameter name="Vt" dimension="voltage"/>
    <Parameter name="Vb" dimension="voltage"/>
    <Parameter name="Vpeak" dimension="voltage"/>
    <Parameter name="Cm" dimension="specificCapacitance"/>
    <AnalogReducePort name="iSyn" dimension="current" operator="+"/>
    <AnalogReceivePort name="iExt" dimension="current"/>
    <AnalogSendPort name="U" dimension="current"/>
    <AnalogSendPort name="V" dimension="voltage"/>
    <EventSendPort name="spikeOutput"/>
    <Dynamics>
      <StateVariable name="V" dimension="voltage"/>
      <StateVariable name="U" dimension="current"/>
      <Regime name="subthresholdRegime">
        <TimeDerivative variable="U">
          <MathInline>a * (b * pow(V - Vb, 3) - U)</MathInline>
        </TimeDerivative>
        <TimeDerivative variable="V">
          <MathInline>V_deriv</MathInline>
        </TimeDerivative>
        <OnCondition targetRegime="subthresholdRegime">
          <Trigger>
            <MathInline>V &gt; Vpeak</MathInline>
          </Trigger>
          <StateAssignment variable="V">
            <MathInline>c</MathInline>
          </StateAssignment>
          <StateAssignment variable="U">
            <MathInline>U</MathInline>
          </StateAssignment>
          <OutputEvent port="spikeOutput"/>
        </OnCondition>
        <OnCondition targetRegime="subVbRegime">
          <Trigger>
            <MathInline>V &lt; Vb</MathInline>
          </Trigger>
        </OnCondition>
      </Regime>
      <Regime name="subVbRegime">
        <TimeDerivative variable="U">
          <MathInline>- U * a</MathInline>
        </TimeDerivative>
        <TimeDerivative variable="V">
          <MathInline>V_deriv</MathInline>
        </TimeDerivative>
        <OnCondition targetRegime="subthresholdRegime">
          <Trigger>
            <MathInline>V &gt; Vb</MathInline>
          </Trigger>
        </OnCondition>
      </Regime>
      <Alias name="V_deriv">
        <MathInline>(k * (V - Vr) * (V - Vt) - U + iSyn + iExt) / Cm</MathInline>
      </Alias>
    </Dynamics>
  </ComponentClass>

which I am much more comfortable with.

from nineml-spec.

pgleeson avatar pgleeson commented on August 18, 2024

Ideally the units/dimensions of the ComponentClasses should be checked by the interpreter and throw an error when there are inconsistencies.

I don't think manipulating k & b etc. to ensure the equations are dimensionless is the best idea as this will lead to messy units having to be used in the user layer. Do you have an updated user layer equivalent of this to look at? Also it means that modellers can use other units in their model specification, e.g. b = 10 nS per mV^2 which doesn't help with making this model more portable/transparent.

Do you have a ref for the original paper this version of the model was used in? I still think the version in the 2003 paper and here: http://www.izhikevich.org/publications/whichmod.htm is the more well known version to use...

from nineml-spec.

tclose avatar tclose commented on August 18, 2024

Ideally the units/dimensions of the ComponentClasses should be checked by the interpreter and throw an error when there are inconsistencies.

Once my "sympy" branch is merged into master (which converts all lib9ml Expression objects into SymPy expressions) this should be fairly straightforward (at least in my head it is). But I don't expect I will have the chance to implement this until after the next 9ML meeting.

I don't think manipulating k & b etc. to ensure the equations are dimensionless is the best idea as this will lead to messy units having to be used in the user layer.

My take on units and dimensions is that once you commit to them you have to go all the way, and the price of that will be a little bit extra overhead. However, I think in many cases it is instructive to consider the dimensions of these parameters even if it is a little harder to translate from the initial publication.

Do you have an updated user layer equivalent of this to look at?

  <Component name="Izhikevich">
    <Definition>IzhikevichClass</Definition>
    <Property name="a" units="none">
      <SingleValue>0.02</SingleValue>
    </Property>
    <Property name="b" units="uS_per_mV2">
      <SingleValue>0.025</SingleValue>
    </Property>
    <Property name="c" units="mV">
      <SingleValue>-45.0</SingleValue>
    </Property>
    <Property name="k" units="uS_per_mV">
      <SingleValue>1</SingleValue>
    </Property>
    <Property name="Vpeak" units="mV">
      <SingleValue>25</SingleValue>
    </Property>
    <Property name="Vr" units="mV">
      <SingleValue>-55</SingleValue>
    </Property>
    <Property name="Vb" units="mV">
      <SingleValue>-55</SingleValue>
    </Property>
    <Property name="Vt" units="mV">
      <SingleValue>-40</SingleValue>
    </Property>
    <Property name="Cm" units="uF">
      <SingleValue>20</SingleValue>
    </Property>
  </Component>

Also it means that modellers can use other units in their model specification, e.g. b = 10 nS per mV^2 which doesn't help with making this model more portable/transparent.

I think the thing is that there are implied units in Izhikevich's models that get kind of glossed over. One assumes that membrane voltage is in mV and injected current is in nA and you have to work everything back from that. I think just sticking to SI units wouldn't work unless you make everything in SI units including the ports.

For example, in your approach here, http://www.neuroml.org/NeuroML2CoreTypes/Cells.html#izhikevichCell, how does the synaptic current ISyn get compared to the dimensionless state 'U'?

Do you have a ref for the original paper this version of the model was used in? I still think the version in the 2003 paper and here: http://www.izhikevich.org/publications/whichmod.htm is the more well known version to use...

It is from Izhikevich's book, although probably the email chain relating to the paper is a better place for this discussion.

from nineml-spec.

pgleeson avatar pgleeson commented on August 18, 2024

@tclose re ISyn, see https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes/Cells.xml#L1047, where ISyn is defined as dimensionless.

from nineml-spec.

tclose avatar tclose commented on August 18, 2024

But is it really appropriate for synaptic current to be dimensionless rather than of "current" dimension?

from nineml-spec.

tclose avatar tclose commented on August 18, 2024

Constants have been included in version 1.0

from nineml-spec.

pgleeson avatar pgleeson commented on August 18, 2024

Re dimensionless current, that's really the only option for this version of the Izh model, since there is no explicit concept of a membrane capacitance to properly scale a dimensional current. A current in nA say could be used and scaled out in the same way as voltage for v, but that would mean an arbitrary choice of the "proper" units of current.

This problem probably motivated in part the reformulation of the model to include a Cm term in his book, though the original formalism seems to be more popular now, in networks that are less worried about dimensional currents.

from nineml-spec.

tclose avatar tclose commented on August 18, 2024

I suppose it comes down to personal preference a little bit at the end of the day but I think I would prefer to add a unit capacitance constant and keep ISyn a current (I think the assuming units either explicitly or implicitly is unavoidable when dealing with external ports). That way you could use the same post-synaptic response component with abstract models such as this as well as more biologically detailed models.

from nineml-spec.

tclose avatar tclose commented on August 18, 2024

Just had another go at that model and came up with this

<?xml version="1.0" encoding="UTF-8"?>
<NineML xmlns="http://nineml.net/9ML/1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://nineml.net/9ML/1.0/schema/NineML_v0.2.xsd">
  <ComponentClass name="IzhikevichClass">
    <Parameter name="a" dimension="per_time"/>
    <Parameter name="b" dimension="per_time"/>
    <Parameter name="c" dimension="voltage"/>
    <Parameter name="d" dimension="voltage_per_time"/>
    <Parameter name="theta" dimension="voltage"/>
    <!-- AnalogPort or Exposure?? -->
    <AnalogReducePort name="iSyn" dimension="current" operator="+"/>
    <AnalogSendPort name="U" dimension="voltage_per_time"/>
    <AnalogSendPort name="V" dimension="voltage"/>
    <EventSendPort name="spikeOutput" mode="send"/>
    <Dynamics>
      <!-- Suggested addition Wednesday morning...-->
      <StateVariable name="V" dimension="voltage"/>
      <StateVariable name="U" dimension="voltage_per_time"/>
      <Regime name="subthresholdRegime">
        <!-- if "independent_variable" is missing, it should be assumed to be "t" -->
        <!-- Should this "ODE" be called "Rate", RateODE, "RateEqn" ??-->
        <TimeDerivative variable="U">
          <MathInline>a*(b*V - U)</MathInline>
        </TimeDerivative>
        <TimeDerivative variable="V">
          <MathInline>const1*V*V + const2*V + const3 - U + iSyn/C</MathInline>
        </TimeDerivative>
        <OnCondition>
          <Trigger>
            <MathInline>V &gt; theta</MathInline>
          </Trigger>
          <StateAssignment variable="V">
            <MathInline>c</MathInline>
          </StateAssignment>
          <StateAssignment variable="U">
            <MathInline>U+d</MathInline>
          </StateAssignment>
          <OutputEvent port="spikeOutput"/>
        </OnCondition>
      </Regime>
      <Constant name="const1" units="per_mV_ms">0.04</Constant>
      <Constant name="const2" units="per_ms">5</Constant>
      <Constant name="const3" units="mV_per_ms">140</Constant>
      <Constant name="C" units="nF">1.0</Constant>
    </Dynamics>
  </ComponentClass>
  <Component name="Izhikevich">
    <Definition>IzhikevichClass</Definition>
    <Property name="a" units="per_ms">
      <SingleValue>0.02</SingleValue>
    </Property>
    <Property name="b" units="per_ms">
      <SingleValue>0.2</SingleValue>
    </Property>
    <Property name="c" units="mV">
      <SingleValue>-65.0</SingleValue>
    </Property>
    <Property name="d" units="mV_per_ms">
      <SingleValue>8</SingleValue>
    </Property>
    <Property name="theta" units="mV">
      <SingleValue>-40.0</SingleValue>
    </Property>
  </Component>
  <Dimension name="voltage" m="1" l="2" t="-3" i="-1"/>
  <Dimension name="voltage_per_time" m="1" l="2" t="-4" i="-1"/>
  <Dimension name="per_voltage_time" m="-1" l="-2" t="2" i="1"/>
  <Dimension name="per_time" t="-1"/>
  <Dimension name="current" i="1"/>
  <Unit symbol="mV" dimension="voltage" power="-3"/>
  <Unit symbol="mV_per_ms" dimension="voltage_per_time" power="3"/>
  <Unit symbol="per_mV_ms" dimension="per_voltage_time" power="6"/>
  <Unit symbol="per_ms" dimension="per_time" power="3"/>
</NineML>

with U of dimension voltage / time (as it is in the PyNN mod file). Would this work for you?

from nineml-spec.

tangorn avatar tangorn commented on August 18, 2024

Are you sure theta is -40 and not +40?

Regards,

Anatoli.


Anatoli Gorchetchnikov, PhD
Research Assistant Professor
Neuromorphics Lab
Boston University
677 Beacon St
Boston, MA, USA, 02215
+1-617-353-8771


From: Tom Close [[email protected]]
Sent: Wednesday, March 18, 2015 10:28 PM
To: INCF/nineml
Subject: Re: [nineml] Add "Constant" tag for numerical constants (#15)

Just had another go at that model and came up with this





















a_(b_V - U)


const1_V_V + const2*V + const3 - U + iSyn/C



V > theta


c


U+d




0.04
5
140
1.0



IzhikevichClass

0.02


0.2


-65.0


8


-40.0











with U of dimension voltage / time (as it is in the PyNN mod filehttps://github.com/NeuralEnsemble/PyNN/blob/master/src/neuron/nmodl/izhikevich.mod). Would this work for you?

β€”
Reply to this email directly or view it on GitHubhttps://github.com//issues/15#issuecomment-83269581.

from nineml-spec.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.