Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit do loop array initialization

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 /)
like image 664
tarrasch Avatar asked Nov 01 '10 15:11

tarrasch


People also ask

Can you initialize array in for loop?

Using For Loop: We can also use for loop to initialize an array with the same value.

What is the correct way to initialize an array?

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.

How can we initialize an array in C language?

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.

How is an array of structure initialized?

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 } };


2 Answers

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
like image 182
Tim Whitcomb Avatar answered Oct 27 '22 21:10

Tim Whitcomb


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.

like image 34
High Performance Mark Avatar answered Oct 27 '22 22:10

High Performance Mark