Deep array copy in Fortran

14,889

Solution 1

The three ways you mention for copying arrays, the do loop, b(1:n) = a(1:n) and b = a, are all equivalent; they copy the contents of the array a into the array b. a and b are simply arrays, not fancy pointers or anything and so the assignment a = b is basically the same as the mathematical expression. There is no magic with references going on (that the user needs to know about), which is why Fortran is a pretty straight forward language to learn. You can have pointer arrays in Fortran, but this is a whole other issue.

M Metcalf and J Reid's Fortran 90/95 explained is always a good reference for consulting on Fortran language features. From page 48:

3.11 Array assignment

By intrinsic assignment, an array expression may be assigned to an array variable of the same shape, which is interpreted as if each element of the expression were assigned to the corresponding element of the variable. For example, with the declarations

real, dimension(10, 20) :: a

The assignment

a = a  + 1.0

replaces a(i,j) by a(i,j) + 1.0 for i=1,2..,10 and j=1,2,..,20.

Also note that a scalar expression may be assigned to an array, in which case the saclar value is broadcast to all the array elements.

In terms of how this is all actually implemented, which is what I think you are driving at with your question, this is completely unspecified by the Fortran standard. This sort of thing is left unspecified to allow compiler writers to do whatever optimisations they feel like. For example, in the assignment a = b, the order in which the elements of b are copied into a is unspecified by the standard, so different compilers could do this in different ways. All that you need to know is that for this question is that, provided a and b are not pointers, then a and b are distinct arrays and that changing an element of one does not change the corresponding element of the other. So it a sense, a=b is a "deep copy" and you can think of this as copying all items in b to the memory location of a.

Solution 2

a = b copies the entire array b into a. If you only want part of the array that is dimensioned larger than n, then you can use subscript notation a(1:n) = b(1:n). That is Fortran 90 -- it is a higher level language than FORTRAN 77. We can tell that "a = b" is a copy and not associating pointer a with target b because that statement used the operator "=". Pointer association uses =>.

Edit: by copy, it makes a duplicate, with probably the same machine code as your do loop. The pointer association makes a reference without doing the do loop to duplicate all of the array elements.

See http://en.wikipedia.org/wiki/Fortran_95_language_features

Share:
14,889
astay13
Author by

astay13

Updated on June 12, 2022

Comments

  • astay13
    astay13 almost 2 years

    I need a deep copy of a (real) array in Fortran (90), but am not sure exactly how to get one, since I do not completely understand how references work. Intuitively, I would expect this to get me what I want:

    do i=1,n
      b(i) = a(i)
    end do
    

    However, it was recently pointed out to me that b(1:n) = a(1:n) is equivalent to the code above. Intuitively, I would expect that b(1:n) = a(1:n) merely causes the reference of b(1:n) to point to the location of a(1:n) in memory.

    Is b(1:n) = a(1:n) a deep copy? Why? What is going on with the underlying references as opposed to b = a?

  • astay13
    astay13 over 11 years
    How does it copy it? By repointing the reference of a to the location of b in memory, or by moving a copy of all items in b to the location of a in memory?
  • Chris
    Chris over 11 years
    @IanH This is not something I know that much about, so I just focused on arrays in my answer. It would be interesting to see an example of the above not being the case for derived types if you want to post an answer.
  • Hristo Iliev
    Hristo Iliev over 11 years
    @astay13, Fortran is not Java or C#. It doesn't have references. It has pointers but those use special syntax to associate as M. S. B. has pointed out (=> instead of =). gfortran for example implements array copy using either memcpy (bitwise memory copy, very fast) or hidden DO loops, depending on the context.
  • IanH
    IanH over 11 years
    Apologies for that babble, it was an unfinished thought bubble that I decided was irrelevant to the question (given the poster specifically mentions REAL variables). I wasn't even aware that it had been posted.
  • astay13
    astay13 over 11 years
    @HristoIliev, yes, the question comes because Java is my first language so I'm used to thinking in terms of = being used for reference assignment.
  • Vladimir F Героям слава
    Vladimir F Героям слава over 11 years
    b(1:n) = a(1:n) and b = a are not equivalent. The former will not check for necessary reallocation, for example.
  • user26143
    user26143 over 2 years
    @VladimirF, sorry for replying this old post, would you please explain more about the necessary reallocation? thanks.
  • Vladimir F Героям слава
    Vladimir F Героям слава over 2 years
    @user26143 If the array on the left-hand side is not allocated or is allocated to a different size, a = b will automatically reallocate a to the same size as b. This requires checking whether they do conform or not. This is not necessary for b(1:n) = a(1:n) because no reallocation can happen.