Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deep array copy in Fortran

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?

like image 832
astay13 Avatar asked Aug 03 '12 16:08

astay13


2 Answers

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.

like image 96
Chris Avatar answered Nov 13 '22 19:11

Chris


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

like image 11
M. S. B. Avatar answered Nov 13 '22 20:11

M. S. B.