Boost logo

Boost Users :

Subject: Re: [Boost-users] Help with a generic algorithm using boost::MultiArray
From: Robert Jones (robertgbjones_at_[hidden])
Date: 2009-01-11 17:36:41


On Sun, Jan 11, 2009 at 7:22 AM, Jesse Perla <jesseperla_at_[hidden]> 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.



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