1

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?

bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • You either do the conditionals at runtime, or at write-time. In certain languages, you maybe able to simplify the unrolled code (think macros or templates), but you haven't specified a language... – Oliver Charlesworth Mar 15 '12 at 23:05
  • Can you clarify; "So, say you're visiting the black elements here, and adding in all white neighbours. You can't do this on the edges or corners, so you'd end up adding all 3 whites on the edges and 0 for out of bounds accesses." – Mike Purcell Mar 15 '12 at 23:15
  • I mean, "You're visiting the black elements, 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" – bobobobo Mar 16 '12 at 14:17
  • @OliCharlesworth I am using C++, so macros are available – bobobobo Mar 16 '12 at 14:20
  • 1
    @Closer This isn't a "localized" problem. It's a general question about efficiently not stepping out of bounds of a 2d array. – bobobobo Mar 16 '12 at 14:22
  • 2
    I assume that padding with "zero" data around the boundary is not acceptable? You'd have more data, but would avoid any special checks. – Bart Mar 16 '12 at 14:56
  • @Bart actually I was just going to answer my own question with this. Care to formalize? – bobobobo Mar 17 '12 at 02:34

1 Answers1

2

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 x

The 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.

Bart
  • 19,692
  • 7
  • 68
  • 77