Boost::Multi_array and reducing dimensions

I am trying to use boost::multi_array and want to create a view where I am
lowering the number of dimensions, but I wish the dimension to be reduced
to be decided at runtime.
I have a vector of integers and this vector size is the same as the number
of dimensions. If the vector [1] value is -1, then the first dimension
will have all values (i.e. range ()), otherwise it will be a number
indicating what slice to use.
You can see in case 2 what I have tried and maybe what I am trying to do.
Case 3 and 4 I am hard coding the dimensions where I want all values, which
does work, but I'd like to get rid of the hard-codedness and make this more
generic.
Furthermore, I have a one dimensional array of values which I am
"converting" to a boost::multi_array so I can slice into it with the views.
I won't know the dimensions until I read the data. Is there a better more
generic way of doing this? Something like a pointer to a N-dimensional
structure where I can just use the view?
Thanks in advance for any ideas!
Joey
Here is my code:
{
double ret_val;
typedef boost::multi_array_types::index_range range;
const VariableInfo &vinfo = GetVariable (si._sensor);
SubSensorType local_subsensors (si._subsensors);
assert (local_subsensors.size () == vinfo._sizes.size ());
switch (vinfo._sizes.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 subsensor element that has -1, and
// create a slice along that dimension
case 2 : { // two-dimensional array
typedef boost::const_multi_array_ref

Hi Joey, I can't quite follow what you are trying to do below. Could you boil it down to a small self-contained program that I can compile and run? Thanks, ron On Jun 14, 2008, at 10:32 AM, Joey Mukherjee wrote:
I am trying to use boost::multi_array and want to create a view where I am lowering the number of dimensions, but I wish the dimension to be reduced to be decided at runtime.
I have a vector of integers and this vector size is the same as the number of dimensions. If the vector [1] value is -1, then the first dimension will have all values (i.e. range ()), otherwise it will be a number indicating what slice to use.
You can see in case 2 what I have tried and maybe what I am trying to do. Case 3 and 4 I am hard coding the dimensions where I want all values, which does work, but I'd like to get rid of the hard-codedness and make this more generic.
Furthermore, I have a one dimensional array of values which I am "converting" to a boost::multi_array so I can slice into it with the views. I won't know the dimensions until I read the data. Is there a better more generic way of doing this? Something like a pointer to a N- dimensional structure where I can just use the view?
Thanks in advance for any ideas!
Joey
Here is my code:
{ double ret_val; typedef boost::multi_array_types::index_range range;
const VariableInfo &vinfo = GetVariable (si._sensor); SubSensorType local_subsensors (si._subsensors); assert (local_subsensors.size () == vinfo._sizes.size ()); switch (vinfo._sizes.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 subsensor element that has -1, and // create a slice along that dimension
case 2 : { // two-dimensional array typedef boost::const_multi_array_ref
array_type; array_type::index_gen indices; array_type multi_array (&(vals [0]), vinfo._sizes); /*
This doesn't work!
array_type::const_array_view <1>::type OneDView; if (local_subsensors [0] == -1) OneDView = multi_array [indices [range ()] [local_subsensors [1]]]; else if (local_subsensors [1] == -1) OneDView = multi_array [indices [local_subsensors [0] [range ()]]];
ret_val = (OneDView [whichPosition]); */ } break; case 3 : { // three-dimensional array
typedef boost::const_multi_array_ref
array_type; array_type::index_gen indices; array_type multi_array (&(vals [0]), vinfo._sizes); array_type::const_array_view <1>::type OneDView = multi_array [indices [local_subsensors [0]] [local_subsensors [1]] [range ()]]; ret_val = (OneDView [whichPosition]); } break; case 4 : { // four-dimensional array typedef boost::const_multi_array_ref
array_type; array_type::index_gen indices; array_type multi_array (&(vals [0]), vinfo._sizes); array_type::const_array_view <1>::type OneDView = multi_array [indices [local_subsensors [0]] [local_subsensors [1]] [local_subsensors [2]] [range ()]];
ret_val = (OneDView [whichPosition]); } break; default : assert (vinfo._sizes.size () < 4);
} return (ret_val); _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Hi Joey, I have looked at your self-contained example, so I get the gist of what you're trying to do. Rather than assigning to the array view, you can assign to an indices object and build the view after the fact. Here's how to do the 2-dimensional case that you had commented out: //This doesn't work, but I would love a generic version of this: array_type::index_gen::gen_type<1,2>::type myindices; if (desired_slice [0] == -1) myindices = indices [range ()][desired_slice [1]]; else if (desired_slice [1] == -1) myindices = indices [desired_slice [0]][range ()]; array_type::const_array_view <1>::type OneDView = multi_array[myindices]; ret_val = (OneDView [whichPosition]); HTH, ron On Jun 14, 2008, at 10:32 AM, Joey Mukherjee wrote:
I am trying to use boost::multi_array and want to create a view where I am lowering the number of dimensions, but I wish the dimension to be reduced to be decided at runtime.
I have a vector of integers and this vector size is the same as the number of dimensions. If the vector [1] value is -1, then the first dimension will have all values (i.e. range ()), otherwise it will be a number indicating what slice to use.

Hi Ron, This helped a great deal. I have one follow on question: Suppose this type of setup was within a function, is it possible to make OneDView the return value of this function? In other words, I would like to: array_type::const_array_view <1>::type OneDView; OneDView = multi_array[myindices]; return OneDView; In every dimensional case, could I construct my OneDView and save it to a variable so I have don't have to do the setup every time? The reason I ask is I have this piece of code in a tight loop and it does take a bit of time. Maybe there is an easier way to do it? Alternatively, I suppose I could copy the contents of the slice to another vector or array?. Is there an easy C++/Boost way to do this? When I compile the code above, I get a compiler error saying operator= is private as least that's what I think it is saying! Joey On Jun 18, 2008, at 11:51 AM, Ronald Garcia wrote:
Hi Joey,
I have looked at your self-contained example, so I get the gist of what you're trying to do. Rather than assigning to the array view, you can assign to an indices object and build the view after the fact. Here's how to do the 2-dimensional case that you had commented out:
//This doesn't work, but I would love a generic version of this:
array_type::index_gen::gen_type<1,2>::type myindices; if (desired_slice [0] == -1) myindices = indices [range ()][desired_slice [1]]; else if (desired_slice [1] == -1) myindices = indices [desired_slice [0]] [range ()];
array_type::const_array_view <1>::type OneDView = multi_array[myindices];
ret_val = (OneDView [whichPosition]);
HTH, ron
On Jun 14, 2008, at 10:32 AM, Joey Mukherjee wrote:
I am trying to use boost::multi_array and want to create a view where I am lowering the number of dimensions, but I wish the dimension to be reduced to be decided at runtime.
I have a vector of integers and this vector size is the same as the number of dimensions. If the vector [1] value is -1, then the first dimension will have all values (i.e. range ()), otherwise it will be a number indicating what slice to use.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Hi Joey, On Jun 26, 2008, at 2:43 PM, Joey Mukherjee wrote:
Suppose this type of setup was within a function, is it possible to make OneDView the return value of this function? In other words, I would like to:
array_type::const_array_view <1>::type OneDView; OneDView = multi_array[myindices]; return OneDView;
Off-hand, I see no reason why you couldn't do this. So long as the multi_array is still in existence, you can build and keep a view of it. How are you calling your function? I'm afraid I can't tell what the problem might be since I can't see how it's really used. Cheers, ron
When I compile the code above, I get a compiler error saying operator= is private as least that's what I think it is saying!
Joey

On Jun 27, 2008, at 11:16 AM, Ronald Garcia wrote:
On Jun 26, 2008, at 2:43 PM, Joey Mukherjee wrote:
Suppose this type of setup was within a function, is it possible to make OneDView the return value of this function? In other words, I would like to:
array_type::const_array_view <1>::type OneDView; OneDView = multi_array[myindices]; return OneDView;
Off-hand, I see no reason why you couldn't do this. So long as the multi_array is still in existence, you can build and keep a view of it. How are you calling your function? I'm afraid I can't tell what the problem might be since I can't see how it's really used.
What would be the return value of the function? In other words, what would the function prototype be? As in the code above, I am not allowed to assign to a OneDView. How can I write it so that I am able to? The way I have my function, I am calling it like so: double GetRealData (const SensorInfo &si, const std::vector <double> &vals, const unsigned int whichPosition) The vals is a n-dimensional array of doubles and the si variable has the desired slice and the sizes of my array. Rather than return a double, I would like to return a one-dimensional const_array_view. Thanks for your help! Joey

On Jun 30, 2008, at 9:46 AM, Joey Mukherjee wrote:
On Jun 27, 2008, at 11:16 AM, Ronald Garcia wrote:
On Jun 26, 2008, at 2:43 PM, Joey Mukherjee wrote:
Suppose this type of setup was within a function, is it possible to make OneDView the return value of this function? In other words, I would like to:
array_type::const_array_view <1>::type OneDView; OneDView = multi_array[myindices]; return OneDView;
Off-hand, I see no reason why you couldn't do this. So long as the multi_array is still in existence, you can build and keep a view of it. How are you calling your function? I'm afraid I can't tell what the problem might be since I can't see how it's really used.
What would be the return value of the function? In other words, what would the function prototype be? As in the code above, I am not allowed to assign to a OneDView. How can I write it so that I am able to?
Rather than assign to a OneDView, you can construct a OneDView as the
result of a function call:
typedef boost::multi_array
The way I have my function, I am calling it like so:
double GetRealData (const SensorInfo &si, const std::vector <double> &vals, const unsigned int whichPosition)
The vals is a n-dimensional array of doubles and the si variable has the desired slice and the sizes of my array. Rather than return a double, I would like to return a one-dimensional const_array_view.
If you don't know at compile-time how many dimensions your array is, then I think that you will need to copy the view into a one- dimensional multi_array.
Thanks for your help!
Joey
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Joey Mukherjee
-
Ronald Garcia