Comments (17)
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.
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.
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.
I think that constants should perhaps be included in v1.
ok with me.
from nineml-spec.
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.
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.
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 > 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 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.
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 > 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.
from nineml-spec.
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.
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.
@tclose re ISyn, see https://github.com/NeuroML/NeuroML2/blob/master/NeuroML2CoreTypes/Cells.xml#L1047, where ISyn is defined as dimensionless.
from nineml-spec.
But is it really appropriate for synaptic current to be dimensionless rather than of "current" dimension?
from nineml-spec.
Constants have been included in version 1.0
from nineml-spec.
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.
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.
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 voltage / time
(as it is in the PyNN mod file). Would this work for you?
from nineml-spec.
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)
- Defining NineML Core HOT 1
- Impulse ports HOT 1
- Separate Dynamics and ConnectionRule Components into different root tags HOT 5
- Sampling random variables HOT 1
- Connection re mapping via proxies HOT 2
- Cell packing density as a unit. HOT 1
- Reintroducing the 'Quantity' element HOT 1
- Integer and "sized" Parameters and Property ports
- Using Reference instead of Definition and Prototype elements
- Changing "name" of Unit to 'name' instead of 'symbol' HOT 1
- Builtin functions: abs (fabs), ceil, floor, round?
- Nonlinear interactions between spikes on the same stream (accessing spike buffers) HOT 2
- Inactivation of OnEvent transitions HOT 1
- Resolution of simultaneous transitions HOT 1
- Refer to units using Reference elements
- Replace universal Reference type with specific <Element-type>Reference types
- Use HDF5 array structures for ArrayValue HOT 1
- Support for non-standard unit scales (e.g. min, hour, days)
- Is the time variable `t` permissible in TimeDerivative expressions? HOT 1
- NineML spec GitHub pages seem broken
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nineml-spec.