C++ standalone mode neuron's spatial location assign error

I’m trying to build a lateral inhibition and SOM neural network based on spatial distance, Created a NeuronGroup with 98×98 or 998×998 neurons, When assigning each neuron a spatial location, I found that in the C++ standalone mode the location will be changed, and this situation only occurs in 98,998 ,maybe more(49,98,103,107,161,187,196,197,206,214,237,239,249,253,…), is something wrong?

#%matplotlib inline
from brian2 import *
import numpy as np
import matplotlib.pyplot as plt

set_device('cpp_standalone')

start_scope()

rows,cols=126,126
rr,cc=98,98
grid_dist = 1000*umeter
grid_dist1 = 1000*umeter
in_x = '(i // rows) * grid_dist-rows/2.0 * grid_dist '
in_y = '(i % rows) * grid_dist-rows/2.0 * grid_dist  '
out_x1 = '(i // rr) * grid_dist1-rr/2.0 * grid_dist1 '
out_y1 = '(i % rr) * grid_dist1-rr/2.0 * grid_dist1 '

neuron_eqs = '''

# Neuron position in space
x : meter 
y : meter 
'''
neuron_eqs1 = '''

# Neuron position in space
x1 : meter 
y1 : meter 
'''
Gin=NeuronGroup(rows*rows, model=neuron_eqs)
Gin.x=in_x
Gin.y=in_y

Gout = NeuronGroup(rr*cc, model=neuron_eqs1)
Gout.x1=out_x1
Gout.y1=out_y1

#S = Synapses(Gin, Gout)
#S.connect(False)

run(1*ms)

fig=plt.figure(figsize=(6, 6))
plt.scatter(Gout.x1,Gout.y1,s=5,c='r')
#show()

Hi @ansuz, many thanks for the report, this seems indeed to be a bug! This looks very much like a floating point issue, i.e. something like int(0.3/(3*0.1)) being 0 (since the argument of the int function is 0.999…). But then of course, in your case you are dividing integers, so it shouldn’t use floating point operations in the first place. I will look into this in more detail soon, but until then you can use one of the following workarounds:

  1. Pre-calculate the positions, instead of using Brian’s code generation mechanism, i.e. use:
Gin = NeuronGroup(rows*rows, model=neuron_eqs)
Gin.x = (Gin.i//rows) * grid_dist-rows/2.0 * grid_dist
Gin.y = (Gin.i % rows) * grid_dist-rows/2.0 * grid_dist

Gout = NeuronGroup(rr*cc, model=neuron_eqs1)
Gout.x1 = (Gout.i//rr) * grid_dist1-rr/2.0 * grid_dist1
Gout.y1 = (Gout.i % rr) * grid_dist1-rr/2.0 * grid_dist1
  1. Or make sure that floating point operations give the correct result by using these strings for Brian’s code generation:
in_x = '((i + 0.5) // rows) * grid_dist-rows/2.0 * grid_dist '
in_y = '((i + 0.5) % rows) * grid_dist-rows/2.0 * grid_dist  '
out_x1 = '((i + 0.5) // rr) * grid_dist1-rr/2.0 * grid_dist1 '
out_y1 = '((i + 0.5) % rr) * grid_dist1-rr/2.0 * grid_dist1 '

For reference, I opened an issue about this here: Floor division of integer values sometimes incorrect on C++ standalone · Issue #1495 · brian-team/brian2 · GitHub

1 Like

Hi, @mstimberg,Thank you sincerely for your response and suggestions, which’s effectively solved the problem that confused me, and also wish you could find the way to fix it smoothly.

1 Like