-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add "Constant" tag for numerical constants #15
Comments
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. |
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. |
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 One alternative might be to add an explicit |
ok with me. |
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 Actual constants like |
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 notifications@github.com wrote:
For the first term, k is a parameter that probably holds all the relevant At least, I would suggest a different symbol than * to indicate the That's my immediate reaction to that idea, anyway. What do others think? |
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 <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 > 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 < 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 > 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 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 |
On further consideration, I don't think that multiplying <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 > 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 < 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 > 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. |
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... |
Once my "sympy" branch is merged into master (which converts all lib9ml
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.
<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>
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 For example, in your approach here, http://www.neuroml.org/NeuroML2CoreTypes/Cells.html#izhikevichCell, how does the synaptic current
It is from Izhikevich's book, although probably the email chain relating to the paper is a better place for this discussion. |
@tclose re ISyn, see https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes/Cells.xml#L1047, where ISyn is defined as dimensionless. |
But is it really appropriate for synaptic current to be dimensionless rather than of "current" dimension? |
Constants have been included in version 1.0 |
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. |
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. |
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 > 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 |
Are you sure theta is -40 and not +40?Regards, Anatoli. Anatoli Gorchetchnikov, PhD From: Tom Close [notifications@github.com] Just had another go at that model and came up with this
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? — |
In math-inline/mathml expressions, only allow access to parameters/state-variables and aliases not numerical constants with units (dimensionless constants would be permitted to allow 1/exp(-x) and the like). Constants would then be defined through aliases or perhaps it would be better to make an explicit “constant” tag eg.
The text was updated successfully, but these errors were encountered: