Need an efficient Fortran equivalent of Matlab AccuArray (2023)

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

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
dpb2010-05-15 09:15:10 UTC
John D'Errico 2010-05-15 12:58:06 UTC
dpb2010-05-15 13:23:18 UTC
dpb2010-05-15 15:33:40 UTC
James Tursa2010-05-15 19:05:08 UTC
dpb2010-05-15 19:50:57 UTC
Top Articles
Latest Posts
Article information

Author: Clemencia Bogisich Ret

Last Updated: 03/11/2023

Views: 5369

Rating: 5 / 5 (80 voted)

Reviews: 87% of readers found this page helpful

Author information

Name: Clemencia Bogisich Ret

Birthday: 2001-07-17

Address: Suite 794 53887 Geri Spring, West Cristentown, KY 54855

Phone: +5934435460663

Job: Central Hospitality Director

Hobby: Yoga, Electronics, Rafting, Lockpicking, Inline skating, Puzzles, scrapbook

Introduction: My name is Clemencia Bogisich Ret, I am a super, outstanding, graceful, friendly, vast, comfortable, agreeable person who loves writing and wants to share my knowledge and understanding with you.