Say you’re trying to visit an array in a checkerboard pattern:
0 1 2 3 4 5 6 7 0 o • o • o • o • 1 • o • o • o • o 2 o • o • o • o • 3 • o • o • o • o 4 o • o • o • o • 5 • o • o • o • o 6 o • o • o • o • 7 • o • o • o • o
So, say you’re visiting the black elements here, and adding in all 4 white neighbours.
You can’t do this at the edges or corners, because there are only 3 and 2 white neighbours there respectively. So you’d end up adding all 3 whites on the edges and 0 for out of bounds accesses.
The inefficient way to do this is to do something like
at each element
if element to the right is not out of bounds ...
But I don’t want to be doing checks like this.
So what I did was cut the loop into strips, so:
at each element ON LEFT EDGE
add 3 elements i know are in bounds (right, up, down)
Then a special case for the very corners
at top left corner..
add 2 elements i know are in bounds (right, down)
So this ended up with a very long bit of code that works, but has no constraint checking. I’m looking for a way to cut down on the length of the code block though, and make it more maintainable.
Any tricks?
One possible solution would be to pad your data instead. That is, add a boundary with some neutral values. I have illustrated this below with the
x-es.0 1 2 3 4 5 6 7 x x x x x x x x x x 0 x o • o • o • o • x 1 x • o • o • o • o x 2 x o • o • o • o • x 3 x • o • o • o • o x 4 x o • o • o • o • x 5 x • o • o • o • o x 6 x o • o • o • o • x 7 x • o • o • o • o x x x x x x x x x x xThe actual “thickness” of the boundary obviously depends on how far away you look for each element (your window/kernel width/height). In the case of looking at a direct neighbor, there is only need for a boundary of size one.
Yes, this does mean you’ll be dealing with an increased amount of data. But the advantage is that, although you’ll have to take some care of the addressing, there are no longer any special checks needed for corner/boundary cases.