3

I'm collecting data into a 4D array (it's how most of the code is already implemented) and I'm recording the data over time (i.e. there will be multiple 4D arrays).

The total size of the 4D array is 8x2x8x150 of floats i.e. float data[8][2][8][150]

I want to be able to store each subsequent incoming 4D array into a vector for saving/manipulation later.

I understand, though, that arrays in C++ can't be stored in vectors as is. How can I easily store this data for an undetermined amount of time (i.e. not a fixed vector size)? Keep in mind that this is a fairly large data set (~38Kb per 4D array)

Rohan
  • 515
  • 10
  • 30
  • 3
    Either you store everything in a vector and index the right element manually, or you use something like `boost::multi_array` – sbabbi Oct 13 '15 at 22:14

4 Answers4

2

You can create a helper class that stores the data in a std::vector but provides the interface of a 4D array.

struct My4DArray
{
   My4DArray(int d1, int d2, int d3, int d4) :
     d1(d1), d2(d2), d3(d3), d4(d4), data(d1*d2*d3*d4) {}

   float& at(int i1, int i2, int i3, int i4)
   {
       return data[getIndex(i1, i2, i3, i4)];
   }

   int getIndex(int i1, int i2, int i3, int i4)
   {
      assert(i1 >= 0 && i1 < d1);
      assert(i2 >= 0 && i2 < d2);
      assert(i3 >= 0 && i3 < d3);
      assert(i4 >= 0 && i4 < d4);

      // ??? Need to verify the formula.
      return (((i1*d2 + i2)*d3 + i3)*d4 + i4);
   }

   int d1;
   int d2;
   int d3;
   int d4;
   std::vector<float> data;

};
R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

You could define an alias for defining an std::array of some time with multiple dimensions almost as easy as with C-style arrays:

template<typename Type, std::size_t N, std::size_t... Sizes>
struct multi_array {
    using type = std::array<typename multi_array<Type, Sizes...>::type, N>;
};

template<typename Type, std::size_t N>
struct multi_array<Type, N> {
    using type = std::array<Type, N>;
};

template<typename Type, std::size_t... Sizes>
using multi_array_t = typename multi_array<Type, Sizes...>::type;

and then, since std::array is storable in an std::vector, just use the resulting array:

using my_array = multi_array_t<int, 2, 3>;
my_array arr1 {{ 
    {{1, 2, 3}}, 
    {{4, 5, 6}} 
}};
my_array arr2 {{ 
    {{7, 8, 9}}, 
    {{10, 11, 12}} 
}};

std::vector<my_array> vector {arr1, arr2};
assert(vector[0][0][1] == 2);
assert(vector[1][1][2] == 12);

Live demo

Shoe
  • 74,840
  • 36
  • 166
  • 272
0

Interesting question. I think you might be interested in Pramod Gupta's C++ Multi-dimensional Arrays talk at this year's cppcon.

Basically, using his orca_array library (header-only, MIT license), you should be able to do something like this:

#inclue <vector>
#include "orca_array.hpp"

std::vector<orca_array::array4d<double>> my_vector_of_4d_arrays;
maddouri
  • 3,737
  • 5
  • 29
  • 51
-2

You can store it a one-dimensional array of 19200 elements, accessed as

array[i*2400 + j*1200 + k*150 + l] // array[i,j,k,l]
PineForestRanch
  • 473
  • 2
  • 11