10. 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.

One-dimensional arrays

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. 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     We will only use the upper 3 by 3 part of this array.
      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 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 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.

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