Arrays |
Many scientific computations use
vectors and matrices. The data type Fortran uses for representing such objects
is the array. A one-dimensional array corresponds to a vector, while a
two-dimensional array corresponds to a matrix. To fully understand how this
works in Fortran 77, you will have to know not only the syntax for usage, but
also how these objects are stored in memory in Fortran 77.
A D V E R T I S E M E N T
One-dimensional arrays
The simplest array is the one-dimensional array, which is
just a linear sequence of elements stored consecutively in memory. For example,
the declaration
real a(20)
declares
a as a real array of length 20. That is,
a consists of 20 real numbers stored contiguously in
memory. By convention, Fortran arrays are indexed from 1 and up. Thus the first
number in the array is denoted by
a(1) and the last by
a(20). However, you may define an arbitrary index
range for your arrays using the following syntax:
real b(0:19), weird(-162:237)
Here, b
is exactly similar to a
from the previous example, except the index runs from 0 through 19.
weird is an array of
length 237-(-162)+1 = 400.
The type of an array element can be any of the basic data
types. Examples:
integer i(10)
logical aa(0:1)
double precision x(100)
Each element of an array can be thought of as a separate
variable. You reference the i'th element of array
a by
a(i). Here is a code segment that stores the 10 first square
numbers in the array sq:
integer i, sq(10)
do 100 i = 1, 10
sq(i) = i**2
100 continue
A common bug in Fortran is that the program tries to access
array elements that are out of bounds or undefined. This is the responsibility
of the programmer, and the Fortran compiler will not detect any such bugs!
Two-dimensional arrays
Matrices are very important in linear algebra. Matrices are
usually represented by two-dimensional arrays. For example, the declaration
real A(3,5)
defines a two-dimensional array of 3*5=15 real numbers. It
is useful to think of the first index as the row index, and the second as the
column index. Hence we get the graphical picture:
(1,1) (1,2) (1,3) (1,4) (1,5)
(2,1) (2,2) (2,3) (2,4) (2,5)
(3,1) (3,2) (3,3) (3,4) (3,5)
Two-dimensional arrays may also have indices in an
arbitrary defined range. The general syntax for declarations is:
name (low_index1 : hi_index1, low_index2 :
hi_index2)
The total size of the array is then
size =
(hi_index1-low_index1+1)*(hi_index2-low_index2+1)
It is quite common in Fortran to declare arrays that are
larger than the matrix we want to store. (This is because Fortran does not have
dynamic storage allocation.) This is perfectly legal. Example:
real A(3,5)
integer i,j
c
c We will only use the upper 3 by 3 part of this
array.
c
do 20 j = 1, 3
do 10 i = 1, 3
a(i,j) = real(i)/real(j)
10 continue
20 continue
The elements in the submatrix A(1:3,4:5) are undefined. Do
not assume these elements are initialized to zero by the compiler (some
compilers will do this, but not all).
Storage format for 2-dimensional arrays
Fortran stores higher
dimensional arrays as a contiguous linear sequence of elements. It is important
to know that 2-dimensional arrays are stored by column. So in the above
example, array element (1,2) will follow element (3,1). Then follows the rest of
the second column, thereafter the third column, and so on.
Consider again the example where
we only use the upper 3 by 3 submatrix of the 3 by 5 array
A(3,5). The 9
interesting elements will then be stored in the first nine memory locations,
while the last six are not used. This works out neatly because the leading
dimension is the same for both the array and the matrix we store in the
array. However, frequently the leading dimension of the array will be larger
than the first dimension of the matrix. Then the matrix will not be
stored contiguously in memory, even if the array is contiguous. For example,
suppose the declaration was
A(5,3) instead. Then there would be two "unused" memory cells between the
end of one column and the beginning of the next column (again we are assuming
the matrix is 3 by 3).
This may seem complicated, but
actually it is quite simple when you get used to it. If you are in doubt, it can
be useful to look at how the address of an array element is computed.
Each array will have some memory address assigned to the beginning of the array,
that is element (1,1). The address of element (i,j) is then given by
addr[A(i,j)] =
addr[A(1,1)] + (j-1)*lda + (i-1)
where
lda is the leading (i.e. column) dimension of
A. Note that
lda is in general
different from the actual matrix dimension. Many Fortran errors are caused by
this, so it is very important you understand the distinction!
Multi-dimensional arrays
Fortran 77 allows arrays of up to seven dimensions. The
syntax and storage format are analogous to the two-dimensional case, so we will
not spend time on this.
The dimension
statement
There is an alternate way to declare arrays in Fortran 77.
The statements
real A, x
dimension x(50)
dimension A(10,20)
are equivalent to
real A(10,20), x(50)
This
dimension statement is considered old-fashioned style today.