-
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
Proposal for generic ConnectionRule syntax #72
Comments
Some examples <ComponentClass name="AllToAll">
<ConnectionRule/>
</ComponentClass> <ComponentClass name="OneToOne">
<ConnectionRule>
<ConnectCondition>
<MathInline>i == j</MathInline><!-- Reserved names, this could change -->
</ConnectCondition>
</ConnectionRule>
</ComponentClass> <ComponentClass name="ExplicitList">
<Parameter name="one_or_zeros" dimension="dimensionless"/>
<ConnectionRule>
<ConnectCondition>
<MathInline>one_or_zeros</MathInline>
</ConnectCondition>
</ConnectionRule>
</ComponentClass> <ComponentClass name="ExplicitProbability">
<Parameter name="p" dimension="dimensionless"/>
<ConnectionRule>
<ConnectCondition>
<MathInline>r < p</MathInline>
</ConnectCondition>
<RandomVariable name="r" units="none">
...uncertml...
</RandomVariable>
</ConnectionRule>
</ComponentClass> <ComponentClass name="OneDDistanceDependent">
<Parameter name="threshold" dimension="length"/>
<PropertyReceivePort name="src_x_pos" dimension="length"/>
<PropertyReceivePort name="dest_x_pos" dimension="length"/>
<ConnectionRule>
<ConnectCondition>
<MathInline>src_x_pos - dest_x_pos < threshold</MathInline>
</ConnectCondition>
</ConnectionRule>
</ComponentClass> or <ComponentClass name="OneDDistanceDependent">
<Parameter name="threshold" dimension="length"/>
<SourceReceivePort name="src_x_pos" dimension="length"/>
<DestinationReceivePort name="dest_x_pos" dimension="length"/>
<ConnectionRule>
<ConnectCondition>
<MathInline>src_x_pos - dest_x_pos < threshold</MathInline>
</ConnectCondition>
</ConnectionRule>
</ComponentClass> <ComponentClass name="SmallWorld">
<Parameter name="k" dimension="dimensionless"/>
<ConnectionRule>
<SelectConnections referencePoint="source" stage="0">
<Number>
<MathInline>k</MathInline>
</Number>
<Preference order="ascending">
<MathInline>abs(i - j)</MathInline>
</Preference>
</SelectConnections>
<ConnectCondition stage="1">
</ConnectionCondition>
</ConnectionRule>
</ComponentClass> <ComponentClass name="RandomFanOut">
<Parameter name="number" dimension="dimensionless"/>
<ConnectionRule>
<SelectConditions referencePoint="source">
<Number>
<MathInline>number</MathInline>
</Number>
<Preference order="ascending">
<MathInline>r</MathInline>
</Preference>
</SelectConditions>
<RandomVariable name="r" units="none">
...uncertml...
</RandomVariable>
</ConnectionRule>
</ComponentClass> <ComponentClass name="RandomNearestNeighbour">
<Parameter name="mean" dimension="dimensionless"/>
<Parameter name="variance" dimension="dimensionless"/>
<ConnectionRule>
<SelectConditions referencePoint="source">
<Number>
<MathInline>round(r)</MathInline>
</Number>
<Preference order="ascending">
<MathInline>abs(i - j)</MathInline>
</Preference>
</SelectConditions>
<RandomVariable name="r" units="none">
<un:NormalDistribution>
<un:mean>mean</un:mean>
<un:variance>variance</un:variance>
</un:NormalDistribution>
</RandomVariable>
</ConnectionRule>
</ComponentClass> |
The Committee has decided that the NineML core should support OneToOne AllToAll and ExplicitList connectivity, with a standard connection scheme in the Standard Extensions and all other connection schemes are further Extensions. |
The Committee decided that there should be a Standard Extension ConnectionRule format, however this is a complex issue and requires consideration. Proposals for a format and challenging connection schemes to test these rules will be added below. |
Proposal: There are two types of set here - nodes (neurons) and edges (connections) - and these can be iterated over using the ForEach tags. How sets are describes is not shown here but could be any set selection format (MathInline CSA etc...) Within the ForEachEdge there are reserved set i,j and c - the current source node, destination node and edge respectively <Parameter name=“p”/>
<DefineNodeSet name=“all_source”>
<AllSource…/>
</DefineNodeSet>
<ForEachNode set=“all_source”>
<DefineEdgeSet name=“local”>
<LocalSet…/>
</DefineEdgeSet>
<DefineEdgeSet name=“not_local”>
<NotLocal…./>
</DefineEdgeSet>
<ForEachEdge set=“local”>
<Choose>
<Condition>
<MathInline>rand() < p</MathInline>
<DefineEdgeSet name=“t”>
<One randomly from NotLocal and current…/>
</DefineEdgeSet>
<AddEdges set=“t”/>
</Condition>
<Otherwise>
<AddEdges set=“c”/>
</Otherwise>
</Choose>
</ForEachEdge>
</ForEachNode> |
Sorry Alex, I don't quite get your proposal, I think you will need to explain it to me. |
On the way home I came up with a modified version of what I initially proposed along the lines of what Paul was going for I think, where you are able to nest “select” elements within each other. The nice thing about doing this (apart from the syntactic cleanliness) is that it allows you to scope variables (in a typical way) that are only available to subsequent selection stages, such as the number of selections made in the current stage. The small world example would then look like this, <ConnectionRuleClass name="smallWorld">
<Parameter name="k" dimension="dimensionless"/>
<Parameter name="beta" dimension="dimensionless"/>
<Select action="add">
<Mask>
<!-- Connect each cell with all cells within k indices on either side.
-->
<MathInline>abs(i - j) < k && i != j</MathInline>
</Mask>
<Select action="remove">
<Mask>
<!-- Randomly select cells from the provisionally connected set to
remove. -->
<MathInline>r < beta</MathInline>
</Mask>
<RandomVariable name="r" units="none">
<un:UniformDistribution xmlns:un="www.uncertml.org/distributions">
<un:low>0</un:low>
<un:high>1</un:high>
</un:UniformDistribution>
</RandomVariable>
<SelectionMask name="wasRemoved" scope="current"/>
<SelectionSize name="numRemoved" perspective="source" scope="current"/>
<!-- 'scope' can either be 'current' to specify only the selections in
the current scope (i.e. connections to be connected if action="add"
or connections to be removed if action="remove"), or 'all' to
represent all connections that have been provisionally connected -->
<Select action="add">
<Number perspective="source">
<MathInline>numRemoved</MathInline>
</Number>
<!-- If you want to guarantee that the removed connections are not
chosen again. If there are not enough connections in the mask then
the full mask is returned. -->
<Mask>
<MathInline>!wasRemoved</MathInline>
</Mask>
or
<!-- If you would prefer that the removed connections are not
chosen again but the number of connections overrides it -->
<Preference>
<MathInline>wasRemoved ? 0 : 1</MathInline>
</Preference>
or
<!-- If it doesn't matter if the removed connections are added back
in you can just omit the Mask and Preference tags -->
</Select>
</Select>
</Select>
</ConnectionRuleClass> so for the small-world connector as it is implemented in PyNN the XML would look like <ConnectionRuleClass name="smallWorld">
<Parameter name="k" dimension="dimensionless"/>
<Parameter name="beta" dimension="dimensionless"/>
<Select action="add">
<Mask>
<MathInline>abs(i - j) < k && i != j</MathInline>
</Mask>
<Select action="remove">
<Mask>
<MathInline>r < beta</MathInline>
</Mask>
<RandomVariable name="r" units="none">
<un:UniformDistribution xmlns:un="www.uncertml.org/distributions">
<un:low>0</un:low>
<un:high>1</un:high>
</un:UniformDistribution>
</RandomVariable>
<SelectionSize name="numRemoved" perspective="source" scope="current"/>
<Select action="add">
<Number perspective="source">
<MathInline>numRemoved</MathInline>
</Number>
</Select>
</Select>
</Select>
</ConnectionRuleClass> I think this is pretty neat as only requires 5 specialty connection rule tags and leads to pretty compact examples so far, and I reckon it will also be quite general. So if people could post some tricky use cases up here I will put it through its paces. If we really wanted to amp up the power maybe we could even allow recursion within this syntax, which should make the schemers (i.e. Ivan) happy I imagine. For example <!-- Mock selection rule using recursion. Randomly assigns connections with
probability 'a' then iteratively removes a connection from each source
cell (one-shell at a time) until the total number of connections is less than
or equal to 'b' -->
<ConnectionRuleClass name="RecursingConnectionRule">
<Parameter name="a" dimension="dimensionless"/>
<Parameter name="b" dimension="dimensionless" container="single"/>
<Select action="add">
<Mask>
<MathInline>r < a</MathInline>
</Mask>
<RandomVariable name="r" units="none">
<un:UniformDistribution xmlns:un="www.uncertml.org/distributions">
<un:low>0</un:low>
<un:high>1</un:high>
</un:UniformDistribution>
</RandomVariable>
<Select action="remove">
<Number perspective="source">
<MathInline>1</MathInline>
</Number>
<SelectionSize name="totalNumSelections" scope="all"/>
<RecurseUp>
<MathInline>totalNumSelections > b ? 1 : 0</MathInline>
</RecurseUp>
</Select>
</Select>
</ConnectionRuleClass> However, this is a getting a bit exotic and would probably be something to look at in Version 3.0 I imagine. The basic examples that were posted above in the new format would look like <!-- New Syntax examples -->
<ConnectionRuleClass name="AllToAll">
<Select action="add"/>
</ConnectionRuleClass>
<ConnectionRuleClass name="OneToOne">
<Select action="add">
<Mask>
<MathInline>i == j</MathInline>
</Mask>
</Select>
</ConnectionRuleClass>
<ConnectionRuleClass name="Explicit">
<Parameter name="list" dimension="dimensionless"/>
<Select action="add">
<Mask>
<MathInline>list != 0</MathInline><!-- Could use just list if non-zero integers are interpreted as true as they are in C/C++/Python/etc.. -->
</Mask>
</Select>
</ConnectionRuleClass>
<ConnectionRuleClass name="Probabilistic">
<Parameter name="p" dimension="dimensionless"/>
<Select action="add">
<Mask>
<MathInline>r < p</MathInline>
</Mask>
<RandomVariable name="r" units="none">
<un:UniformDistribution xmlns:un="http://www.uncertml.org/1.0">
<un:low>0</un:low>
<un:high>1</un:high>
</un:UniformDistribution>
</RandomVariable>
</Select>
</ConnectionRuleClass>
<ConnectionRuleClass name="OneDDistanceDependent">
<Parameter name="threshold" dimension="length"/>
<PropertyReceivePort name="src_x_pos" dimension="length" container="source"/>
<PropertyReceivePort name="dest_x_pos" dimension="length" container="destination"/>
<Select action="add">
<Mask>
<MathInline>abs(src_x_pos - dest_x_pos) < threshold</MathInline>
</Mask>
</Select>
</ConnectionRuleClass>
<ConnectionRuleClass name="FixedNumber">
<Parameter name="number" dimension="dimensionless" container="single"/>
<Select action="add">
<Number>
<MathInline>number</MathInline>
</Number>
<!-- If a Preference element is not provided all connections are given
equal preference, and are therefore randomly selected from -->
</Select>
</ConnectionRuleClass>
<ConnectionRuleClass name="RandomFanOut">
<Parameter name="number" dimension="dimensionless" container="source"/>
<Select action="add">
<Number perspective="source">
<MathInline>number</MathInline>
</Number>
</Select>
</ConnectionRuleClass>
<ConnectionRuleClass name="RandomFanIn">
<Parameter name="number" dimension="dimensionless" container="destination"/>
<Select action="add">
<Number perspective="destination">
<MathInline>number</MathInline>
</Number>
</Select>
</ConnectionRuleClass> |
The select "action" attribute could also default to "add" to make it a bit cleaner for most cases |
I had a brief look at the 2012 CSA paper again (http://link.springer.com/article/10.1007%2Fs12021-012-9146-1) and reminded myself why I didn't think it would be a good fit for our purposes. If I understand it correctly (which I may not) all connections are built out of the following primitives (plus set and arithmetic operations)
which doesn't appear to cover all the cases we will need. For example, the distance based metric can't handle ellipse or box-shaped connectivity patterns (which appear frequently in our models in the lab), and the random selection operator cannot preference particular connections over others. I also find the examples a little complex for non-mathematicians. For an example, have a look at the "Patchy Connectivity" section in the discussion of the paper. This example also appears to be defining the positions of the destination cells, which would make more sense for us to do within the population, so the mapping from CSA -> |
On Sat, Apr 4, 2015 at 5:30 AM, Tom Close [email protected] wrote:
I don't want to interfer in the committees discussion, but let me clarify To summarize: Is CSA currently a well-constrained standard language to
This example demonstrates how one can compute with geometry functions and Best regards,
|
A, sorry, I forgot one comment: Yes, CSA can be complex for On Sat, Apr 4, 2015 at 11:04 AM, Mikael Djurfeldt [email protected]
|
Not at all. One of the main reasons we discuss everything via GitHub is to encourage input from the community, especially experts in the field. In fact, I had planned to write to you and invite you to comment on my post but you beat me to it ;)
I was thinking some more about this and was wondering why you need the Disc operator at all. Couldn't you just use the threshold operator and pass it a function that is only below zero inside the disc (i.e. f(x,y) = sqrt(x^2 + y^2) - R)? Is this the kind of metric you were referring to for the box connectivity?
I'm sorry if my post came across as being critical of CSA, it wasn't my intention, particularly as I think you have done some really nice work with it and being able to express connection rules in formal mathematics could be very useful. I should have clarified what I meant by "our purposes" when posting outside of the scope of the discussion we had the meeting. I believe the approach we have adopted for 9ML in general matches the one you have been advocating for connection rules. That is to define a core set of "primitives" required to describe network simulations (which all 9ML-compliant simulators are required to implement) and then add layers (for want of another word) of "extensions" (which map onto the core) on top of that (see #92). In the case of the connection rule syntax, we decided that the core will consist of an explicit connection lists, and in a concession to practical considerations, 'all-to-all' and 'one-to-one' connectivity operators. On top of the core we plan to add a 9ML-committee-supported "standard extension" layer, which is what the syntax proposed above is designed for (i.e. "our purposes"). The 9ML community would then be encouraged to add further "community extensions", which can decide to either map onto the standard extensions or directly onto the core (or both). Bearing in mind that some simulators may implement the standard extension layer directly to optimise their performance (e.g. distribute random number generation across multiple cores), so it would be beneficial to map onto standard extensions where possible. In the committee meeting last week, we all agreed that it would be great to have 9ML support for CSA, but the debate was whether CSA was suitable to serve as the standard extension for connection rules or whether it should be left as a community extension. My feeling was that we should design our own simpler syntax for the standard extension layer, as the point of standard extensions is to provide convenient, easy-to-understand access to the majority of the core, and leave you to develop a CSA community extension. Was this what you had in mind?
Definitely and I think it is neat that CSA is able to represent that example so concisely. However, for a standard such as 9ML, which is aiming to provide descriptions that are accessible to the wider neuroscience community, I think it might be a little dense (I would have struggled to follow it without the explanation in the text).
Okay, sorry I must have misread it. How are the positions of the source cells defined?
I think we are on the same page then, sorry that I didn't explain where I was coming from better in my previous post. |
Sorry, one more thing Mikael. I was wondering whether you might be able to post some particularly tricky connectivity patterns you have come across to this thread. As it would be great to have a set of difficult examples to test out new proposals on. |
Another example: randomly selecting 20 connections on average, with a variance of 4, for each cell <ConnectionRuleClass name="OneToOne">
<Select action="add">
<Number perspective="source">
<MathInline>round(r)</MathInline>
</Number>
<RandomVariable name="r" units="none">
<un:NormalDistribution xmlns:un="http://www.uncertml.org/1.0">
<un:mean>20</un:mean>
<un:variance>4</un:high>
</un:NormalDistribution>
</RandomVariable>
</Select>
</ConnectionRuleClass> |
Hi Tom, I like this format. It is more or less what I was thinking. In my view as long as this syntax is able to capture a good range of connection types then anything that is beyond the scope can be delayed until V3.0 and instead converted to an explicit list. |
Great, I have started implementing this in a branch of lib9ML, and we will attempt to port the models we have in the lab to it over the next few weeks. However, it would be great to a have a list of theoretically minded connection rules to test it out on (most of our networks could be implemented by distanced-based masks I think), so if anyone comes across on they think will be tricky could they please post a link to it on the thread. |
@tclose I am responding to your mail to the NEST Developer list a couple of weeks ago. It's been quite a few years since I was actively involved in 9ML, so I am unfortunately not entirely up to date on your work. We will certainly keep an eye on 9ML when working on the connection specification and creation in NEST. For now, probably the best way to integrate 9ML connectivity descriptions with NEST would be to use the connection generator interface to NEST that Jochen Eppler, Mikael Djurfeldt, and Andrew Davison developed (http://dx.doi.org/10.3389/fninf.2014.00043). It provides an entirely general interface from NEST to libraries generating connectivity. I suppose a first important step would be to get things to work, e.g., by interfacing a Python implementation of 9ML with the NEST connection generator interface. To make this useful for real work, especially for large networks, efficiency will become a crucial concern and that might require rather simulator-specific code generation for optimal performance. But that bridge can be crossed when one gets there. Btw, in the last example above, there is a tiny chance that |
Since this is already written up in the v2.0 spec I sent around I will keep it short here (checkout my dev2.0 branch for the latest version with references to the related github issues).
The list of elements that would be valid within
ConnectionRule
ConnectCondition
SelectConnections
Alias
Constant
RandomVariable
Piecewise
of which only
ConnectCondition
andSelectConnections
are specific to connection rules.ConnectCondition
would contain a boolean math-inline expression, which determines whether a source and destination cell are "provisionally" connected (or non-provisionally if there isn't aSelectConnections
element). The expression could be dependent on parameters of theConnectionRule
class, random variables, and properties and indices of the cells in the population class via ports. IfConnectCondition
is not provided then all-to-all connections are connected.A subset of the provisionally connected connections (which would be all possible if
ConnectCondition
is not provided), can be selected viaSelectConnections
elements. Where a specific number (which can be derived from a random distribution) of connections are made either to a destination cell, from a source cell or in total. Connections can be placed in order of preference via aPreference
expression, which evaluates to a real number and is sorted from lowest to highest. Otherwise ifPreference
is not provided the connections are chosen randomly from the provisionally connected connections.Explicit connections lists could be passed as a binary mask from a parameter straight into the
ConnectCondition
, although we would want to have sparse array support for external data files in place for this to be practical.My thinking is that this should be generic enough to handle most connection rules, and more complex algorithms could be implemented via extensions if required. Let me know what you think.
The text was updated successfully, but these errors were encountered: