Indexing in PopulationViews

15 views
Skip to first unread message

Emma

unread,
Oct 23, 2025, 12:43:45 PMOct 23
to ANNarchy
Dear Julien, 

I encountered results that I could not figure out at all in a model simulation. In an attempt to build a minimal example to reproduce what I thought could boil down to an indexing issue with PopulationViews, I found something quite strange.

I am using ANNarchy 4.8.2.5

from ANNarchy import *
import numpy as np



LeakyIntegratorNeuron = Neuron(
parameters = """
tau = 10.0
baseline = -0.2
""",
equations = """
tau * dmp/dt + mp = baseline + sum(exc)
r = pos(mp)
""")


neurons = Population(geometry=10, neuron=LeakyIntegratorNeuron, name='neurons')
print(neurons.ranks)

popview_post = neurons.neuron(7) + neurons.neuron(8) + neurons.neuron(9)
print(popview_post.ranks)

popview_post = neurons[7:10]
print(popview_post.ranks)

This code prints these ranks:
[0 1 2 3 4 5 6 7 8 9]
[8 9 7]
[7 8 9]

I believe the issue arises from the use of a set when adding PopulationViews
 def __add__(self, other):
        """Allows to join two PopulationViews if they have the same population."""
        from ANNarchy.core.Neuron import IndividualNeuron
        if other.population == self.population:
            if isinstance(other, IndividualNeuron):
                tmp = list(set(list(self.ranks) + [other.rank]))
                return PopulationView(self.population, np.array(tmp))
            elif isinstance(other, PopulationView):
                tmp = list(set(list(self.ranks) + list(other.ranks)))
                return PopulationView(self.population, np.array(tmp))
        else:
            Messages._error("can only add two PopulationViews of the same population.")

But I'm wondering if that can be true. It was really unexpected behaviour for me, especially since according to the examples in the  docs I was expecting both methods to produce an equivalent result.  

I am using two PopulationViews of the same population to define pre and post of a Projection and was not getting the results I expected. 

Thank you so much for taking a look. 
Cheers!
Emma 

Helge Dinkelbach

unread,
Oct 23, 2025, 1:06:21 PMOct 23
to Emma, ANNarchy
Dear Emma,

Indeed, the behavior is not the expected one. I assume, that the set() call in:

list(set(list(self.ranks) + [other.rank]))

is the culprit. Typically, we use this to remove doublons, which could be added by repeated calls, or having the same rank in both added PopulationView by accident. Unfortunately, the result of set() is not ordered (by definition), more precise, it can be ordered but is not guaranteed. Anyways, this implementation would not cover, when the last addition would introduce a new doublon ... I will have to take a closer look on that tomorrow.

The slice operator works differently and therefore does not mess up the ordering, therefore, should always produce the correct result.

I will verify this tomorrow, thank you already for bringing up this issue.

Best regards,
Helge

--
You received this message because you are subscribed to the Google Groups "ANNarchy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to annarchy+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/annarchy/148ab939-830d-40ca-acfc-af8a273eb47an%40googlegroups.com.

Helge Dinkelbach

unread,
Oct 24, 2025, 3:49:37 AMOct 24
to ANNarchy
Dear Emma,

the bug was caused by the set() as you suggested, more precise a missing follow-up sort of the new ranks array.

The bugfix (https://github.com/ANNarchy/ANNarchy/commit/6777787) will be part of the upcoming 5.0 release. This release will introduce a reworked user interface. However, as the new release possibly break ANNarchy 4.8 code, we also have a "legacy" branch which I also updated (https://github.com/ANNarchy/ANNarchy/commit/bf6e68f).

I extended the list of your examples, which work fine now:

* popview_post = neurons.neuron(7) + neurons.neuron(8) + neurons.neuron(9) + neurons.neuron(1)
  results in [1,7,8,9]

* popview_post = neurons[7:9] + neurons.neuron(9) + neurons.neuron(1)
  results in [1,7,8,9]

* popview_post = neurons[7:10] + neurons.neuron(1)
  results in [1,7,8,9]

Besides, the removal of doublons work already (I misread the brackets, sorry if my E-Mail yesterday caused confusion on that)
* popview_post = neurons[7:10] + neurons.neuron(1) + neurons.neuron(9)
  results in [1,7,8,9]

Best regards,
Helge
Reply all
Reply to author
Forward
0 new messages