Discussion:

Need efficient Fortran equivalent to Matlab accumarray

(too old to answer)

Ed Stein8778

15/05/2010 08:09:23 UTC

link permanente

Hello,

I'm looking for efficient vectorized Fortran90/95 code that works like

The Matlab accumray function, which accumulates elements from an input

array(data), based on arrays of subscripts (like data

array) that point to the location in a new target array that the input

array will accumulate into . More precisely:

Given a data matrix of size A(M,N) and a set of row indices DROW(M,N) and

column indexes DCOLUMN(M,N), the accumarray function accumulates data

from A to a new matrix of size D(Md,Nd) where D(md,nd) is the sum of

A(m,n) for all values of m,n for which DROW(m,n)=md and DCOLUMN(m,n)=nd.

Matlab's Accumarray does this:

D = accumarray([DROW(:) DCOLUMN(:)], A(:) );

Can anyone suggest some equivalent Fortran code that avoids loops?

Although Matlab's accumarray handles an arbitrary range, restricting the

The Fortran version for 2D matrices A and D, as in the example above, is fine.

Thank you very much,

ed.

dpb

15/05/2010 09:15:10 UTC

link permanente

Posted by Ed Stein8778

Hello,

I'm looking for efficient vectorized Fortran90/95 code that works like

The Matlab accumray function, which accumulates elements from an input

array(data), based on arrays of subscripts (like data

array) that point to the location in a new target array that the input

Given a data matrix of size A(M,N) and a set of row indices DROW(M,N) and

column indexes DCOLUMN(M,N), the accumarray function accumulates data

from A to a new matrix of size D(Md,Nd) where D(md,nd) is the sum of

A(m,n) for all values of m,n for which DROW(m,n)=md and DCOLUMN(m,n)=nd.

D = accumarray([DROW(:) DCOLUMN(:)], A(:) );

Can anyone suggest some equivalent Fortran code that avoids loops?

Although Matlab's accumarray handles an arbitrary range, restricting the

The Fortran version for 2D matrices A and D, as in the example above, is fine.

As with Matlab, vectorization in source code is not always necessarily the same.

responder.

Just as you build blocks in Matlab in m-files that sometimes have loops,

here I think the solution is to write a routine and hide the details,

then call.

--

John D'Errico

15/05/2010 12:58:06 UTC

link permanente

Publish by dpb

Posted by Ed Stein8778

Hello,

I'm looking for efficient vectorized Fortran90/95 code that works like

The Matlab accumray function, which accumulates elements from an input

array(data), based on arrays of subscripts (like data

array) that point to the location in a new target array that the input

Given a data matrix of size A(M,N) and a set of row indices DROW(M,N) and

column indexes DCOLUMN(M,N), the accumarray function accumulates data

from A to a new matrix of size D(Md,Nd) where D(md,nd) is the sum of

A(m,n) for all values of m,n for which DROW(m,n)=md and DCOLUMN(m,n)=nd.

D = accumarray([DROW(:) DCOLUMN(:)], A(:) );

Can anyone suggest some equivalent Fortran code that avoids loops?

Although Matlab's accumarray handles an arbitrary range, restricting the

The Fortran version for 2D matrices A and D, as in the example above, is fine.

As with Matlab, vectorization in source code is not always necessarily the same.

responder.

Just as you build blocks in Matlab in m-files that sometimes have loops,

here I think the solution is to write a routine and hide the details,

then call.

--

Exactly. In Fortran, a loop will be very efficient.

So write a routine that does that and you have it.

John

dpb

15/05/2010 13:23:18 UTC

link permanente

Posted by John D'Errico

Posted by Ed Stein8778

Hello,

Posted by Ed Stein8778

I'm looking for efficient vectorized Fortran90/95 code that

works like Matlab's > accumarray...

...

Posted by John D'Errico

Posted by Ed Stein8778

Posted by Ed Stein8778

Can anyone suggest some equivalent Fortran code that avoids

bucles?...

As with Matlab, vectorization in source code is not always necessarily

the answer.

Just like how you build blocks in Matlab in m files which sometimes have

loops, here I think the solution is to write a routine and hide the

details, then call him.

--

Exactly. In Fortran, a loop will be very efficient.

So write a routine that does that and you have it.

I would point out to the OP that even if he found a way to use the Fortran array

syntax with cut notation or something like that in all likelihood the result would be

be slower than direct loops due to temporary intermediates

and such. This is often a complaint in the comp.lang.fortran group when

people try something like that.

I'll also point out that while you can create a functional form that uses a

pointer as return, F95+TR has no dynamic allocation in

assignment so that the postulated syntax of a function call like Matlab just

it's not possible. This would at least require a compiler that

implements F2003, not F95 (and I'm not entirely sure the FUNCTION

you can return the array there, even, and you don't have the

feel like going looking for it now :)).

Hence, I would recommend writing it as a SUBROUTINE rather than a

FUNCTION where the ASSIGNABLE array assignment can be handled in a

assumed length argument.

For efficiency, make sure additions are done as much as possible.

possible in main column order, of course, consistent with underindexing

prompted for any call.

--

dpb

15/05/2010 15:33:40 UTC

link permanente

dbp wrote:

...

Publish by dpb

Hence, I would recommend writing it as a SUBROUTINE rather than a

FUNCTION where the ASSIGNABLE array assignment can be handled in a

assumed length argument.

...

Heck, I got the metaphors mixed up... an ASSIGNABLE array is an ASSIGNABLE array,

Assumed length is another matter. Thought I edited this to fix it

the slip, sorry.

The problem one might have with doing what the OP wants is that if the

The ALLOCATE statement is in the accumarray() routine, so it's the

caller's responsibility to deallocate it at the appropriate time

Time place. Fortran's dynamic memory, particularly in F95, is not as

flexible like Matlab; there are more features built into the F2003.

--

james rides

15/05/2010 19:05:08 UTC

link permanente

Publish by dpb

I would point out to the OP that even if he found a way to use the Fortran array

syntax with cut notation or something like that in all likelihood the result would be

be slower than direct loops due to temporary intermediates

and such. This is often a complaint in the comp.lang.fortran group when

people try something like that.

I'll also point out that while you can create a functional form that uses a

pointer as return, F95+TR has no dynamic allocation in

assignment so that the postulated syntax of a function call like Matlab just

it's not possible. This would at least require a compiler that

implements F2003, not F95 (and I'm not entirely sure the FUNCTION

you can return the array there, even, and you don't have the

feel like going looking for it now :)).

To complete the thought, yes you can. For example, you can have a function return a dynamically sized array based on the size of the inputs. The main problem with the approach, in my opinion, is that for many (most?) implementations, the memory for the array comes off the stack rather than the heap. So if you are working with large arrays you can easily explode your stack and bomb the program. Also, if the calling routine assigns the result to a variable, there will be an extra copy of the data involved.

Publish by dpb

Hence, I would recommend writing it as a SUBROUTINE rather than a

FUNCTION where the ASSIGNABLE array assignment can be handled in a

assumed length argument.

This is the most efficient approach for the reasons mentioned above. Allocated memory comes off the heap instead of the stack and prevents further memory copying.

What I sometimes do is create both versions and set up a generic routine interface so I can call it either way.

james rides

dpb

15/05/2010 19:50:57 UTC

link permanente

...

Posted by James Tursa

Publish by dpb

I'll also point out that while you can create a functional form that uses a

pointer as return, F95+TR has no dynamic allocation in

assignment so that the postulated syntax of a function call like Matlab

it is simply not possible. This would require at least one compiler

which implements F2003, not F95 (and I'm not entirely sure that the

FUNCTION can return the array itself there, even, and not

feel like going to look for it right now :)).

To complete the thought, yes you can. For example, you can have a function

return a dynamically sized array based on the size of the

Appetizer. ...

Well, James, thanks for the attachment.

For my own clarification, this requires more than F95, correct?

The following compiles without warning, but aborts in CVF6.6 when accessing any

element of x() and ALLOCATED(x) returns false since AIUI F95 does not

learn how to assign the variable x anything other than REAL

variable, not the array elements x(:).

program foobar

real, assignable :: x(:)

x = foo(10)

! It dies with bound error because it can't recognize and assign to an array...

! This is the F95 limitation, not a compiler bug, correct?

write(*,*)x(1)

fin

function foo(n) result(x)

integer ::n

real, assignable :: x(:)

assign (x(n))

x = 3,0

final function

OTOH, a form of SUBROUTINE works well, with difficulty above

which requires keeping track of where/when the array is deallocated

--

6 answers

11 views

Permanent link for this page

Disable enhanced parsing

discussion navigation

Ed Stein87782010-05-15 08:09:23 UTC