Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

How to reduce array

alexismor
Beginner
859 Views
Hi everybody,

I'm not sure if this is the right place to post this, but I'll try anyway. I'm trying to figure out what's the most efficient way to do this following problem:

I have a subroutine that has inputs A (which is an array) and "indexes" (which is a list of indices of data to be eliminated from the array A. I currently have a way to do this, except I find it quite clumsy. I'm quite new to fortran 90 and so I was wondering if there was a fancy way of doing this with all those new intrinsics such as MERGE and PACK.

Here's a specific example:

On input I have:
A=(10,11,22,33,44,55)
indexes=(2,5)
I then call reduce(A,indexes)
On output I want
A=(10,11,33,44)

Thanks!

Message Edited by alexismor on 06-23-2005 08:25 PM

0 Kudos
7 Replies
TimP
Honored Contributor III
859 Views
LOGICAL MASK(SIZE(A))
MASK = .TRUE.
MASK(indexes(:SIZE(indexes)))= .FALSE.
A = PACK(A, MASK)

should do this.

The implementation in ifort isn't particularly efficient in run time.
0 Kudos
alexismor
Beginner
859 Views
Thanks! I'll give it a try right away.

Alexis
0 Kudos
alexismor
Beginner
859 Views
Hi Tim18,

I played around with your suggestion and it seems to work fine except for the fact that the matrix A still has the same size before and after the pack command. To get around this I used and intermediary array called B:

subroutine reduce(A,indexes)
implicit none
integer, allocatable, intent(inout) :: A(:)
integer, intent(in) :: indexes(:)
integer :: B(size(A)-size(indexes))
logical :: mask(size(A))
mask=.true.
mask(indexes)=.false.
B=pack(A,mask)
deallocate(A)
allocate(A(size(B)))
A=B
return
end subroutine reduce

Is this the only way?

Also, I was wondering why you specified the upper bound on the indexes array in the following line:

MASK(indexes(:SIZE(indexes)))= .FALSE.

Isn't this the same as

MASK(indexes)= .FALSE. ?

Thanks for your help!

Alexis
0 Kudos
TimP
Honored Contributor III
859 Views
Alexis,

As you can see, I am more used to the old-fashioned scheme of leaving an array allocated and taking care to specify the upper bound of the part which is in use. You are correct about my redundant use of SIZE(); it's just my habit of always specifying an upper bound. If you have a reason for taking the time to deallocate memory you don't need after PACKing, I have no problem with your suggestion, There was a thread on reallocation recently on comp.lang.fortran USEnet group which may be related.
0 Kudos
alexismor
Beginner
859 Views
Thanks for the reply--you've been a great help.

Cheers,

Alexis
0 Kudos
alexismor
Beginner
859 Views
One last question, I promise! Is there something equivalent to PACK for 2D arrays? Thank!
0 Kudos
Steven_L_Intel1
Employee
859 Views
No - PACK works on rank-1 arrays only.
0 Kudos
Reply