$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Joey Mukherjee (joey_at_[hidden])
Date: 2008-06-16 12:10:10
Hello Ronald,
I unfortunately was not receiving email when your email came through  
so I had to start a new thread.  Anyway, here is a main program which  
I hope explains what I am trying to do.
I have a stream of numbers and I want to apply a view onto it via the  
boost::multi_array.  I am basically taking a slice of an n- 
dimensional tensor of data.  In my case, I am not currently handling  
tensors greater than 4.  The challenge is that I want to decide at  
runtime where to slice the array.  In my program, this is actually  
from the GUI.
This example code is a fully contained main program which hard codes  
everything.  I hope it makes sense!
Thanks for any ideas!
Joey
#include <iostream>
#include <boost/multi_array.hpp>
int main (int argc, char **argv)
{
     int ret_val;
     typedef boost::multi_array_types::index_range range;
// Hard coded values - this is a 4x3x3 matrix
// In my real program, I read this in from data
     int vals [] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
                    0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
                    0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
                    0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
                    0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
                    0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
                    0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
                    0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
                    0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3};
     boost::array <int, 3> sizes = { { 4, 3, 3 } };
     int size = 3;  // three dimensional matrix
// I want to get to get the second X, all the Y's, and the third Z
// The -1 could be along any axis, but for now, hard coded to Y
     int desired_slice [] = {1, -1, 2};  // how to reduce to 1D view
     int whichPosition = 2;              // where in the 1D that I  
wish to print...
// Based on the dimensionality of my array which is known from the  
data...
// Pick out which slice is being requested
     switch (size) {
         case 0  : ret_val = vals [0];
                   break;
         case 1  : { // one-d array
                       ret_val = (vals [whichPosition]);
                   }
                   break;
// Now we get into slices, find the slice element that has -1, and  
create a slice along that dimension
         case 2  : { // two-dimensional array
                       typedef boost::const_multi_array_ref <int, 2>  
array_type;
                       array_type::index_gen indices;
                       array_type multi_array (&(vals [0]), sizes);
/*
This doesn't work, but I would love a generic version of this:
                       array_type::const_array_view <1>::type OneDView;
                       if (desired_slice [0] == -1) OneDView =  
(multi_array [indices [range ()][desired_slice [1]]]);
                           else
                       if (desired_slice [1] == -1) OneDView =  
(multi_array [indices [desired_slice [0][range ()]]]);
                       ret_val = (OneDView [whichPosition]);
*/
                   }
                   break;
         case 3  : { // three-dimensional array
                       typedef boost::const_multi_array_ref <int, 3>
                       array_type::index_gen indices;
// Hard coded range () means we are always slicing along Z
                       array_type multi_array (&(vals [0]), sizes);
                       array_type::const_array_view <1>::type  
OneDView = multi_array [indices [desired_slice [0]][desired_slice [1]] 
[range ()]];
                       ret_val = (OneDView [whichPosition]);
                   }
                   break;
         case 4  : { // four-dimensional array
                       typedef boost::const_multi_array_ref <int, 4>  
array_type;
                       array_type::index_gen indices;
                       array_type multi_array (&(vals [0]), sizes);
                       array_type::const_array_view <1>::type  
OneDView = multi_array [indices [desired_slice [0]][desired_slice [1]] 
[desired_slice[2]][range ()]];
                       ret_val = (OneDView [whichPosition]);
                   }
                   break;
         default : assert (size < 4);  // would like to handle n- 
dimensional case, but how?
     } // switch
     std::cout << ret_val << std::endl;
}