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 <double, 2> 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 <double, 3> 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 <double, 4> 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