http://ponce.sdsu.edu/fortran_book_08.html





CHAPTER 8 

 

SUBSCRIPTED VARIABLES

 

In Chapter 5 we learned how to assign values to variables, but we could assign only one value per variable. A variable which can take only one value is referred to as an unsubscripted or scalar variable. So far, we have worked only with scalar variables.

Often there is a need to assign more than one value per variable, i.e., to connect a group or "array" of values with one variable name. A variable which can take an array of values is referred to as a subscripted variable. Arrays can be of one dimension (a vector), two dimensions (a matrix), or multidimensional (a multidimensional matrix, limited to a maximum of seven dimensions).

In Chapter 3 we learned how to use declaration state ments to specify variable types (integer, real, complex, and so on). In this chapter we learn how to use the DIMENSION statement to specify the name and size of subscripted variables. The size of a subscripted variable refers to the number of values it can store for later reference.

When the program includes many subscripted variaables and corresponding DIMENSION statements, the PARAMETER statement may be used to list a common variable size as a program parameter (see Section 8.2). 

Input/output of subscripted variables is accomplished with the implied DO list, which combines the features of a DO loop and a READ/WRITE. When program units include subscripted variables, array specification is accomplished with DIMENSION statements (Section 8.1), their input/output with implied DO lists (Section 8.4), and their manipulation with one or more single or nested DO loops (Section 7.1).

8.1 ARRAY SPECIFICATION 

The specification block is a block of nonexecutable state ments which is placed immediately after the PROGRAM statement and before all executable statements in a program unit (see Table 1.1).

The specification block contains the usual declaration statements (INTEGER, REAL, COMPLEX, DOUBLE PRECISION, LOGICAL, and CHARACTER) and all other specification statements, including IMPLICIT (Section 11.6), PARAMETER and DIMENSION. INTEGER and REAL arrays may be declared implicitly or explicitly (see Chapter 3). As before, DOUBLE PRECISION, LOGICAL, and CHARACTER arrays may only be declared explicitly. 

Specification of Integer or Real Arrays that Are Declared Implicitly 

The DIMENSION statement is used to specify arrays of integer or real type that are declared implicitly. The DIMENSION statement defines:

  1. The array's name. 
  2. Its number of dimensions, and 
  3. The number of elements in each one of its dimensions, and by extension, the total number of elements (values) it can hold.

The following examples illustrate the DIMENSION statement: 

      DIMENSION ITEM(10),A(3,5) 

      DIMENSION VELOCITY(10,20,5) 

In the first example, ITEM(10) defines 

  • an integer subscripted variable or array named ITEM, 
  • the dimension of the array: one dimension, since only one number appears within the parentheses, and 
  • the number of elements or values that the array can hold (10). This may be visualized as 10 storage locations: 
  • |___ |___ |___ |___ |___ |___ |___ |___ |___ |___

In the same example, A(3,5) defines 

  • a real subscripted variable or array named A, 
  • the dimension of the array: two dimensions, since two numbers are listed within the parentheses, separated by a comma, and 
  • the number of elements or values that the array can hold (3 rows × 5 columns, making a total of 15 values). 
  • |___ |___ |___ |___ |___

    |___ |___ |___ |___ |___

    |___ |___ |___ |___ |___

In the second example, VELOCITY(10,20,5) defines

  • a real subscripted variable or array named VELOCITY, 
  • the dimension of the array: three dimensions, since three numbers are listed within the parentheses, separated by commas, and 
  • the number of elements or values that the array can hold (10 rows × 20 columns × 5 layers, making a total of 1000 values). 

A program unit may have as many DIMENSION statements as is necessary to properly specify all subscripted variables. However, several arrays may be listed in one DIMENSION statement. Thus, within one program unit, subcripted variables may be specified either (1) in one long DIMENSION statement, using column 6 for continuation, or (2) in several short DIMENSION statements, avoiding the use of column 6. The decision of whether to have one long or several short DIMENSION statements is one of individual preference.

Specification of Integer or Real Arrays that are Declared Explicitly 

The specification of arrays of integer or real type that are declared explicitly is accomplished in either of the following ways: 

  1. Using a declaration statement (INTEGER or REAL) to declare the variable type, and a DIMENSION statement to size the subscripted variable, or 
  2. Using a declaration statement (INTEGER or REAL) to declare and size the subscripted variable, therefore eliminating the need for a DIMENSION statement.

 The first case is illustrated below. 

      INTEGER TEST 

      REAL LENGTH

      DIMENSION TEST(10),LENGTH(10,3) 

In these statements, TEST and LENGTH are explicitly declared as integer and real variables, respectively, and they are specified as one- and two-dimensional arrays, respectively, by the DIMENSION statement.

The second case is the following: 

      INTEGER TEST(10) 

      REAL LENGTH(10,3)

In these statements, TEST and LENGTH are explicitly declared as integer and real variables, and specified in the declaration statement as one- and two-dimensional arrays, respectively. Both of these cases are equivalent. 

Note that a subscripted variable may be specified only once in a program unit. Therefore, the following set of statements will cause an error during compilation, because the size of the array TEST has been defined twice. 

      INTEGER TEST(10) 

      REAL LENGTH 

      DIMENSION TEST(10),LENGTH(10,3)

Arrays of Logical and Character Type

The specification of arrays of logical or character type is accomplished with the LOGICAL or CHARACTER state ments, respectively, as illustrated by the following examples:

      LOGICAL SWITCH(10) 

      CHARACTER*15 NAME(12),SSNO(12)*11 

In these examples: 

  • SWITCH is the name of a one-dimensional logical array which can store up to 10 values (either .TRUE. or .FALSE.); 
  • NAME is the name of a one-dimensional character array of 15-character maximum length, which can store up to 12 values; and 
  • SSNO is the name of a one-dimensional character array of 11-character maximum length, which can store up to 12 values. 

Lower and Upper Bounds of Arrays 

Arrays have lower and upper bounds. The lower bound of a one-dimensional array is the subscript number of its first (base) element; the upper bound is the subscript of its last element. 

The array bounds are specified in the DIMENSION or declaration (INTEGER or REAL) statements. 

For example, in

      DIMENSION A(1:10) 

the lower bound is 1 and the upper bound is 10. This array can hold up to 10 elements or values, subscripted from 1 to 10. 

As another example, in

      DIMENSION A(0:20) 

the lower bound is 0 and the upper bound is 20. This array can hold up to 21 elements, subcripted from 0 to 20.

If the lower bound is equal to 1, it can be omitted. For instance, in

      DIMENSION A(30) 

the lower bound is 1 and the upper bound is 30. This array can hold up to 30 elements, subscripted from 1 to 30.

As another example, in

      DIMENSION A(-10:10),B(-5:25)

the lower bound of array A is -10, and the upper bound is +10. This array can hold up to 21 values, subcripted from -10 to +10, including 0. Likewise, array B can hold up to 31 values, subscripted from -5 to +25, including 0.

Another example is: 

      DIMENSION C(0:10,0:5) 

Array C is a two-dimensional array. It can hold 11 rows, subscripted from 0 to 10, and 6 columns, subscripted from 0 to 5, for a total of 11 × 6 = 66 values.

 
8.2 PARAMETER STATEMENT 

The PARAMETER statement is a nonexecutable statement placed within the specification block, i.e., on top of the program unit (see Table 1.1). It is an important statement because it is used to permanently associate a variable name (to be taken as a program parameter) with a constant or with a constant arising from the execution of a constant expression. The PARAMETER statement takes the form: 

PARAMETER (p1=c1, p2=c2, p3=c3,...) 

where p1, p2, and p3 are parameters, and c1, c2, and c3 are constants or constant expressions. The parentheses en closing the parameter list are required in standard Fortran; however, they may be optional in some extensions. 

An example of a PARAMETER statement is: 

      PARAMETER (PI=3.1416) 

Adhere to the following guidelines: 

  • The data type of a parameter is determined either by an explicit type declaration (using INTEGER or REAL statements) or by following the rules for implicit type declaration (i.e., variables starting with I, J, K, L, M, and N are integers; otherwise, they are real). 
  • A parameter may be defined only by a PARAMETER statement, and only once in a program unit. It cannot be redefined, i.e., assigned a new value, elsewhere in the program unit. 
  • Once defined in a PARAMETER statement, a parameter can be referenced anywhere in a program unit, except in FORMAT statements. However, some Fortran exten sions allow the use of parameters in FORMAT state ments. 
  • A parameter may be used as a length specifier in a CHARACTER statement, but only provided it is en closed in parentheses. For example, in:
  •       CHARACTER*(NC) ALPHA

    the character variable ALPHA has a maximum length of NC characters. The value of NC should be defined in the specification block, prior to the appearance of this statement (see next Section). 


8.3 SEQUENCE OF STATEMENTS IN SPECIFICATION BLOCK

The required sequence of statements in the specification block is that which assures that all variable types are declared and all parameters are defined prior to their usage within the block. If this does not occur, errors will result during compilation or execution. For example: 

      LOGICAL FLAG

      PARAMETER (FLAG=.TRUE.)

      PARAMETER (NC=10)

      CHARACTER*(NC) ALPHA10

      PARAMETER (ALPHA10='ABCDEFGHIJ')

      PARAMETER (EX=2.71828,PI=3.1416)

      PARAMETER (PIO2=PI/2)

As shown above:

  • The declaration of variable FLAG as logical type precedes the definition of FLAG as a logical parameter. 
  • The parameter NC is defined prior to its usage as a length specifier in the CHARACTER statement that follows. 
  • The declaration of variable ALPHA10 as character type precedes the definition of ALPHA10 as a character parameter.
  • The parameter PI is properly defined prior to its usage in the constant expression of the PARAMETER statement that follows. 

Alternatively, the specification block shown above can be written as follows:

      LOGICAL FLAG

      CHARACTER*(*) ALPHA10

      PARAMETER (FLAG=.TRUE.)

      PARAMETER (ALPHA10='ABCDEFGHIJ')

      PARAMETER (EX=2.71828,PI=3.1416)

      PARAMETER (PIO2=PI/2)

In this example, the asterisk * has been used as a free length specifier in place of the parameter NC in the CHARACTER statement. This eliminates the need for prior definition of the parameter NC.

Sizing DIMENSION Statements with Parameters

The PARAMETER statement can be used to conveniently size one or more DIMENSION statements. This is particularly useful when many arrays have the same size, as shown in the set of statements that follow:

      PARAMETER (NR=10,NC=20,NL=5)

      DIMENSION A(NR),B(NR),C(NR),D(NR)

      DIMENSION XX(NR,NC),YY(NR,NC)

      DIMENSION ZZ(NR,NC,NL)

In this example, a change in parameter will cause an automatic and corresponding adjustment in one or more DIMENSION statements. The defining PARAMETER statement must precede the DIMENSION statement that references the parameter. 


8.4 INPUT/OUTPUT OF ARRAYS 

Often, arrays are read from an input file or written to an output file. This input/output is usually performed with an implied DO list.

An implied DO list is a combination of a DO loop and a READ or WRITE in one statement. Using implied DO lists, array input/output can be accomplished by either

  •  Using one or more implied DO lists, or 
  • Combining an implied DO list with an explicit DO loop. The choice between these is one of individual preference. 

Rules governing the interaction between: (1) implied DO lists, (2) combined implied DO list and explicit DO loop, and (3) formatted and unformatted input/output are discussed below.

Implied DO Lists in READ/WRITE Statements

 The following examples illustrate the usage of the implied DO list. 

Example 1 

      READ(5,10) (A(J),J=1,10)

      WRITE(6,20) (B(J),C(J),J=1,20)

      READ(5,30) ((D(J,K),E(J,K),J=1,10),K=1,5)

      WRITE(6,40)(((F(J,K,L),J=1,8),K=1,5),L=1,3)

The J in A(J),J=1,10 is the control variable of the DO loop (see Section 7.1). Likewise, the K and L are control variables of nested DO loops.

Note the required syntax of implied DO lists:

  • The implied DO lists are enclosed within parentheses, and follow the respective READ or WRITE statement. 
  • One-dimensional arrays are enclosed within one set of parentheses; two-dimensional arrays within two sets; and so on. 
  • The commas between and immediately following the variable lists are required. 

In this example, the first statement reads 10 values of one-dimensional array A. The second statement writes 20 pairs of values of one-dimensional arrays B and C. The third statement reads 10 × 5 = 50 pairs of values of two- dimensional arrays D and E. The fourth statement writes 8 × 5 × 3 = 120 values of three-dimensional array F. The format statements have not been included.

Example 2 

      WRITE(6,100) (B(J),C(J),J=2,20,2) 

      READ(5,200) ((D(J,1),E(J,1),J=1,10) 

      WRITE(6,300) ((F(J,K,1),J=1,8),K=1,5)

     The first statement writes 10 even values of one- dimensional arrays B and C. The second statement reads 10 pairs of values of two-dimensional arrays D and E (a total of 20 values) and assigns them to the first column of the respective arrays. The third statement writes 8 × 5 = 40 values of three-dimensional array F and assigns them to the first layer (the third dimension) of the array. Again, the format statements have not been included. 

Example 3

      DIMENSION A(8)

      READ(5,400) (A(J),J=1,5)

  400 FORMAT(5F10.2)

      The array A has 8 elements; the first 5 elements are being read, five to a record, following format 400. 

Example 4

In the special case when all the elements of the array are being read (or written in the case of output), the implied DO list of Example 3 can be simplified as follows:

      DIMENSION A(8)

      READ(5,500) A

  500 FORMAT(8F10.2)

Example 5 

      DIMENSION B(10,20)

      READ(5,600) ((B(J,K),J=1,10),K=1,20)

  600 FORMAT(10F8.2)

In this example, the two-dimensional array B contains 10 × 20 = 200 elements, all of which are being read. 

Input/output of two-dimensional arrays can be accom plished in either: (1) column order, or (2) row order. In Example 5, matrix B is being read in column order, i.e., first, column K = 1 is read, with J varying from 1 to 10; then, column K = 2 is read, with J varying from 1 to 10; and so on, until the last column (K = 20) is read.

 Example 6 

 

      DIMENSION B(10,20)

      READ(5,600) ((B(J,K),K=1,20),J=1,10)

  600 FORMAT(10F8.2)

This is the same as Example 5, but with matrix B being read in row order, i.e., first, row J= 1 is read, with K vary ing from 1 to 20; then, row J= 2 is read, with K varying from 1 to 20; and so on, until the last row (J= 10) is read.

 Example 7 

      DIMENSION B(10,20) 

      READ(5,600) B 

  600 FORMAT(10F8.2)

This example should be compared with Examples 5 and 6 above. The implied DO list has been shortened to contain only the name of the array (B). In this case, the processor expects to read the entire array (10 rows by 20 columns, i.e., 200 values), and the data must be arranged by the programmer and read in column order. 

Combined Implied DO Lists with Explicit DO Loops

Implied DO lists of arrays of two or more dimensions can be written by combining an implied DO list with one or more explicit DO loops. 

For instance, compare the implied DO list

      READ(5,100) ((D(J,K),E(J,K),J=1,5),K=1,15)

  100 FORMAT(10F8.2)

with the combined implied DO list and explicit DO loop: 

      DO K= 1,15

      READ(5,100) (D(J,K),E(J,K),J=1,5)

      END DO

  100 FORMAT(10F8.2)

The two forms accomplish the same task of reading 15 records, each containing 5 pairs (10 values).

As another example, compare the implied DO list

      WRITE(6,200)(((F(J,K,L),J=1,8),K=1,5),L=1,3) 

with the combined implied DO list and explicit DO loop: 

      DO L= 1,3 

      WRITE(6,200) ((F(J,K,L),J=1,8),K=1,5) 

      END DO

or, alternatively, with the combined implied DO list and two explicit DO loops: 

      DO L= 1,3

      DO K= 1,5

      WRITE(6,200) (F(J,K,L),J=1,8) 

      END DO

      END DO 

The three forms may accomplish the task, depending on the nature of the list-to-format interaction (see following section).

 
8.5 LIST-TO-FORMAT INTERACTION 

The implied DO lists interact with formatted or unformatted input/output. There are four areas of interaction:

  1. Implied DO lists with FORMAT statements. 
  2. Implied DO lists with unformatted READ and WRITE. 
  3. Combined implied DO lists and explicit DO loops with FORMAT statements. 
  4. Combined implied DO lists and explicit DO loops with unformatted READ and WRITE. 

Interaction of Implied DO Lists with FORMAT Statements 

The interaction of implied DO lists with FORMAT statements follows rules similar to those applicable to input/output of variable lists (Section 6.3). The implied DO list retains control, and it executes the transfer of a number of data items equal to the number of subscripted variables on the list, multiplied by the number of values to read or write per variable. For example, 

      READ(5,100) (A(J),B(J),J=1,10) 

will read two variables (A and B), 10 values per variable, for a total of 20 values transferred. 

      WRITE(6,200) ((C(J,1),D(J,1),J=1,15)

will write two variables (C and D), 15 values per variable, for a total of 30 values transferred. 

      READ(5,300) ((F(J,K,1),J=1,5),K=1,8) 

will read one variable (F), in 5 rows, 8 columns, and 1 layer, for a total of 40 values transferred. 

In each of the above examples, the implied DO list interacts with its format as one READ/WRITE statement. Therefore, the format is referenced only once to transfer the entire DO list. 

Note the following:

  • If the field descriptor list is longer than the implied DO list, the latter takes precedence: the processor uses, from left to right, only as many fields as needed to accomplish the transfer of all items listed on the implied DO list. 

  • If the field descriptor list is shorter than the implied DO list, the processor treats the format specification as typical, and repeats it as many times as needed to accomplish the transfer of all items on the implied DO list. During repeated execution of the field descriptor list, the processor ignores any remaining unused fields. 

Example 1 

      READ(5,100) (A(J),J=1,10) 

  100 FORMAT(10F8.2)

The implied DO list has 10 values of array A, and it is connected to format 100, whose field descriptor specifies 10 real fields of 8 characters each. The number of values in the implied DO list (10) exactly matches the number of fields specified in the format (10). Ten real values of array A will be read under the specified format.

Example 2 

      READ(5,200) (B(J),J=1,5) 

  200 FORMAT(8F10.2) 

The implied DO list has 5 values of array B, and it is connected to format 200, whose field descriptor specifies 8 real fields of 10 characters each. The field descriptor list is longer than the implied DO list. Therefore, 5 real values of array B will be read under the specified format. The remaining unused three fields (8 - 5 = 3) will be ignored. 

Example 3

      READ(5,300) (C(J),J=1,20) 

  300 FORMAT(10F8.2) 

The implied DO list has 20 values of array C, and it is connected to format 300, whose field descriptor specifies 10 real fields of 8 characters each. The field descriptor is shorter than the implied DO list; therefore, the format is interpreted as typical. Twenty real values of array C will be read under the specified format, ten in each of two data records. 

Example 4 

      WRITE(6,400) (D(K),E(K),K=1,120) 

  400 FORMAT(1X,12F10.0) 

The implied DO list has two variables (arrays D and E), and 120 values per variable, for a total of 240 paired values. It is connected to format 400, whose field descrip tor specifies 12 real fields of 10 characters each. The field descriptor list is shorter than the implied DO list; there fore, the format is interpreted as typical. One-hundred- and-twenty pairs of real values of arrays D and E will be written under the specified format, six pairs per record, for a total of twenty records.

Example 5

      WRITE(6,500)((F(J,K,1),J=1,8),K=1,4) 

  500 FORMAT(1X,8E15.6) 

The implied DO list has one three-dimensional variable F, with 8 rows, 4 columns, and only 1 layer, for a total of 32 values. It is connected to format 500, whose field descriptor specifies 8 real E fields of 15 characters each. The field descriptor is shorter than the implied DO list; therefore, the format is interpreted as typical. Thirty-two values of real three-dimensional array F will be written under the specified format, eight values per record, for a total of four records. The first record contains all J values for K= 1; the second all J values for K= 2; and so on. 

Example 6 

      WRITE(6,500)((F(J,K,1),J=1,4),K=1,8) 

  500 FORMAT(1X,8E15.6) 

This example is similar to Example 5. The field descriptor list is shorter than the implied DO list; therefore, the format is interpreted as typical. Thirty-two values of real three-dimensional array F will be written, 8 values per record, for a total of 4 records. However, unlike Example 5, the first record contains all J values for K= 1, followed by all J values for K= 2; the second record contains all J values for K= 3, followed by all J values for K= 4; and so on. 

Example 7 

      WRITE(6,510)((F(J,K,1),J=1,4),K=1,8) 

  510 FORMAT(1X,E15.6)

 This example is similar to Examples 5 and 6, except that the format specification contains only one field descriptor (E15.6). The field descriptor list is shorter than the implied DO list; therefore, the format is interpreted as typical. Thirty-two values of real three-dimensional array F will be written, one per record, for a total of thirty-two records. The first record contains the value for J= 1 and K= 1; the second for J= 2 and K= 1; the third for J= 3 and K=1; and so on.

Interaction of Implied DO Lists with Unformatted READ and WRITE 

The interaction of implied DO lists with unformatted READ and WRITE follows rules similar to those applicable to input/output of variable lists (Section 6.3). Control remains with the implied DO list, which executes the transfer of a number of data items equal to the number of subscripted variables on the list, multiplied by the number of values to read or write per variable.

For example, 

      READ(5,*) (A(J),B(J),J=1,15) 

will read two variables (A and B), 15 values per variable, for a total of 15 pairs = 30 values transferred, in free format (see Section 2.5 for unformatted input/output rules). The processor will read as many records as needed to accomplish the transfer of 30 values. At least one record will be read. In this case, it is likely that several records will be read. 

Likewise, the following example 

     WRITE(6,*) ((C(J,K),J=1,4),K=1,8) 

will write a two-dimensional matrix (C), of 4 rows by 8 columns, for a total of 32 values transferred, in free format. The processor will write as many records as needed to accomplish the transfer of 32 values. Assuming that the processor writes five values per record under free format, this example will write seven records, the first six with five values each, and the last one with the two remaining values. 

Writing arrays in free format may change the character of the array (visually confuse rows and columns) and, therefore, is not recommended. Arrays, particularly two- and three-dimensional arrays, should always be written following a format.

Interaction of Combined Implied DO Lists and Explicit DO Loops with FORMAT Statements

The interaction of combined implied DO lists and explicit DO loops with FORMAT statements follows rules similar to those applicable to that of implied DO lists with FORMAT statements. Control remains with the implied DO list, which executes the transfer of a number of data items equal to the number of subscripted variables on the list, multiplied by the number of values to read or write per variable. 

There is, however, one important difference. Unlike the implied DO list, which interacts with the FORMAT as one statement, the combined implied DO list and explicit DO loops interact with the FORMAT as two or more state ments. This is because the FORMAT is referenced as many times as required by the explicit DO loops.

Example 1 

      DO K= 1,4 

      READ(5,100) (A(J,K),J=1,8) 

      END DO 

   100 FORMAT(8F10.2) 

The combined implied DO list and explicit DO loop has one two-dimensional variable (A), of 8 rows by 4 columns, for a total of 8 × 4 = 32 values. The implied DO list is connected to format 100, whose field descriptor specifies 8 real fields of 10 characters each. Notice that the number of values in the implied DO list (8) matches exactly the number of fields specified in the format (8). 

Eight real values of array A will be read with the implied DO loop under the specified format. The format will be referenced four times by the explicit DO loop, transfer ring 4 data records, 8 values per record, for a total of 4 X 8 = 32 values. The first record contains all eight J values for K= 1; the second all eight J values for K= 2; and so on. 

Example 2 

      DO K= 1,4 

      READ(5,200) (A(J,K),J=1,6) 

      END DO 

  200 FORMAT(8F10.2)

This is similar to Example 1, but the two-dimensional variable A has 6 rows by 4 columns, for a total of 6 × 4 = 24 values. The implied DO list is connected to format 200, whose field descriptor specifies 8 real fields of 10 characters each. The number of values specified in the format (8) is longer than the number of values in the implied DO list (6), which takes precedence.

Six real values of array A will be read in the first record under the specified format; the remaining two fields will be ignored. The format will be referenced four times by the explicit DO loop, transferring 4 data records, 6 values per record, for a total of 4 × 6 = 24 values. The first record contains all six J values for K= 1; the second all six J values for K= 2; and so on. 

Example 3 

      DO K= 1,4 

      READ(5,300) (A(J,K),J=1,8)

      END DO 

  300 FORMAT(4F10.2) 

This is similar to Example 1, but uses a slightly different format. The implied DO list is connected to format 300, whose field descriptor specifies 4 real fields of 10 characters each. The number of values specified in the format (4) is shorter than the number of values in the implied DO list (8); therefore, the format is interpreted as typical.

Four real values of array A will be read with the implied DO loop in the first record, and the remaining four in the second record. The format will be referenced four times by the explicit DO loop, transferring 8 data records, 4 values per record, for a total of 8 × 4 = 32 values. The first and second records contains all eight J values for K= 1; the third and fourth all eight J values for K= 2; and so on. 

Example 4 

      DO L= 1,2 

      DO K= 1,4 

      WRITE(6,400) (B(J,K,L),J=1,6) 

      END DO 

      END DO 

  400 FORMAT(1X,8F10.3)

The combined implied DO list and two nested explicit DO loops have one three-dimensional variable (B), of 6 rows, 4 columns, and 2 layers, for a total of 6 × 4 × 2 = 48 values. The implied DO list is connected to format 400, whose field descriptor specifies 8 real fields of 10 characters each. The number of values specified in the format (8) is longer than the number of values in the implied DO list (6), which takes precedence. 

Six real values of array B will be written in the first record under the specified format; the remaining two fields will be ignored. The format will be referenced 2 × 4 = 8 times by the nested DO loops, transferring 8 data records, 6 values per data record, for a total of 8 × 6 = 48 values. The first record contains all six J values for K =1 and L = 1; the second all six J values for K= 2 and L= 1; and so on. 

Example 5

      DO L= 1,2

      WRITE(6,500) ((B(J,K,L),J=1,6),K=1,4)

      END DO 

  500 FORMAT(1X,8F10.3) 

This is similar to Example 4, but uses only one explicit DO loop instead of two. The implied DO list is connected to format 500, whose field descriptor specifies 8 real fields of 10 characters each. The number of values specified in the format (8) is shorter than the number of values in the implied DO list (6 × 4 = 24); therefore, the format is interpreted as typical. 

The implied DO list will write twenty-four real values of array B, eight values per record, making a total of three records. The format will be referenced twice by the explicit DO loop, each time transferring 3 data records and 8 values per record, for a total of 2 × 3 × 8 = 48 values. The first record contains all six J values for K = 1 and L = 1, and the first two J values for K = 2 and L = 1; the second record contains the remaining four values for K = 2 and L = 1, and the first four values for K = 3 and L = 1, and so on.

This type of list-to-format interaction will change the character of the array (visually confuse rows, columns, and layers), and therefore, is not recommended. A better way of writing array B is shown in the following example.

Example 6 

      DO L= 1,2 

      WRITE(6,600) ((B(J,K,L),J=1,6),K=1,4)

      END DO 

  600 FORMAT(1X,6F10.3) 

This differs from Example 5 in that it uses a slightly different format. The implied DO list is connected to format 600, whose field descriptor specifies 6 real fields of 10 characters each. The number of values specified in the format (6) is shorter than the number of values in the implied DO list (6 x 4 = 24); therefore, the format is interpreted as typical.

The implied DO list will write twenty-four real values of array B, six values per record, for a total of four records. The format will be referenced twice by the explicit DO loop, each time transferring 4 data records and 6 values per record, making a total of 2 × 4 × 6 = 48 values. The first record contains all six J values for K= 1 and L= 1; the second contains all six J values for K= 2 and L= 1; and so on. Unlike Example 5, this type of list-to-format interaction does not alter the visual character of the array.

Interaction of Combined Implied DO Lists and Explicit DO Loops with Unformatted READ and WRITE 

The interaction of combined implied DO lists and explicit DO loops with unformatted READ and WRITE follows rules similar to those applicable to implied DO lists. As before, control remains with the implied DO list, which executes the transfer of a number of data items equal to the number of subscripted variables on the list, multiplied by the number of values to read or write per variable.

However, unlike the implied DO list, which interacts with the free format as one statement, the combined implied DO list and explicit DO loops interact with the free format as two or more statements. 

Example 1 

      DO K= 1,4

      READ(5,*) (A(J,K),J=1,8)

      END DO 

The combined implied DO list and explicit DO loop has one two-dimensional variable, of 8 rows by 4 columns, for a total of 8 × 4 = 32 values. Eight real values of array A will be read by the implied DO loop in free format. The free format will be referenced 4 times by the explicit DO loop, transferring a total of 8 × 4 = 32 values. At least 4 records will be read. As many as 32 records could be read (in case that there is only one value per record). 

Example 2 

      DO 20 L= 1,2 

      DO 20 K= 1,4 

      WRITE(6,*) (B(J,K,L),J= 1,6)

      END DO

      END DO 

The combined implied DO list and two nested explicit DO loops have one three-dimensional variable (B), of 6 rows, 4 columns, and 2 layers, for a total of 6 × 4 × 2 = 48 values. Six real values of array B will be written by the implied DO loop in free format. The free format will be referenced 2 × 4 = 8 times by the nested DO loops, transferring at least 8 records, with up to 6 values per record, for a total of 8 × 6 = 48 values. Each record is written into at least one line. Remember that writing arrays in free format is not recommended because it may alter their appearance in an unpredictable manner.

Things to keep in mind with regard to list-to-format interaction: 
  • To avoid errors in input/output of arrays, try to match the number of values in an implied DO list with the field descriptor list specified in the format. 

  • For arrays of two or more dimensions, you may find it easier to use a combined implied DO list and explicit DO loop. 

  • Always write arrays using a format. 

 

 8.6 IMPLIED DO LISTS IN DATA STATEMENTS

Often it is necessary to use DATA statements to provide initial values of one or more arrays. For this purpose, the implied DO list is included in a DATA statement, as illustrated by the following examples: 

Example 1

      DIMENSION A(10) 

      DATA (A(J),J= 1,5) /1.,4.,-3.,10.,25./ 

This example considers an array A of 10 elements. The first 5 elements of the array are initialized in a DATA statement using an implied DO list. 

Example 2

      DIMENSION A(5)

      DATA (A(J),J= 1,5) /1.,4.,-3.,10.,25./ 

The array A has 5 elements. The entire array is initialized in a DATA statement using an implied DO list. 

Example 3 

      DIMENSION A(5)

      DATA A /1.,4.,-3.,10.,25./ 

This is similar to Example 2. Since the entire array is being initialized, the reference to the implied DO list in the DATA statement may be omitted. 

Example 4 

      DIMENSION B(4,6) 

      DATA

     *((B(J,K),K=1,3),J=1,2) /3.,4.,7.,2.,9.,-0.5/ 

The two-dimensional array B has 4 rows by 6 columns, for a total of 4 × 6 = 24 values. Six (2 × 3 = 6) values of the array are being initialized. Note that the array is being initialized in row order, i.e., first, all K values of row J= 1, second, all K values of row J= 2. The matrix B is stored as follows:

                  column 1             column 2                column 3 

        row 1             3.                         4.                           7. 

        row 2             2.                         9.                        -0.5 

Example 5 

      DIMENSION B(2,3) 

      DATA

     *((B(J,K),K=1,3),J=1,2)/3.,4.,7.,2.,9.,-0.5/ 

This is similar to Example 4, with the difference that the entire array is being initialized. As with Example 4, the array is being initialized in row order, i.e., first, all K values of row J= 1, second, all K values of row J= 2. 

Example 6 

      DIMENSION B(2,3)

      DATA

     *(B(J,K),J=1,2),K=1,3)/3.,4.,7.,2.,9.,-0.5/ 

This is similar to Example 5, with the difference that the array is being initialized in column order, i.e., first, all J values of column K= 1; second, all J values of column K= 2; third, all J values of column K= 3. The matrix B is stored as follows:

                  column 1              column 2                column 3 

        row 1             3.                         7.                           9. 

        row 2             4.                         2.                        -0.5 

Example 7 

      DIMENSION B(2,3)

      DATA B /3.,4.,7.,2.,9.,-0.5/ 

This is the same as Example 6. The array has 6 values (2 × 3), and the DATA statement lists 6 values, i.e., the entire array is being initialized. In this case, the reference to the implied DO list in the DATA statement may be omitted. 

If a DATA statement contains an array, and the implied DO list is missing, the array is assumed to be in column order, and is stored as such.

Example 8

      DIMENSION C(5,12)

      DATA C /60*1./ 

The entire array C, consisting of 5 × 12 = 60 values, has been initialized with an implied DO list in a DATA statement. A repeat counter 60, placed within the delimiting slashes and preceding the asterisk, is used to express that all elements are being initialized with the value 1. As with Example 7, the reference to the implied DO list has been omitted.

Example 9 

      DIMENSION C(5,12) 

      DATA C /28*1.,32*0./

This is similar to Example 8. The array C consists of 5 × 12= 60 values. The entire array is being initialized with an implied DO list. The reference to the implied DO list has been omitted. A repeat counter is used to express that the first 28 elements are being initialized with the value 1., and the remaining 32 with the value 0. 

The array C is stored in column order as shown below. 

column no.      1  2  3  4  5  6  7  8  9 10  11  12

 row 1               1. 1. 1. 1. 1. 1. 0. 0. 0.  0.   0.   0.

 row 2               1. 1. 1. 1. 1. 1. 0. 0. 0.  0.   0.   0.

 row 3               1. 1. 1. 1. 1. 1. 0. 0. 0.  0.   0.   0.

 row 4               1. 1. 1. 1. 1. 0. 0. 0. 0.  0.   0.   0.

 row 5               1. 1. 1. 1. 1. 0. 0. 0. 0.  0.   0.   0. 

 

8.7 SORTING OF ARRAYS: THE BUBBLE SORT 

When working with arrays, you may need to sort the entries to arrange them in a specific order. For instance, consider the following one-dimensional array A:

12.            45.            23.            87.            51.            20.            11. 

To arrange it in ascending order, i.e., to produce 

11.            12.            20.            23.            45.            51.            87. 

a sorting procedure must be implemented.

The bubble sort is a commonly used sorting procedure. In a bubble sort, the values of two variables (addresses) A(J) and A(J+1) are to be interchanged. First, a temporary variable TEMP is created by assigning the value of A(J) to TEMP. Second, the value of A(J+1) is assigned to A(J). Third, the value of TEMP, i.e., the value of A(J), is assigned to A(J+1). This procedure effectively switches the values of A(J) and A(J+1). 

The following program implements a bubble sort for the previous example. 

Example Program: Bubble Sort 

C234567890

      PROGRAM BUBBLE_SORT

      PARAMETER (N=7)

      DIMENSION A(N)

      OPEN(5,FILE='SORT.DAT',STATUS='UNKNOWN') 

      OPEN(6,FILE='SORT.OUT',STATUS='UNKNOWN') 

      READ(5,*) (A(J),J=1,N) 

      DO 20 K= 1,N-1

      DO 10 J= 1,N-K

      IF(A(J).GT.A(J+1)) THEN 

      TEMP= A(J) 

      A(J)= A(J+1)

      A(J+1)= TEMP

      ENDIF 

   10 END DO 

   20 END DO 

      WRITE(6,*) (A(J),J=1,N)

      END

In this example program, each execution of the outer loop positions the largest value to the right of the array. Complete execution of the program sorts the array in ascending order.

 
8.8 EXAMPLE PROGRAM 

Matrix Multiplication 

This program reads an array A of 2 rows by 3 columns, and an array B of 3 rows by 2 columns, and multiplies the arrays to obtain C, of 2 rows by 2 columns. [Note that in order to multiply A × B, the number of columns of A (three rows) has to be equal to the number of rows of B (three columns)]. Array C has the same number of rows as A (two rows) and the same number of columns as B (two columns). 

Note the features of this program:

  • PARAMETER and DIMENSION statements are used to size the arrays A, B, and C. 
  • The outer two DO loops, with index J varying from 1 to 2, and index K varying from 1 to 2, generate an array C of 2 rows by 2 columns. 
  • The inner loop, with index L varying from 1 to 3, gener ates the four elements of array C.
  • Each element of array C is equal to the sum of the prod ucts of A(J,L) times B(L,K), where L varies from 1 to 3, with 3 being the number of columns of A and the number of rows of B. 

Example Program: Matrix Multiplication 

C234567890

      PROGRAM MATRIX_MULT 

      PARAMETER (MZ=2,NZ=3) 

      DIMENSION A(MZ,NZ),B(NZ,MZ),C(MZ,MZ) 

      DATA C/4*0./ 

      READ(5,100)((A(J,K),K=1,NZ),J=1,MZ) 

      READ(5,110)((B(J,K),K=1,MZ),J=1,NZ)

      DO 10 J= 1,MZ 

        DO 10 K= 1,MZ

          DO 10 L= 1,NZ

          C(J,K)= C(J,K) + A(J,L)*B(L,K) 

   10 END DO

      WRITE(6,200) ((C(J,K),K=1,MZ),J=1,MZ) 

  100 FORMAT(3F5.0) 

  110 FORMAT(2F5.0)

  200 FORMAT(1X,2F5.0)

      END

      The input arrays are: 

A= 1.      2.      3.            B= 7.      1. 

     4.       5.      6.                 8.       2. 

                                            9.       3.

     The output array is: 

C= 50.      14.

     122.     32.

For instance, the first row and column of the output array C is:
1 × 7 + 2 × 8 + 3 × 9 = 7 + 16 + 27 = 50.

 
8.9 SUMMARY

 This chapter describes subscripted variables, which can take an array of values. 

  • The name and size of a subscripted variable (the number of values it can take) is specified in a DIMENSION statement. 

  • The specification of subscripted variables is made in the specification block, a block of nonexecutable statements which is placed immediately after the PROGRAM statement and before all executable statements. 

  • Subscripted variables (arrays) can be of integer, real, logical, or character type. 

  • The PARAMETER statement specifies program parameters, which unlike variables, cannot be redefined elsewhere in the program unit. 

  • The PARAMETER statement helps in conveniently setting up the specification block, particularly when declaring many subscripted variables.

  • The implied DO list combines the features of DO and READ/WRITE statements into one. 

  • Implied DO lists can be combined with explicit DO loops to accomplish the transfer of data in many ways, both formatted and unformatted

  • The list-to-format interaction has the following rules: 

    • If the format is longer than the list, the latter takes precedence.

    • If the format is shorter than the list, the format is re garded as typical, and repeated as many times as needed to accomplish the transfer of the entire list. 

  • Implied DO lists can also be used in conjunction with DATA statements. 

  • The bubble sort is a procedure to interchange the values of subscripted variables.

 
CHAPTER 8--PROBLEMS

1. Solve Problem 4.5 (water utility billing) using formatted input/output, subscripted variables, and two indexed DO loops, one to calculate the values and another to print them.

2. Solve Problem 4.10 (electric utility billing) using formatted input/output, subscripted variables, and two indexed DO loops, one to cal culate the values and another to print them. 

3. Solve Problem 6.3 (natural log table) using subscripted variables. Use a two-dimensional array, nested DO loops, and combined explicit DO loops and implied DO lists. 

4. Solve Problem 6.7 (table of hyperbolic sines) using using subscripted variables. Use a two-dimensional array, nested DO loops, and combined explicit DO loops and implied DO lists. 

5. Solve Problem 6.11 (radian-to-degree conversion table) using subscripted variables. Use two indexed DO loops, one to calculate the values and another to print them.

6. Solve Problem 7.12 (annuity table) using a one-dimensional array for the annuity factor A/P. 

7. Solve Problem 7.12 (annuity table) using a two-dimensional array for the annuity factor A/P. Calculate and print the array in two separate DO loops. 

8. Solve Problem 7.19 using subscripted variables. Include the calculation of the median, the value which divides the distribution into two equal parts (half of the values are lower than the median). 

9. Write a program to read a two-dimensional array of M rows by N columns, and to search for and report the entry having the minimum absolute value. Test your program with the following array: 

    11.      34.      67.      -12.       23.      76.      12.

-10.5      43.      78.      112.    -13.     -12.      56.5 

-120.      56.      23.      78.       90.      111.      90.1

10. Write a program to read a two-dimensional array of M rows by N columns, to sum all rows and all columns, and to report the row or column with the minimum sum. As an example, the output should read: ROW 3 HAS THE MINIMUM SUM, EQUAL TO 34.5. Test your program with the input array of Problem 8.9. 

11. Write a program to read from an input file a two-dimensional array of M rows by N columns, to sort all rows in descending order, and print the sorted array to an output file. Test your program with the input array of Problem 8.9.

12. Write a program to read from an input file a two-dimensional array of M rows by N columns, to sort all columns in ascending order, and print the sorted array to an output file. Test your program with the input array of Problem 8.9. 

13. Write a program to read a square matrix of size N, and to calculate and report the average of the entries in the outside rows and columns, and the average of the inside entries. Test your program with the following matrix:

10. 12. 13. 12. 15. 18. 

11. 23. 21. 17. 13. 10. 

12. 21. 10. 16. 12. 14.

12. 13. 14. 16. 12. 20.

10. 12. 14. 21. 22. 21. 

15. 12. 13. 23. 21. 20. 

14. Write a program to read a square matrix A of size N (for N even), and to partition the matrix into four square submatrices each of size N/2. If N is not even, print an appropriate message and stop execution. Calculate and report a square matrix B, of size 2, with each entry being the average of all entries in each of the four square submatrices. Test your program with the input array of Problem 8.13. 

10. 12. 13. 12. 15. 18.

11. 23. 21. 17. 13. 10.

12. 21. 10. 16. 12. 14.

12. 13. 14. 16. 12. 20. 

10. 12. 14. 21. 22. 21. 

15. 12. 13. 23. 21. 20.

15. Solve Problem 7.17 (numeral design) using subscripted variables.

16. Write a program to print the following numeric pattern: 



0123456789 


1012345678 


2101234567


3210123456 


4321012345 


5432101234


6543210123


7654321012 


8765432101 


9876543210 

Use subscripted variables, and a combined implied DO list and explicit DO loop.

17. Write a program to calculate the parameters a, b, and c of the nonlinear equation z= axbyc, given three data arrays x, y, and z, of n elements each. Taking u= log x, v= log y, and w= log z, use the following regression equations (Σ is the summation from 1 to n):

b= (AC - BE)/(A2 - DE)

c= (B - bD)/A 

a= log-1 [(Σw - b Σu - c Σv)/n] 

in which: 

A= n Σuv - Σu Σv 

B= n Σwu - Σw Σu 

C= n Σwv - Σw Σv

D= n Σ(u2)- (Σu)2

E= n Σ(v2)- (Σv)2

Test your program with the following data: 

                               Z                       X                         Y

 __________________________________________________________

                             89.                 3245.                   0.008
                             75.                 2567.                  0.011
                             57.                 2783.                  0.009 
                             34.                 1234.                  0.015 
                            101.                5345.                  0.006 
                            121.                5329.                  0.007
                              68.                3002.                  0.008 
                              79.                2976.                  0.010 
                              25.                 1034.                 0.018
                              59.                 2984.                 0.010 
                              96.                 3892.                 0.007 
                              12.                  534.                  0.020
__________________________________________________________ 

18. Eight persons take a TRUE or FALSE test containing ten questions. Write a program to calculate the number of correct answers for each person. Test your program with the following data: 

KEY      T T F F T F T F F F

JONES    T T T F F F T F T F 

LONG     F F F F F T T F T F 

MARTIN   F F F F T T F F T T

PETERS   F F F F T F T F T F 

DALEY    F F F F T F T F T F 

PEREZ    T T T F F F T F F T 

FONG     F F F F T T F T F T 

JACKSON  T T F F F T T T F T 

Your output should read, for example:

JONES    NO. OF CORRECT ANSWERS: 7


       http://ponce.sdsu.edu/fortran_book_08.html 090311