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.

The simplest array is the one-dimensional array, which is just a 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, while `weird` is an array
of length 237-(-162)+1 = 400.

The type of an array element can be any of the basic data types. For example:

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 squares of the numbers 1 through 10 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.

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 arbitrarily 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. For 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).

Fortran stores higher dimensional arrays as a contiguous 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. row) 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 that you
understand the distinction.

FORTRAN 77 allows arrays of up to seven dimensions. The syntax and storage format are analogous to the two-dimensional case.

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.

*Copyright © 1995-7 by Stanford University. All rights reserved.*