Reputation: 2680
I want to initialize an array on one line with an implicit do loop. However, I always get a syntax or shape error. Can anyone help me correct the following construct?
integer myarray :: (maxdim, nr)
myarray(1:maxdim,nr) = (/ (/i,i=1,maxdim/),nr /)
Upvotes: 13
Views: 19990
Reputation: 10677
You are initializing an array with MAXDIM
rows and NR
columns, and it looks like each column contains the integers 1 to MAXDIM
.
As a first step, go ahead and write out the actual DO
-loop:
do j=1,NR
do i=1,MAXDIM
myarray(i,j) = i
end do
end do
Collapse the inner loop to an implicit loop structure:
do j = 1,NR
myarray(1:MAXDIM,j) = (/ (i, i=1,MAXDIM) /)
end do
When we try to collapse the outer loop, though, something strange happens:
myarray = (/ ((/ (i, i=1,MAXDIM) /), j=1,NR) /)
Now, I get an incompatible ranks error as you did. Since I'm not very good at the implicit do-loops either, I looked at the shape
intrinsic results for the array constructor:
print *, shape(myarray)
print *, shape((/ ((/ (i, i=1,MAXDIM) /), j=1,NR) /))
This prints out
5 10
50
The array constructor is simply expanding a 1-D array , flattening any nested array constructions. We can actually drop the second set of (/ /)
to simplify. Since everything is already in the proper order, we can use the reshape
intrinsic to ensure proper rank. My full test program is then:
program sotest
implicit none
integer, parameter :: MAXDIM = 5
integer, parameter :: NR = 10
integer :: i
integer :: j
integer :: myarray(MAXDIM, NR)
integer :: myarray_implicit(MAXDIM, NR)
do j = 1,NR
do i = 1,MAXDIM
myarray(i,j) = i
end do
end do
myarray_implicit = reshape((/ ((i,i=1,MAXDIM), j=1,NR) /), (/ MAXDIM, NR /))
print *, all(myarray == myarray_implicit)
end program sotest
Upvotes: 22
Reputation: 78324
The implicit do loop will only create a vector so you'll have to reshape that. Something like this:
integer, dimension(m,n) :: myarray
integer :: ix, jx
...
myarray = reshape( [ (ix, ix = 1, m*n) ], [ m, n ] )
or perhaps you want a more complicated, nested, implied-do loop:
myarray = reshape( [ ((ix+jx, ix = 1, m), jx = 1, n) ], [ m, n ] )
Note that I'm using the Fortran2003 convention of [ ]
to delimit array constructions, rather than (/ /)
. Note also that you have to declare the implied do loop index variables.
Upvotes: 8