Reputation: 867
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
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
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
Reputation: 21431
INTEGER :: i, j
FORALL (i=1:nRadii, j=1:nSpeciesDC) scansDC(i,iScanF,j) = b(j,i)
Upvotes: 1