4

I've looked at this post which addresses how to loop over arrays that aren't zero-based using the boost::multi_array::origin() function, but that only creates a single loop.

How does one traverse each dimension of a multi_array, for example:

for(index i = <origin of dim 1>; ...) {
   for(index j = <origin of dim 2>; ...) {
      for(index k = <origin of dim 3>; ...) {
         myArray[i][j][k] = <something>;
      }
   }
}

when given an array where both upper and lower bounds are unknown?

Community
  • 1
  • 1
tpg2114
  • 14,112
  • 6
  • 42
  • 57

1 Answers1

5

The index_bases member function returns a container with each dimension's index base. The shape member function returns a container with each dimension's extent (size). You can use both of these to determine the range of indices for each dimension:

typedef boost::multi_array<int, 3> array_type;

void printArray(const array_type& a)
{
    // Query extents of each array dimension
    index iMin = a.index_bases()[0];
    index iMax = iMin + a.shape()[0] - 1;
    index jMin = a.index_bases()[1];
    index jMax = jMin + a.shape()[1] - 1;
    index kMin = a.index_bases()[2];
    index kMax = kMin + a.shape()[2] - 1;

    for (index i=iMin; i<=iMax; ++i)
    {
        for (index j=jMin; j<=jMax; ++j)
        {
            for (index k=kMin; k<=kMax; ++k)
            {
                std::cout << a[i][j][k] << " ";
            }
        }
    }
}

int main()
{
    typedef array_type::extent_range range;
    typedef array_type::index index;
    array_type::extent_gen extents;

    // Extents are hard-coded here, but can come from user/disk.
    array_type a(extents[2][range(1,4)][range(-1,3)]);

    // Populate array with values...

    // Pass the array to a function. The function will query
    // the extents of the given array.
    print(a);

    return 0;
}
Emile Cormier
  • 28,391
  • 15
  • 94
  • 122
  • 1
    but this requires that you know the dimension of the array at the time you are writing the code, losing most of the genericity of multi_array. – David Doria Apr 07 '16 at 19:29
  • @DavidDoria, in `A(extents[2][range(1,4)][range(-1,3)])`, you can replace the hard-coded dimension values with whatever you like, be it values loaded from disk or input from the user. I had hard-coded the numbers for the sake of simplifying the example. – Emile Cormier Apr 07 '16 at 20:09
  • Re-arranged example to better illustrate how the dimension extents are being queried outside of where the array was initialized. – Emile Cormier Apr 07 '16 at 20:21
  • But you still are listing iMin, jMin, kMin... What do you do if `printArray` doesn't know that `array_type` is 3D? – David Doria Apr 07 '16 at 20:23