[multi_array] Slices along the N'th dimension of a multi_array in a generic function
I have a generic function which will take in a boost::multi_array of dimension size N. I need to take slices along the M'th < N dimension (known at compile time). I can't figure out how to do this with the multi_array library and associated ranges/array_views. Is there another way to do this rather than building a boost::indices object directly? Besides the sliced dimension, I will always want the entire ranges for the other ones. I believe the problem is that the index_gen object needs different types as we build the indices in parts. The following code shows what a hardcoded example would look like for N = 4 and M = 3 const std::size_t n_1 = 3; const std::size_t n_2 = 4; const std::size_t n_3 = 5; const std::size_t n_4 = 6; typedef boost::multi_array<double, 4> array_type; array_type vals(boost::extents[n_1][n_2][n_3][n_4]); //...fill the array... typedef boost::multi_array_types::index_range range; typedef boost::multi_array_types::index_gen index_gen_type; //Trying to do this dynamically instead, but in pieces. Note that you need the different autos at each stage since you can't build an index directly? auto slice_indices2 = boost::indices[range(0,n_1)][range(0,n_2)]; //first dimensions auto slice_indices3 = slice_indices2[1]; //Slice dimension.... for the 2nd index. auto slice_indices4 = slice_indices3[range(0,n_4)]; //last dimensions auto vals_slice3 = vals[ slice_indices4 ]; //Take slices with the final object. This is a proper multi_array view cout << vals_slice3[0][0][0] << endl; Thanks, Jesse
On Jun 24, 1:54 pm, Jesse Perla <jessepe...@gmail.com> wrote:
I believe the problem is that the index_gen object needs different types as we build the indices in parts. The following code shows what a hardcoded example would look like for N = 4 and M = 3
Sorry to answer my own question, but I poked around in the code and found that the member data is public. The following seems to solve my problem (though I would still love suggestions on if it is the best way to tackle this problem with multi_array): boost::multi_array<double, 4> vals; //...fill.... boost::detail::multi_array::index_gen<4, 3> slice_build; slice_build.ranges_[0] = range(0,n_1); slice_build.ranges_[1] = range(0,n_2); //could loop before slice_build.ranges_[2] = range(1); slice_build.ranges_[3] = range(0,n_4); //could loop after auto vals_slice4 = vals[ slice_build ]; cout << vals_slice4[0][0][0] << endl; cout << vals_slice4[1][1][1] << endl;
participants (2)
-
Jesse Perla
-
jp