After struggling with robots simulations in a grid world written in Matlab/Octave code I remembered how easy it is to program such a movement if the language allows to start with index “0”. Or in more mathematical words: a nice application of ring of integers modulo n (\(\mathbb{Z} / \mathbb{Z} n\)).
Ring of integers modulo n
The ring of integers modulo n is denoted as \(\mathbb{Z} / \mathbb{Z} n\) and denotes a set of numbers \(\{0, ..., n-1\}\).
Therefore, we could write the binary field as: \(\mathbb{Z} / \mathbb{Z} 2 = \{0,1\}\).
Some more examples:
\[\mathbb{Z} / \mathbb{Z} 3 = \{0,1,2\}\] \[\mathbb{Z} / \mathbb{Z} 4 = \{0,1,2,3\}\] \[\mathbb{Z} / \mathbb{Z} 5 = \{0,1,2,3,4\}\] \[...\]The modulo (%
, mod
) after integer division is a positive integer (unlike the remainder) and tells us how much is left after dividing one integer by another without using e.g. floating point. Let us assume that we use \(\mathbb{Z} / \mathbb{Z} 3\). We will only end up with numbers \(x \in \{0,1,2\}\):
Ìn [1]: 0 % 3
Out [1]: 0
Ìn [2]: 1 % 3
Out [2]: 1
Ìn [3]: 2 % 3
Out [3]: 2
Ìn [4]: 3 % 3
Out [4]: 0
Ìn [5]: 5 % 3
Out [5]: 2
Ìn [6]: 7 % 3
Out [6]: 1
In [7]: 82934 % 3
Out[7]: 2
Application for grid world robotics
Back to what made me angry when using Matlab/octave or other programming languages that use 1 as their index for the first entry in an array. Let us assume that we move a robot around in a cyclic grid world (gridded torus). Once the robot has reached a side and we want to move further into that direction we will end up on the opposite site. This is similar to moving on a globe of Earth with grid coordinates on it (sry Flat Earth Society - but someone has to tell you ;)). This movement can be programmed extremely efficient using modulo if the programming language starts indexing arrays with 0. Here is a little example in JavaScript using math.js and plotly.js.
A grid with random initial position is created and then a function that updates the position using modulo is called every second:
// calculate next move
// using idx and current_idx for better explanation
var current_idx_x = idx_x;
var current_idx_y = idx_y;
grid._data[current_idx_x][current_idx_y] = 0;
// maximum distance per step: 1
var move_distance_x = math.randomInt(-1,1);
var move_distance_y = math.randomInt(-1,1);
// using math.mod since % returns the remainder
var idx_x = math.mod((current_idx_x + move_distance_x),grid._size[0]);
var idx_y = math.mod((current_idx_y + move_distance_y), grid._size[1]);
grid._data[idx_x][idx_y] = 1;