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 /)
Using For Loop: We can also use for loop to initialize an array with the same value.
The initializer for an array is a comma-separated list of constant expressions enclosed in braces ( { } ). The initializer is preceded by an equal sign ( = ). You do not need to initialize all elements in an array.
Array Initialization Using a Loop An array can also be initialized using a loop. The loop iterates from 0 to (size - 1) for accessing all indices of the array starting from 0. The following syntax uses a “for loop” to initialize the array elements. This is the most common way to initialize an array in C.
Here is how initialize the structure : struct str { char arr1[4]; // this string is limited to three characters plus null char arr2[4]; int num1[4]; int num2[4]; }; struct str select = { "Sam", "Joe", { 0, 1, 2, 3 }, { 4, 5, 6, 7 } };
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With