On Sun, Jan 11, 2009 at 7:22 AM, Jesse Perla <jesseperla@gmail.com> wrote:
Hi:
I would like to write an algorithm that operates on a multi-array and am having trouble figuring out how to work with arbitrary numbers of dimensions.  A simplified version of my problem that captures all of the types of access I need is:
1) You have a multi-array of (statically defined at compilation) dimensionality N.
2) This data is filled in, but the number of elements in each dimension will frequently be different.
3) Write a function that takes a reference to this multiarray and assigns it the value which is the sum of all of the actual indices(this is contrived, but if I can solve this, I can solve my problem... The key is I need an iterator moving through all dimensions, and I need the index numbers for my calculations).
Here is some pseudocode that gives the kind of iterator I would love to have:

template<int N>
void test_setting(multi_array<double, N>& arr)
{
//HERE IS PSEUDOCODE:  LETS SAY THERE WAS A WAY TO GET AN INDEX THAT YIELDED THE ACTUAL INDEX NUMBERS BUT STILL ACTED AS A POINTER.
for(FANCYINDEX = arr.begin(); FANCYINDEX != arr.end(); ++FANCYINDEX)
{
boost::array<int, N> indicies = FANCYINDEX.get_indices(); //SAY IT RETURNED THE ACTUAL NUMBERS
*FANCYINDEX = sum(indicies);
//Alternatively, could we go: arr(indicies) = sum(indices); if there is no way for it to be a proper pointer.
}

}
//TO CALL:
const int NUMDIMS = 3; //Static at compile time.
int n1 = 3; //These might be dynamic.
int n2 = 4;
int n3 = 5;
boost::multi_array<double, NUMDIMS> A(boost::extents[n1][n2][n3]);
test_setting(A);

Any ideas on how this could be implemented without too much code?


Hi Jesse

Quite by coincidence I've been considering a similar problem myself, and perhaps
my reflections will be of use.

I think that use of iterators in this way is probably a mistake, since by that point
you've already lost the index information.

If you write your traversal code as

for ( int i=0;i!=3;++i)
  for ( int j=0;j!=4;++j)
    for ( int k=0;k!=5;+k)
      f(i,,j,k);

then I think you address the same problem, but the problem is a simpler one.
I envisage that f() will be a bind or lambda function, and that the triple loop
will be some templated header code that you only write once, and that will
generalised to arbitrary number of dimensions. The function f() would probably
take a tuple in the general case.

I haven't thought this this through to extent of having any working code, but I
think the fusion library offers all the tools necessary to do this.

Hope that's useful anyway.

Rob.