Skip to content

Commit 2a5ba7a

Browse files
author
Andrew Davison
committed
Implement __eq__ and __ne__ for PopulationView
Should fix #622.
1 parent 822ec75 commit 2a5ba7a

2 files changed

Lines changed: 32 additions & 9 deletions

File tree

pyNN/common/populations.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ def get(self, parameter_names, gather=False, simplify=True):
266266
"""
267267
Get the values of the given parameters for every local cell in the
268268
population, or, if gather=True, for all cells in the population.
269-
269+
270270
Values will be expressed in the standard PyNN units (i.e. millivolts,
271271
nanoamps, milliseconds, microsiemens, nanofarads, event per second).
272272
"""
@@ -429,7 +429,7 @@ def record(self, variables, to_file=None, sampling_interval=None):
429429
430430
If specified, `to_file` should be either a filename or a Neo IO instance and `write_data()`
431431
will be automatically called when `end()` is called.
432-
432+
433433
`sampling_interval` should be a value in milliseconds, and an integer
434434
multiple of the simulation timestep.
435435
"""
@@ -479,7 +479,7 @@ def write_data(self, io, variables='all', gather=True, clear=False, annotations=
479479
simulated on that node.
480480
481481
If `clear` is True, recorded data will be deleted from the `Population`.
482-
482+
483483
`annotations` should be a dict containing simple data types such as
484484
numbers and strings. The contents will be written into the output data
485485
file as metadata.
@@ -533,7 +533,7 @@ def get_gsyn(self, gather=True, compatible_output=True):
533533
def get_spike_counts(self, gather=True):
534534
"""
535535
Returns a dict containing the number of spikes for each neuron.
536-
536+
537537
The dict keys are neuron IDs, not indices.
538538
"""
539539
# arguably, we should use indices
@@ -915,6 +915,25 @@ def index_in_grandparent(self, indices):
915915
else:
916916
return indices_in_parent
917917

918+
def __eq__(self, other):
919+
"""
920+
Determine whether two views are the same.
921+
"""
922+
return not self.__ne__(other)
923+
924+
def __ne__(self, other):
925+
"""
926+
Determine whether two views are different.
927+
"""
928+
# We can't use the self.mask, as different masks can select the same cells
929+
# (e.g. slices vs arrays), therefore we have to use self.all_cells
930+
if isinstance(other, PopulationView):
931+
return self.parent != other.parent or not numpy.array_equal(self.all_cells, other.all_cells)
932+
elif isinstance(other, Population):
933+
return self.parent != other or not numpy.array_equal(self.all_cells, other.all_cells)
934+
else:
935+
return True
936+
918937
def describe(self, template='populationview_default.txt', engine='default'):
919938
"""
920939
Returns a human-readable description of the population view.

pyNN/connectors.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ def _standard_connect(self, projection, connection_map_generator, distance_map=N
191191
# `source_mask` - boolean numpy array, indicating which of the pre-synaptic neurons should be connected to,
192192
# or a single boolean, meaning connect to all/none of the pre-synaptic neurons
193193
# It can also be an array of addresses
194-
_proceed = False
194+
_proceed = False
195195
if source_mask is True or source_mask.any():
196196
_proceed = True
197197
elif type(source_mask) == numpy.ndarray:
@@ -206,7 +206,7 @@ def _standard_connect(self, projection, connection_map_generator, distance_map=N
206206
source_mask = numpy.arange(projection.pre.size, dtype=int)
207207
elif source_mask.dtype == bool:
208208
source_mask = source_mask.nonzero()[0]
209-
209+
210210
# Evaluate the lazy arrays containing the synaptic parameters
211211
connection_parameters = {}
212212
for name, map in parameter_space.items():
@@ -275,6 +275,10 @@ def __init__(self, allow_self_connections=True, safe=True,
275275
def connect(self, projection):
276276
if not self.allow_self_connections and projection.pre == projection.post:
277277
connection_map = LazyArray(lambda i, j: i != j, shape=projection.shape)
278+
# there is a more complicated scenario, where we connect two different
279+
# views of the same population. In this case, something other than i != j
280+
# will be needed. It should at least be documented that we currently
281+
# don't handle this situation.
278282
elif self.allow_self_connections == 'NoMutual' and projection.pre == projection.post:
279283
connection_map = LazyArray(lambda i, j: i > j, shape=projection.shape)
280284
else:
@@ -555,7 +559,7 @@ class FromFileConnector(FromListConnector):
555559
556560
# columns = ["i", "j", "weight", "delay", "U", "tau_rec"]
557561
558-
Note that the header requires `#` at the beginning of the line.
562+
Note that the header requires `#` at the beginning of the line.
559563
560564
`distributed`:
561565
if this is True, then each node will read connections from a file
@@ -1011,7 +1015,7 @@ def connect(self, projection):
10111015

10121016
# Assume that targets are equally distributed over processes
10131017
targets_per_process = int(len(projection.post) / num_processes)
1014-
1018+
10151019
# Calculate the number of synapses on each process
10161020
bino = RandomDistribution('binomial',
10171021
[self.n, targets_per_process / len(projection.post)],
@@ -1027,7 +1031,7 @@ def connect(self, projection):
10271031
sum_dist += targets_per_process
10281032
sum_partitions += num_conns_on_vp[k]
10291033

1030-
# Draw random sources and targets
1034+
# Draw random sources and targets
10311035
connections = [[] for i in range(projection.post.size)]
10321036
possible_targets = numpy.arange(projection.post.size)[projection.post._mask_local]
10331037
for i in range(num_conns_on_vp[rank]):

0 commit comments

Comments
 (0)