Manipulating boost::multi_array

Right now, I'm using boost::multi_array for implementing a dynamic-sized matrix for an algorithm in which the number of rows and columns therein may wildly fluctuate (is boost::multi_array even the right class for this?). What's frustrating me is how I can do any and all of the following: 1. Remove a single row or column from a matrix 2. Insert a single row or column to a matrix 3. Augment two matrices together 4. Swap two rows or columns Is there any way to do the first three without calling resize() and moving the elements around manually? For the last, does something like std::swap(A[row1], A[row2]) work?

I too would like answers to these questions. I tried: template <typename T> void display_array_3d( T& array_3d ) { int z_dim = array_3d.shape()[0]; int y_dim = array_3d.shape()[1]; int x_dim = array_3d.shape()[2]; if( x_dim > 0 && y_dim > 0 ){ for( int z = 0; z < z_dim; z++ ){ for( int y = 0; y < y_dim; y++ ){ for( int x = 0; x < x_dim; x++ ){ printf( "\t%f", array_3d[z][y][x] ); } printf( "\n" ); } printf( "\n" ); } return; } if( y_dim > 0 ){ for( int z = 0; z < z_dim; z++ ){ for( int y = 0; y < y_dim; y++ ){ printf( "\t%f", array_3d[z][y] ); } printf( "\n" ); } return; } if( z_dim > 0 ){ for( int z = 0; z < z_dim; z++ ){ printf( "\t%f", array_3d[z] ); } return; } } void test_3d_to_2d_matrix( void ) { int z_dim = 2; int y_dim = 3; int x_dim = 4; boost::shared_ptr<float> array_3d_data = boost::shared_ptr<float>( new float[x_dim * y_dim * z_dim] ); for( int i = 0; i< x_dim * y_dim * z_dim; i++){ (array_3d_data.get())[i] = i; } typedef boost::multi_array_ref<float, 3> array_type; typedef array_type index; array_type a_3d_array( array_3d_data.get(), boost::extents[z_dim][y_dim][x_dim] ); printf( "a_3d_array\n" ); display_array_3d<array_type>( a_3d_array ); boost::multi_array<float, 2> t_mat = eye( 4, 4 ); typedef boost::multi_array_types::index_range range; array_type::index_gen indices; for( int mat_i = 0; mat_i < z_dim; mat_i++ ) { array_type::array_view<3>::type p_mat_view = a_3d_array[ boost::indices[range(mat_i, mat_i)][range(0,2)][range(0,3)] ]; //display_matrix<float,3>( p_mat_view ); } array_type::array_view<3>::type row_1 = a_3d_array[ boost::indices[range(0, z_dim)][range(0,1)][range(0,1)] ]; array_type::array_view<3>::type row_2 = a_3d_array[ boost::indices[range(0, z_dim)][range(1,2)][range(0,1)] ]; printf( "row_1\n" ); display_array_3d<array_type::array_view<3>::type>( row_1 ); printf( "\n" ); printf( "row_2\n" ); display_array_3d<array_type::array_view<3>::type>( row_2 ); printf( "\n" ); printf( "swap\n" ); std::swap( row_1, row_2 ); printf( "row_1\n" ); display_array_3d<array_type::array_view<3>::type>( row_1 ); printf( "\n" ); printf( "row_2\n" ); display_array_3d<array_type::array_view<3>::type>( row_2 ); printf( "\n" ); printf( "a_3d_array\n" ); display_array_3d<array_type>( a_3d_array ); } int main( void ) { test_3d_to_2d_matrix(); } and received: a_3d_array 0.000000 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000 9.000000 10.000000 11.000000 12.000000 13.000000 14.000000 15.000000 16.000000 17.000000 18.000000 19.000000 20.000000 21.000000 22.000000 23.000000 row_1 0.000000 12.000000 row_2 4.000000 16.000000 swap row_1 4.000000 16.000000 row_2 4.000000 16.000000 a_3d_array 4.000000 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000 9.000000 10.000000 11.000000 16.000000 13.000000 14.000000 15.000000 16.000000 17.000000 18.000000 19.000000 20.000000 21.000000 22.000000 23.000000 which is not what I was expecting... but almost And I am only left with more questions like 5) how to create views which are a minimum number of dimensions such as: array_type::array_view<1>::type row_1 = a_3d_array[ boost::indices[range(0, z_dim)][range(0,1)][range(0,1)] ]; and not: array_type::array_view<3>::type row_1 = a_3d_array[ boost::indices[range(0, z_dim)][range(0,1)][range(0,1)] ]; with out getting: 2>..\..\..\..\..\source\Matlab\lib\dsaLib\matrix\src\matrix_test_app.cpp(82) : error C2440: 'initializing' : cannot convert from 'boost::detail::multi_array::multi_array_view<T,NumDims> due to the dimensionality miss match.

Something else I noticed: array_type::array_view<3>:: type row_2 = a_3d_array[ boost::indices[range(0, z_dim)][range(1,1)][range(0,0)] ]; was perfectly acceptable from a boost::multi_array ... why? dimensions of zero thickness should not be allowed. That is the ranges range(1,1) and range(0,0) should not be allowed imho. Of course if I can enter the zeroth dimenson of infintesmal thickness then all would be good.

On 11/29/11 19:46, Brian Davis wrote:
Something else I noticed:
array_type::array_view<3>:: type row_2 = a_3d_array[ boost::indices[range(0, z_dim)][range(1,1)][range(0,0)] ];
was perfectly acceptable from a boost::multi_array ... why? dimensions of zero thickness should not be allowed. That is the ranges range(1,1) and range(0,0) should not be allowed imho. Of course if I can enter the zeroth dimenson of infintesmal thickness then all would be good.
If a multi_array with 0 elements is not allowed, then a std::list<T> with no elements should not be allowed. To be more concrete, imagine: multi_array<T,2> maT(extents[n1][n2]; The std::list counterpart would be: std::list<std::list> lT; where lT.size()==n1, and for any 0<i<lT.size(), lT[i].size()=n2. Now, the constraint that all the dimensions of maT must be >0 would mean that in the counterpart lT, all the lT[i].size() would have to be n2 and n2>0. Now why couldn't all the lT[i].size() be 0. That's certainly possible. If it's possible for lT, why not for maT? -regards, Larry
participants (3)
-
Brian Davis
-
kelvSYC
-
Larry Evans