ev-br
ev-br

Reputation: 26030

array-valued array indices

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

Answers (1)

zmi
zmi

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

Related Questions