Reputation: 26030
I've just stumbled upon the fact that compiler lets me use integer arrays as indices to other arrays. For example:
implicit none
real*8 :: a(3), b(2)
integer :: idx(2)
a=1.d0
idx=(/1,2/)
b = a(idx)
print*,shape(b)
print*,b
print*
end
Given the fact that this seems to work with both gfortan and a PGI compiler, I'm wondering if this a language feature rather than something compiler just lets me out with. I would appreciate if somebody more knowledgeable than me can comment if this is really a language feature.
And if it is, than I'd appreciate if somebody would spell out the exact language rules of how such constructions are interpreted in multidimensional case, like here:
implicit none
real*8 :: aa(3,3), bb(2,2)
integer :: idx(2)
do i=1,3 ; do j=1,3
aa(i,j) = 1.d0*(i+j)
enddo; enddo
bb=aa(idx,idx)
print*,shape(bb)
print*,bb
end
Upvotes: 3
Views: 397
Reputation: 94
Yes, it is.
The final draft of the Fortran 2008 standard, ISO/IEC JTC 1/SC 22/WG 5/N1830, ftp://ftp.nag.co.uk/sc22wg5/N1801-N1850/N1830.pdf says on page 84
4.8 Construction of array values
...
6 If an ac-value is an array expression, the values of the elements of the expression, in array element order (6.5.3.2), specify the corresponding sequence of elements of the array constructor.
Example
real, dimension(20) :: b
...
k = (/3, 1, 4/)
b(k) = 0.0 ! section b(k) is a rank-one array with shape (3) and
! size 3. (0.0 is assigned to b(1), b(3), and b(4).)
The rules you can see directly from your code
implicit none
real*8 :: aa(3,3), bb(2,2)
integer :: idx(2),i,j,k
idx=(/3, 2/)
k=0
do i=1,3 ; do j=1,3
k=k+1
aa(i,j) = aa(i,j)+1.d0*k
enddo; enddo
write(*,*),shape(aa)
write(*,'(3G24.6,2X)') aa
bb=aa(idx,idx)
print*,shape(bb)
write(*,'(2G24.6,2X)'),bb
end
Output:
3 3 1.00000 4.00000 7.00000 2.00000 5.00000 8.00000 3.00000 6.00000 9.00000 2 2 9.00000 6.00000 8.00000 5.00000
Upvotes: 3