Woody20
Woody20

Reputation: 867

Fortran array assignment when the subscripts are not in the same order

How can I accomplish an array assignment when the subscripts are not in the same order? I tried

scansDC(1:nRadii, iScanF, 1:nSpeciesDC) = b(1:nSpeciesDC, 1:nRadii)

but, although this compiles and runs without error, it gives the wrong result.

The intent is to copy b(iSpeciesDC, iRadius) to scansDC(iRadius, iScanF, iSpeciesDC) for 1 <= iSpeciesDC <= nSpeciesDC and 1 <= iRadius<= nRadii.

Compiler is Intel Fortran XE 2015.

Upvotes: 1

Views: 97

Answers (3)

user1139069
user1139069

Reputation: 1623

Simplest way to do this to use the transpose intrinsic.

scansDC(1:nRadii, iScanF, 1:nSpeciesDC) = TRANSPOSE(b(1:nSpeciesDC, 1:nRadii))

Upvotes: 0

Jonathan Dursi
Jonathan Dursi

Reputation: 50927

The reason your original attempt

scansDC(1:nRadii, iScanF, 1:nSpeciesDC) = b(1:nSpeciesDC, 1:nRadii)

gave a different answer than you wanted is because there's no reason for your compiler to infer that you want the transpose taken of b just because the 1:nRadii and 1:nSpeciesDC ranges are switched around. The array ranges are compatible, so the data is just copied over in linear order, giving you the transpose of what you want.

If you need the data copied over in a different order, you need to specify that, either by doing the copy fairly explicitly, as in IanH's correct answer, or by explicitly asking for a transpose:

program test

    integer, parameter :: nradii=10, nspeciesDC=2
    integer, dimension(nradii, 5, nspeciesDC) :: scansDC
    integer, dimension(nspeciesDC, nradii) :: b
    integer :: i,j,k
    integer, parameter :: iscanf = 2

    scansDC = 0
    k = 0
    do i=1,nradii
        do j=1,nspeciesDC
            b(j,i) = k
            k = k + 1
        enddo
    enddo
    print *, b

    scansDC(1:nRadii, iScanF, 1:nSpeciesDC) = transpose(b(1:nspeciesDC, 1:nRadii))   

    print *,scansDC(:,iScanF,:)
end program test

Upvotes: 0

IanH
IanH

Reputation: 21431

INTEGER :: i, j
FORALL (i=1:nRadii, j=1:nSpeciesDC) scansDC(i,iScanF,j) = b(j,i)

Upvotes: 1

Related Questions