Reputation: 493
Let A be a multi-dimensional array of DIMENSION(m,n,p). Is linear indexing of A (using a single index) allowed in Fortran? If so, what is correspondence between the linear index and the multi-dimensional index?
In other words, is A(i) allowed, and which element does A(i) correspond to (in which order are the dimensions traversed)?
Upvotes: 3
Views: 3403
Reputation: 28384
I would add the following possibility, even though I've never used it, since I find it confusing. Someone (Nek5000, see page 22) claims it's faster.
do i=1,nx1*ny1*nz1*nelv u(i,1,1,1) = vx(i,1,1,1) enddo
which is equivalent but superior (WHY?) to:
do e=1,nelv do k=1,nz1 do j=1,ny1 do i=1,nx1 u(i,j,k,e) = vx(i,j,k,e) enddo enddo enddo enddo
which is equivalent but vastly superior (WHY?) to:
do i=1,nx1 do j=1,ny1 do k=1,nz1 do e=1,nelv u(i,j,k,e) = vx(i,j,k,e) enddo enddo enddo enddo
Upvotes: 1
Reputation: 2605
You can pass a 3D array to a function or subroutine as if it were a 1D array, as shown in the code below. I don't recommend using this feature, but you will see it in pre-Fortran 90 code.
program xarray
implicit none
! demonstrate storage association
integer, parameter :: n1 = 2, n2 = 4, n3 = 3
integer :: i1,i2,i3,arr(n1,n2,n3)
forall (i1=1:n1,i2=1:n2,i3=1:n3) arr(i1,i2,i3) = i1 + 10*i2 + 100*i3
print*,"arr =",arr
! output: arr = 111 112 121 122 131 132 141 142 211 212 221 222 231 232 241 242 311 312 321 322 331 332 341 342
call print_array(arr,n1*n2*n3)
end program xarray
subroutine print_array(arr,n)
implicit none
integer, intent(in) :: arr(n)
integer, intent(in) :: n
print*,"arr(1), arr(n) =",arr(1),arr(n)
! output: arr(1), arr(n) = 111 342
end subroutine print_array
Upvotes: 4
Reputation: 32366
For the array declared dimension A(m,n,p)
it isn't allowed to reference like A(i)
. However, the linear indexing, the so-called array element order is an important concept. As stated in another answer the left-most index is the most rapidly varying. A(1,1,1)
comes immediately before A(2,1,1)
, ..., A(1,2,1)
, etc.
The array element order becomes useful because of various associations, and the like. For example - not that I would recommend them except with real need - equivalence
and argument association with an assumed-size array allow much the same thing.
As a more modern feature, one can have pointer bounds remapping. And, of course, with a copy, the reshape
intrinsic.
Upvotes: 3
Reputation: 48580
http://www.obliquity.com/computer/fortran/array.html explains that arrays are stored in "column-major" form, so that the left most index changes the most quickly, followed by the second to leftmost, etc. (this is the opposite of C, I believe). It seems quite unwise to try to index a multidimensional array as though it were one-dimensional, but as the above-linked page explains, your compiler will produce code that does just that (and is therefore very fast) as long as you nest your loops in the right order.
Upvotes: 6