-
Notifications
You must be signed in to change notification settings - Fork 370
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
Implemented requires_symmetric flag for synapse models #524
Changes from 11 commits
6cd11eb
0d8f108
d523e0d
14de8fa
cfe0f3e
1f7a3de
d93ab76
047c6f8
7a777ea
71e0755
ce72b4b
bd646a6
20c53c9
7216fec
4a3f41d
897e6d1
111dd31
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -382,9 +382,19 @@ nest::ConnBuilder::change_connected_synaptic_elements( index sgid, | |
void | ||
nest::ConnBuilder::connect() | ||
{ | ||
if ( kernel().model_manager.connector_requires_symmetric( synapse_model_ ) | ||
&& not symmetric_ && not is_symmetric() ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I find this still confusing, and I fear anyone reading this in five years time will not feel enlightened. How about renaming if ( kernel().model_manager.connector_requires_symmetric( synapse_model_ )
and not ( is_symmetric() or make_symmetric_ ) ) That seems more readable to me. |
||
{ | ||
throw BadProperty( | ||
"This synapse model requires symmetric (or suitable uniform " | ||
"all-to-all) connections" ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "suitable" is unclear. How about "Connections with synapse model {0} can only be created as one-to-one connections with "make_symmetric" set to true or as all-to-all connections with equal source and target populations and default or scalar parameters."? |
||
} | ||
|
||
if ( symmetric_ && not supports_symmetric() ) | ||
{ | ||
throw NotImplemented( | ||
"This connection rule does not support symmetric connections." ); | ||
} | ||
|
||
if ( pre_synaptic_element_name != "" && post_synaptic_element_name != "" ) | ||
{ | ||
|
@@ -580,6 +590,27 @@ nest::ConnBuilder::set_post_synaptic_element_name( std::string name ) | |
post_synaptic_element_name = name; | ||
} | ||
|
||
bool | ||
nest::ConnBuilder::all_parameters_scalar_() const | ||
{ | ||
bool all_scalar = true; | ||
if ( weight_ ) | ||
{ | ||
all_scalar = all_scalar && weight_->is_scalar(); | ||
} | ||
if ( delay_ ) | ||
{ | ||
all_scalar = all_scalar && delay_->is_scalar(); | ||
} | ||
for ( ConnParameterMap::const_iterator it = synapse_params_.begin(); | ||
it != synapse_params_.end(); | ||
++it ) | ||
{ | ||
all_scalar = all_scalar && it->second->is_scalar(); | ||
} | ||
return all_scalar; | ||
} | ||
|
||
void | ||
nest::OneToOneBuilder::connect_() | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,6 +102,8 @@ class ConnBuilder | |
void set_pre_synaptic_element_name( std::string name ); | ||
void set_post_synaptic_element_name( std::string name ); | ||
|
||
bool all_parameters_scalar_() const; | ||
|
||
int change_connected_synaptic_elements( index, index, const int, int ); | ||
|
||
virtual bool | ||
|
@@ -110,6 +112,12 @@ class ConnBuilder | |
return false; | ||
} | ||
|
||
virtual bool | ||
is_symmetric() const | ||
{ | ||
return false; | ||
} | ||
|
||
protected: | ||
//! Implements the actual connection algorithm | ||
virtual void connect_() = 0; | ||
|
@@ -240,6 +248,12 @@ class AllToAllBuilder : public ConnBuilder | |
{ | ||
} | ||
|
||
bool | ||
is_symmetric() const | ||
{ | ||
return *sources_ == *targets_ && all_parameters_scalar_(); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is not always true. If all-to-all has a randomized synapse parameter, it is no longer automatically symmetric. We will still have a backward connection for each forward connection, but their properties will differ. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @heplesser Good catch, I did not think of that. Is there any easy way to determine if all-to-all uses randomized synapse parameters? I am thinking of a solution where this functions first checks if there are any randomized parameters involved (if so throws an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above, array parameters are also problematic because costly to check. |
||
|
||
protected: | ||
void connect_(); | ||
void sp_connect_(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@janhahne It seems to me we get a bit of an inflation here:
symmetric_
,is_symmetric()
andsupports_symmetric()
. Could we at least integratesymmetric_
andis_symmetric()
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@heplesser I agree that this is a bit unfortunate, but all three of them serve a purpose:
symmetric_
is the property of the created connection (issymmetric
set totrue
orfalse
?)supports_symmetric
determines if a specific ConnBuilder supports the creation of symmetric connection. This is only implemented for the OnetoOne builder.is_symmetric
is needed to allow all-to-all connections without settingsymmetric
totrue
. Otherwise the creation of all-to-all connection would not be possible at all for gap-junctions (all-to-all does not supportsymmetric=true
)Unless we want to prohibit any kind of all-to-all connections for gap-junctions I do not see any way of reducing the number of symmetric parameters. Or is there any solution that I am not thinking of?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@janhahne I wonder if we should take a step back and think this through once more. All-to-all is inherently symmetric, provided source and target populations are identical and all synapses are created with the same parameters. Guaranteeing symmetric connections when randomized parameters are used would be very difficult, and for explicit parameter arrays it would require very cumbersome checks for matrix symmetry.
So I would think the best approach might be to prohibit both array and random parameters if the synapse model is derived from
gap_junction
, and to also require that source and target populations are identical. Then, you get symmetry for free. @jougs Is it possible to compare two GIDCollections for equality?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@heplesser Good points! I think now we found all conditions that need to be checked in order to ensure that an all-to-all connection is symmetric. I would also vote for a solution where we prohibit both array and random parameters, rather than allowing those in general and check them for symmetry case by case.
So I would imagine our solution like this: Change the
is_symmetric()
function of the all-to-all ConnBuilder toand adjust the
BadProperty
-Message to"This synapse model requires symmetric (or suitable uniform all-to-all) connections"
The check in
is_symmetric()
will only be performed, if the first two conditions of the if-statement are met, ergo only if a synapse model requires symmetric connections and thesymmetric
flag is set tofalse
Would you agree on this general plan? In this case we would need to figure out how to implement the two
if
statements. @jougs could help with this first one, any idea how to check for the second one most efficiently?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@janhahne @jougs This looks good, although I think that we could simplify the method to
The other method would be something like
We then need in
ConnParameter
and extra methodis_scalar()
that returns true only forScalar{Double,Integer}Parameter
. We cannot use existing methods sinceis_array()
returns false for random numbers andnumber_of_values()
returns 0 for scalar and random.