CompilingCyborg
CompilingCyborg

Reputation: 4860

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.

Upvotes: 5

Views: 8679

Answers (1)

Marc Mutz - mmutz
Marc Mutz - mmutz

Reputation: 25353

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().

Upvotes: 4

Related Questions