Reputation: 5835
Fortran allows the use of array operations much easily. For example,
double precision :: a(3,3), b(3,3), c(3,3)
Given a
and b
are initialized, I am aware that a simple c=a+b
would result in a matrix addition. The same can be achieved using c(:,:) = a(:,:)+b(:,:)
. I am aware that the second method allows slicing of arrays with the use of appropriate indexing. Apart from this, are there any differences between these two methods? Should a particular method be preferred over other?
Upvotes: 3
Views: 1184
Reputation: 32406
In the expression
c = a + b
the references a
, b
and c
are to whole arrays. In
c(:,:) = a(:,:) + b(:,:)
the references a(:,:)
, b(:,:)
and c(:,:)
are to array sections. These are different things.
In general an array section does not have the properties of the whole array: if c
is a pointer or allocatable array even then c(:,:)
is not. Such an aspect is most notable when reallocation may occur on assignment.
In c=a+b
c
may be unallocated and will be allocated in response, but in c(:)=...
c
must be allocated before the assignment. If c
is allocated by the time of the assignment c=...
then it will be deallocated if:
c
; orc
; orc
is polymorphic and has either a different dynamic type or corresponding kind type parameters of the right-hand side expression differ from those of c
.If there is such deallocation then c
is re-allocated to match the right-hand side expression.
With the array section no such freedom exists: c(:)
must suitably match the right-hand side expression or there must be appropriate conversion available (including instead defined assignment).
There are other aspects following from the distinction of whole array and array section.
In the specific context of the question where the arrays are explicit shape then there is less to worry about.
In terms of style, one may view using the array section as adding clarity to human readers of code as "this is an array assignment" or using whole arrays as an aid to compilers in optimizing array operations. The balance between these is situation specific and King notes a related question which considers performance aspects.
Further, because of the deallocation/reallocation mentioned above, compilers are obliged to perform (potentially expensive) shape/type/type parameter checks on intrinsic assignment to allocatable whole arrays (to determine whether deallocation must happen). Using an array section means that these tests are not necessary. For example, with
c(:,:) = array_expr
the programmer guarantees that the array expression array_expr
is of the same shape as c
(if this is not the case then the fragment cannot be valid Fortran) and the compiler need not run the deallocation checks. Again, using this is a choice for the individual situation. (Also note that the compiler may offer runtime checks which look at whether such expressions match: if using this "trick" one should disable these checks.)
Upvotes: 4