If one wants to use multi-dimensional arrays in C++, then one option is to use Boost.MultiArray. One of its good properties is that it allows non-zero start indices. For example, one-dimensional multi array could have indices starting from -5 to 5. It is also widely available, since many other software products use Boost, so it is usually installed by default.
The downsides are many. Firstly, it was written nearly 20 years ago, and it shows. It would probably be much easier to use, if it was redesigned for modern C++. Also, the documentation is not exactly well written or pleasing to one’s eye. Have a look at it your self: reference documentation. In addition, if you forget the small code snippets that are isolated from all context, they provide one complete example that is ready to compile. Too bad that it doesn’t compile without modifications. So, more complete examples would be needed.
But so far I haven’t found better option. So, I thought that I would share some of my code that has some working examples, and that also provides tools to make the use of the Boost.MultiArray library a bit easier. The code can be found from my GitHub repository.
The tools include the following functions and classes:
print: Prints the multi array in a similar format than Python’s NumPy arrays useinfo: Shows the exact type of the multi array, element type, number of dimensions, the shape of the multi array, and the number of elements. Note that multi array is a concept that is implemented by several different classes (multi_array, subarray, array_view, …).shape: Returns the shape of the array in string form. Example result could be: “[2][range(1,4)]”, which mean that the first dimension can be indexed either by 0 or 1, and the second dimension can be indexed with 1, 2, or 3.get_extents: Similar to shape, but the result can be passed to the constructor of boost::multi_array to create a new array of the same shape as the existing one.iterator: This class provides a flat iterator over all elements of the multi arrayconstruct: This function allows one to create multi arrays from C-style multidimensional array. Either from an existing variable or from a literal multidimensional array.sum: An example of an algorithm that recursively goes through all the dimensions of an array.
The default iterator of an n-dimensional Boost.MultiArray iterates over all its n-1 dimensional subarrays. This is not often helpful. The flat iterator provided here enables easy application of STL algorithms over the elements of a multi array. The iterator also allows quering the indices of the element the iterator is pointing to.
The Boost.MultiArray also offers data() method, which returns a pointer to the underlying raw data. This can be used to implement some algorithms, but it is not very C++ like, and in addition, it does not work for subarrays or array views. But my flat iterator works also for them.
It is very easy to get indexing wrong with multi array, especially when index bases are non-zeros. And even though the Boost library checks whether indices are withing bounds, it does not indicative which dimension was wrong and by how much. Therefore it is very helpful to be able to print the contents of the array (or parts of it) and also show information about array shape and size. In addition, using iterators to go through the elements of the array, avoids buffer overflows.
Using the construct function a literal multidimensional array can be converted to boost::multi_array without the need of specifying the number of dimensions or the shape. These are deduced automatically. The implementation of the function is not very pretty, since deduction of multidimensional array is quite hard in C++. For more details about this, see the following page.