4

I would like to translate some existing Matlab code that quite naturally uses a lot of multidimensional arrays and I wonder what are the possible options. I want the containers to have copy constructors, default constructors, if possible clear error messages at compilation, access via A[i][j] and in general not to be troublesome. Preferably, they should use the std::move operation for speed.

As far as I can see the options boils down to:

  • std::vector iterated. It sure works, but it seems stupid to write std::vector<std::vector<std::vector<double> > >for a 3D array. I am also concerned with the overhead in speed and memory.

  • The boost::multiarray and blitz::Array offer most of the functionality but fails at the copy constructor (see stackoverflow) at runtime. It is unclear to me if there are valid reasons for that.

  • The Eigen library seems to be very fast but it does not allow copy at all, and has no default constructor, which means that another container has to be used.

  • The std::array has the disadvantage that the size has to be known when the object is created, so there is no default constructors.

Is there a simpler multidimensional container satisfying all the requests but more frugal than iterated std::vector?

Community
  • 1
  • 1
  • 2
    Who said the Eigen library doesn't support copies at all? – Rapptz Nov 13 '14 at 12:48
  • 2
    http://eigen.tuxfamily.org/dox-devel/classEigen_1_1Array.html#ad9f6f2c9890092e12fd3344aa6ffcbd1, http://eigen.tuxfamily.org/dox-devel/classEigen_1_1Array.html#aa1ef64a2517d538e03b71584369e14bb – R. Martinho Fernandes Nov 13 '14 at 12:53
  • At least with `boost::multi_array`, you do get better locality than with `vector>`, even if copy is apparently broken. As always, there's writing your own? – Barry Nov 13 '14 at 13:34
  • *[...] blitz::Array [...] fails at the copy constructor [...]. It is unclear to me if there are valid reasons for that.* To my understanding it's because Blitz was developed before move-semantics came up. Blitz arrays have a weird mix of value/reference semantics. The copy-ctor creates a reference, whereas the assignment operator does a copy. In a way this emulates move-semantics. E.g. construct an array in a function and initialize another array with the function's return value. This won't copy, just increment and then decrement a ref-count. (Ignoring elision) – Lemming Nov 13 '14 at 13:58
  • I indeed ended up writing the container that I wanted. For `eigen` my first try was unsuccessful and so I assumed there was a good reason for the absence of copy constructor. Thanks, I will look further at eigen even though it does not have multidimensional arrays, only matrices. – Mathieu Dutour Sikiric Nov 13 '14 at 20:16

3 Answers3

1

I am not sure this can answer all your needs but I myself had to handle multi-dimensional arrays for creating meshes/grid and wanted to create my own class for that.
My class let's call it MultiArray uses a a one-dimension vector as container.

For instance, writing MultiArray<4, float, 10, 15, 10, 18> A() would create a multi array A[10][15][10][18] in a vector of size 10*15*10*18.

I can access to elements by single index A(i) or by coordinates A[i][j][k][l] by calling A({i,j,k,l}). For performance purpose I have precomputed in the constructor the product of the dimensions in order to compute fastly coordinates->index or index->coordinates.

The code is generic for N dimensions. I can detail some parts if you want.

coincoin
  • 4,595
  • 3
  • 23
  • 47
1

There is good linear algebra package called Armadillo

http://arma.sourceforge.net/

used it with R, happy user

Severin Pappadeux
  • 18,636
  • 3
  • 38
  • 64
0

You have missed another option:

  • std::valarray

Depending on what your requirements are it could be useful. http://www.cplusplus.com/reference/valarray/

Alan Milton
  • 374
  • 4
  • 13