Part2: Simplified implementation of Grid&Displacement cells layer

Another PART2:

The major problem of the previous post was ENCODING/DECODING the POSITION/LOCATION

I think I solved it :wink:


First lets recap the requirements for Grid Cells :

  1. Large representation capacity - more primes increases capacity
  2. Path integration - when you get back at the same position you get the same Location
  3. Locations are unique to each environment - different maps

Lets add what else we can do with RNS - residue number system :

  1. Addition
  2. Subtraction
  3. Multiplication

Now about the solution, lets pick two primes as quick example:

In [26]: [(i,i % np.array([2,5])) for i in range(11)]                                                                                                                        
Out[26]: 
[(0, array([0, 0])),
 (1, array([1, 1])),
 (2, array([0, 2])),
 (3, array([1, 3])),
 (4, array([0, 4])),
 (5, array([1, 0])),
 (6, array([0, 1])),
 (7, array([1, 2])),
 (8, array([0, 3])),
 (9, array([1, 4])),
 (10, array([0, 0]))]

So the maximum number we can represent w/o repetition is 2*5=10

  1. The more primes we pick the space grows exponentially … by the product of primes.
  2. If we get back to 5 it will always be (1,0)
  3. Every 10 positions are another space/map i.e. once we anchor we get the same grid just different map.

NOW finally how do we encode/decode ?

Very easy simply use Integer encoder with a range of X to X+10, voila :wink:

Again depending on the Encoder you may need different encoder for every map, so it can generate different SDRs.

Or let say 10 maps with single Encoder with range X to X+100.

Here is also operations i.e. motor commands arrive in RNS format

In [27]: n1 = np.array([1,1])                                                                                                                                                

In [28]: n2 = np.array([0,2])                                                                                                                                                

In [29]: n5 = np.array([1,0])                                                                                                                                                

In [30]: m = np.array([2,5])                                                                                                                                                 

In [31]: (n1+n5) % m                                                                                                                                                         
Out[31]: array([0, 1])  ==> 6

In [32]: (n5-n2) % m                                                                                                                                                         
Out[32]: array([1, 3])  ==> 3

In [33]: (n5*n2) % m                                                                                                                                                         
Out[33]: array([0, 0])  ==> 10 | 0

Reversing happens by CRT or Matrix Radix Conversion…

The benefit Displacement is simply RSN Addition and Subtraction …

BTW those 3 RSN operations do not require carry bit which makes them more biologically plausible.

… and here is the kicker in RSN there is a concept of base extension , still reading but may be can use it to convert between different grid systems i.e. Reference frames transformation

And I just found this paper, which elaborates what I found in more details.

What Grid Cells Convey about Rat Location
Ila R. Fiete, Yoram Burak, and Ted Brookings

1 Like