Search code examples
c++boostboost-multi-array

Boost::multi_array looping


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?


Solution

  • 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;
    }