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 construc
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
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.