Deep array copy in Fortran

astay13 picture astay13 · Aug 3, 2012 · Viewed 13.4k times · Source

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?

Answer

Chris picture Chris · Aug 3, 2012

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.