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