real a(20)declares

real b(0:19), weird(-162:237)Here,

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!

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:

The total size of the array is thenname (low_index1 : hi_index1, low_index2 : hi_index2)

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 continueThe 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).

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

whereaddr[A(i,j)] =addr[A(1,1)] + (j-1)*lda + (i-1)

real A, x dimension x(50) dimension A(10,20)are equivalent to

real A(10,20), x(50)This

[SCCM-001 Home Page] [Fortran Tutorial Home]

sarahw@hpsim.stanford.edu e for scaling a matrix that uses the subroutine

subroutine mscale(m, n, alpha, A, lda) integer m, n, lda real alpha, A(lda,*) c c Local variables integer j do 10 j = 1, n call scale(m, alpha, A(1,j) ) 10 continue return endThis version works even when m is not equal to lda since we scale one column at a time and only process the m first elements of each column (leaving the rest untouched).

- Exercise A
- Write a main program that declares a matrix
`A`byinteger nmax parameter (nmax=40) real A(nmax, nmax)

Declare appropriate vectors x and y and initialize m=10, n=20, A(i,j) = i+j-2 for 1<=i<=m and 1<=j<=n, x(j) = 1 for 1<=j<=n. Compute y = A*x by calling the matvec subroutine given in the text. Print the answer y. - Exercise B
- Write a subroutine that computes y = A*x by scalar products,
i.e. the
*j*index should be in the innermost loop. Test your routine on the example in Exercise A and compare your answers.

[AMS Home Page] [Fortran Tutorial Home]

boman@sccm.stanford.edu