Boost logo

Boost Users :

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;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net