
Hi, I am coming back to the list with a question on multi_array views. Some time ago, I asked if I could have a view that would offer a “rotated” multi_array. That is, if I have a 3D MA (=multi_array) of dimensions (shape) {L,M,N}), I would like to obtain a reference to it which would look like {M,N,L} i.e. cyclically rotated (I would actually wish to be able to perform this rotation many times). The operation should be performed at compile time (no need/wish to do it at run time and pay the possible overhead in speed). A couple of friends suggested that I used a storage structure something like this (files are attached for convenience of inspection). namespace boost { class cyclic_storage_order { typedef detail::multi_array::size_type size_type; public: cyclic_storage_order( const std::size_t shift ) :shift_(shift) {} template <std::size_t NumDims> operator general_storage_order<NumDims>() const { boost::array<size_type,NumDims> ordering; boost::array<bool,NumDims> ascending; for (size_type i=0; i != NumDims; ++i) { ordering[i] = (i+shift_)%NumDims; ascending[i] = true; } return general_storage_order<NumDims>(ordering.begin(), ascending.begin()); } private: std::size_t shift_; }; } Now, I am trying to use this is the following example (again the file is attached): #define _SCL_SECURE_NO_WARNINGS #include <iostream> using std::cout; using std::endl; #include <boost/multi_array.hpp> using boost::multi_array; using boost::multi_array_ref; using boost::const_multi_array_ref; #include "MultiArrayRotation.h" int main(){ const unsigned short dimensionality = 3; typedef multi_array< int, dimensionality > IntArray; typedef IntArray::size_type size_type; typedef const_multi_array_ref< int, dimensionality > IntArrayCRef; boost::array<size_type,dimensionality> sizes = { { 2,3,4 } }; IntArray a( sizes ); boost::cyclic_storage_order cyclic_storage(1); boost::array<size_type,dimensionality> sizesRotated = { { 3, 4, 2 } }; IntArrayCRef rotated( a.data(), sizesRotated, cyclic_storage ); //initialize: for ( size_t i = 0 ; i != sizes[0]; ++i ) for ( size_t j = 0 ; j != sizes[1]; ++j ) for ( size_t k = 0 ; k != sizes[2]; ++k ) a[i][j][k] = (i+1) + 10 * (j+1) + 100*(k+1); typedef IntArray::const_iterator iterator3; typedef boost::subarray_gen<IntArray,2>::type::const_iterator iterator2; typedef boost::subarray_gen<IntArray,1>::type::const_iterator iterator1; for ( iterator3 it3 = a.begin(); it3 != a.end(); ++ it3 ) { cout << "in first iterator:"; boost::detail::multi_array::const_sub_array<int,2> & d2 = *it3; cout << (d2.shape())[0] << "x" << (d2.shape())[1] << endl; for ( iterator2 it2 = it3->begin(); it2 != it3->end(); ++ it2 ) { // cout << "\t" << it2->shape()[0] << endl; for ( iterator1 it1 = it2->begin(); it1 != it2->end(); ++ it1 ) cout << "\t\t" << (*it1) << endl; } } //for a rotated system: typedef IntArrayCRef::const_iterator iterator3CRef; typedef boost::subarray_gen<IntArrayCRef,2>::type::const_iterator iterator2CRef; typedef boost::subarray_gen<IntArrayCRef,1>::type::const_iterator iterator1CRef; cout << endl << "In Rotated System" << endl; for ( iterator3CRef it3 = rotated.begin(); it3 != rotated.end(); ++ it3 ) { cout << "in first iterator:"; //boost::const_multi_array_ref::const_sub_array<int,2> & d2 = *it3; cout << (it3->shape())[0] << "x" << (it3->shape())[1] << endl; for ( iterator2CRef it2 = it3->begin(); it2 != it3->end(); ++ it2 ) { // cout << "\t" << it2->shape()[0] << endl; for ( iterator1CRef it1 = it2->begin(); it1 != it2->end(); ++ it1 ) cout << "\t\t" << (*it1) << endl; } } return 1; } This gives me undesired results, though. What I have done here, is define a 2x3x4 main array with entries like abc (i.e. 3 digits).
From the value of abc I can infer the coordinates of the element in the main array. Following the cascade of iterators to sub_arrays, I see that, in the end, I obtain for each value of the first coordinate, the corresponding slices. Then I do a rotation (once) and descend down the iterators. I would expect now 3 slices (instead of 2, before), organized so that each one has the same middle digit (in the abc “representation”. This, however, is not happenning! I attach the code which I have built successfully w/msvc2010 on win7. I use boost1.45. A friend (Larry Evans) , who had offered a lot of help in the past and whom I contacted for suggestion let me know that, the program did not compile in his environment (gcc 4.6.0 and boost v1.46). Any suggestion, help will be greatly appreciated. Kind Regards, Petros