Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the (the Boost Multidimensional Array Library) to construct a dynamic two-dimensional array?

I need help in using the boost multidimensional array. I have to construct a two dimensional array where: (0 <= j <= 1) and (i) grows dynamically according to:

long boostArray[i][j];

Thus, It's like constructing a table of (unknown) columns and two rows.

I started already with the example provided at the Boost Library website:

#include "boost/multi_array.hpp"
#include <cassert>

int main () {
  // 3 x 4 x 2 
  typedef boost::multi_array<double, 3> array_type;
  typedef array_type::index index;
  array_type A(boost::extents[3][4][2]);

  int values = 0;
  for(index i = 0; i != 3; ++i) 
    for(index j = 0; j != 4; ++j)
      for(index k = 0; k != 2; ++k)
        A[i][j][k] = values++;

  int verify = 0;
  for(index i = 0; i != 3; ++i) 
    for(index j = 0; j != 4; ++j)
      for(index k = 0; k != 2; ++k)
        assert(A[i][j][k] == verify++);

  return 0;
}

The problem is that i didn't thoroughly understand the above code in order to tweak on its structure and build up my desired array. I don't know precisely how to add/delete elements to/from my array while using the Boost Library especially if this array grows dynamically as i described above.

For example, when dealing with vectors, i tend to use: push_back and pop_back after resizing the vector.

like image 863
CompilingCyborg Avatar asked Oct 25 '22 13:10

CompilingCyborg


1 Answers

For your particular usecase, you're probably better off using vector<pair<T,T>> or vector<array<T,2>>. You can then use push_back, and it's efficient. boost::multi_array sounds like overkill, otoh:

You can't use something like push_back there, because whenever you extend one dimension of an N-dimensional array, you'd need to supply a slice of N-1 dimensions of initial data. That is usually not very efficient, esp. since you can only add to the dimension with the largest stride in this way. What you need to use instead is resize and assignment.

// std::vector<> equivalent (with vector<>, it's considered bad style)
v.resize( v.size() + 1 );
v[v.size()-1] = newElement;

// boost::multi_array (from the tutorial)
typedef boost::multi_array<int, 3> array_type;

array_type::extent_gen extents;
array_type A(extents[3][3][3]);
A[0][0][0] = 4;
A[2][2][2] = 5;
// here, it's the only way:
A.resize(extents[2][3][4]);
assert(A[0][0][0] == 4);
// A[2][2][2] is no longer valid.

To reiterate: N-dimensional arrays, N>2, are inherently much less dynamic than one-dimensional ones (because of the stride factor). The above resize requires a lot of copying of the data, unlike the vector case, which only needs to copy data when size()>capacity().

like image 77
Marc Mutz - mmutz Avatar answered Oct 27 '22 09:10

Marc Mutz - mmutz