|
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