Chapters 1 through 6 dealt with the basic elements of the Fortran language. Chapters 7 through 9 covered the more advanced features such as DO loops, subcripted variables, and subprograms. This chapter contains a few additional features of the Fortran language which were not covered in previous chapters. These features include:
10.1 TRANSFER OF CONTROL IN INPUT/OUTPUT
In Chapter 2 we learned how to work with the READ and WRITE statements by including two keyword specifiers in the control list (the logical unit and the format label). These were enclosed within parentheses and separated by a comma, as in READ(UNIT=5,FMT=100) A,B,C In practice, this is usually shortened to: READ(5,100) A,B,C An additional and often useful feature of the READ statement is the possibility to transfer control to an executable labeled statement if either of the following is encountered during runtime:
An example of a READ statement with keyword specifiers to accomplish transfer of control is: READ(UNIT=5,FMT=100,END=90,ERR=92) where END and ERR are the keyword specifiers for end-of-file condition and error condition, respectively. The UNIT and FMT specifiers are optional if they appear in first and second place, respectively, on the control list. Thus, the previous statement may be reduced to READ(5,100,END=90,ERR=92) The READ statement can include either the END or ERR specifiers, or both, in any order. The END= and ERR= are required. The WRITE statement can include only the ERR specifier. The statement labels to the right of the equal sign must be valid labels within the same program unit. An end-of-file condition occurs when the execution of a READ statement runs out of records to read. When a READ statement with an end-of-file specifier encounters an end-of-file, control is transferred to the statement designated by the END specifier. If there is no END specifier, control is transferred to the statement designated by the ERR specifier. Is neither END nor ERR specifier appears, execution terminates with a runtime error. For example, an end-of-file condition would occur if a READ statement within a DO loop is supposed to read 10 values, but only 9 values appear in the input file. As the 10th READ statement is executed, control searches for the 10th value and instead, it finds the end of the file. As you can see, the end-of-file feature is useful when the number of data records to be read is not fixed before hand. Such would be the case of an input file whose length varies with each application, and the calculations do not depend on the total number of values read. In this case, the READ can proceed with an end-of-file specifier, and control is transferred in an orderly manner when the entire input file has been read. An error condition occurs when an error is encountered during the execution of a READ or WRITE statement. In this case, control is transferred to the statement designated by the ERR specifier. If there is no ERR specifier, execution terminates with a runtime error. The following example program illustrates the use of END and ERR specifiers. This example counts, reads, and writes several values of variable A, one at a time, in a GO TO-CONTINUE loop according to format 100. If an end-of-file condition is encountered during the execution of the READ statement (no more records are found in the input file), control is transferred to statement 90, an appropriate message is printed, and STOP 90 terminates execution. If an error is encountered during READ (for instance, the occurrence of an extraneous character such as @), control is transferred to statement 92, an appropriate message is printed, and STOP 92 terminates execution. If an error is encountered during WRITE (perhaps, a field overflow due to an insufficient format), control is transferred to statement 94, an appropriate message is printed, and STOP 94 terminates execution. Example Program: Transfer of Control in Input/Output
10.2 COMPLEX INTRINSIC FUNCTIONS
Complex Arithmetic In arithmetic, a complex number is written as a + bi where a is the real part, b is the imaginary part, and i = √ -1 = (-1)1/2. In Fortran, a complex number is written as (a,b) The modulus c of a complex number is its absolute value, that is, the hypotenuse of a right triangle of sides a and b : c = (a2 + b2)1/2 The conjugate of a complex number (a + bi) is the complex number (a - bi). Conversely, the conjugate of complex number (a - bi) is (a + bi). The following intrinsic functions related to complex numbers are valid:
CMPLX takes two integer or real values as arguments and converts them into the real and imaginary parts of a complex value. It has the form: Z= CMPLX(A,B) in which Z is a complex variable, A is an integer/real variable/constant assigned to the real part of Z, and B is an integer/real variable/constant assigned to the imaginary part of Z. When only one argument is given, this argument is taken as the real part, and a value of zero is taken as the imaginary part. The intrinsic function ABS can accept a real or complex number as an argument. If the argument is real, the function returns the absolute value of the argument. If the argument is complex, the function returns the modulus of the argument. COMPLEX Y DATA X,Y /-8.,(3.,4.)/ C= ABS(X) D= ABS(Y) In this example, C = |-8.| = 8., and D = (3 2 + 4 2) 1/2 = 5. The intrinsic function CONJG accepts a complex argument and returns its complex conjugate. The intrinsic function REAL accepts a complex argument and returns its real part. The intrinsic function AIMAG accepts a complex argument and returns its imaginary part. The following example program illustrates the use of complex intrinsic functions. This example declares three complex variables X, Y, and Z, and initializes two real values A and B with a DATA statement (A= 3., B = 4.). Then it uses the intrinsic function CMPLX to define X and Y, ABS to calculate the modules of X and Y, CONJG to get the conjugate of X, and REAL and AIMAG to separate X into its real and imaginary components. Example Program: Use Of Complex Intrinsic Functions
The results (under unformatted write) are shown below. (3.0000,4.0000) (6.0000,8.0000) 5.0000 10.0000 (3.0000,-4.0000) 3.0000 4.0000 Operations with Complex Numbers Operations with complex numbers include addition, subtraction, multiplication, division, and exponentiation. In the addition of complex numbers, the real part of the sum is the sum of the real parts, and the imaginary part of the sum is the sum of the imaginary parts. Therefore: (a + bi) + (c + di) = (a + c) + (b + d) i Subtraction of complex numbers operates in the same way as addition: (a + bi) - (c + di) = (a - c) + (b - d) i Multiplication of complex numbers follows from the fact that i 2 = -1. Therefore: (a + bi) (c + di) = (ac - bd) + (ad + bc) i Division of complex numbers is accomplished by multiplying both numerator and denominator by the conjugate of the denominator. This leads to: (a + bi) / (c + di) = [(ac + bd) - (ad - bc) i ] / (c2 + d2) Exponentiation of complex numbers to an integer power is accomplished in the same way as for real num bers. For instance: (a + bi)3 = (a + bi) (a + bi) (a + bi) The following example program illustrates operations with complex numbers. This example defines three complex variables X, Y, and Z, and initializes the variables X and Y with a DATA statement. It proceeds to add, subtract, multiply, and divide these variables, each time writing out the result Z. Then it takes X to the power 2 and writes the result Z, and Y to the power 3, and writes the result Z. Example Program: Operations with Complex Variables
The results (under unformatted write) are shown below. Z= (4.000000,6.000000) Z= (2.000000,2.000000) Z= (-5.000000,10.00000) Z= (2.200000,-0.4000000) Z= (-7.000000,24.00000) Z= (-117.0000,44.00000)
10.3 CHARACTER MANIPULATION
Character Substrings A character substring is a segment of a character variable or character array element. It has the form: ABC(ileft:iright) where ABC is a character variable or array, and the integer arguments ileft and iright specify the leftmost and rightmost position of the substring of ABC, respectively. The following rules apply to character substrings:
Example 1 CHARACTER*26 ALPHABET DATA ALPHABET 1/'ABCDEFGHIJKLMNOPQRSTUVWXYZ'/ WRITE(6,*) ALPHABET(9:14) This example declares a character variable of 26 characters named ALPHABET, and uses a DATA statement to assign it a string consisting of all 26 letters of the alphabet, Then, it writes in free format a substring consisting of the characters 9 to 14, which is the substring IJKLMN. Example 2 PARAMETER (NE=8,NC=10) CHARACTER*(NC) NAME(NE) DATA (NAME(J),J=1,4)/ 1'SMITH, JOE','PRICE, BOB', 2'LYONS, PAT','JONES, KIM'/ DO 10 J=1,4 WRITE(6,100) NAME(J)(:5) 10 END DO 100 FORMAT(1X,A) This example declares a character array NAME of NE= 8 elements and NC= 10 characters per element, specified via the PARAMETER statement. Four elements of NAME are assigned using a DATA statement. The array of substrings containing characters 1 through 5 (the last names) are written following format 100. Since the left integer has been omitted, a value of 1 is assumed. Character Intrinsic Functions The following character intrinsic functions are valid:
The character intrinsic function LEN(C) returns the length of its character variable argument C, as in the following example. CHARACTER*15 NAME,ADDRESS*20 J= LEN(NAME) K= LEN(ADDRESS) In this example, J = 15 (the length of character variable NAME), and K = 20 (the length of character variable ADDRESS). The character intrinsic function INDEX(C1,C2) searches for the value of a character substring C2 in the value of a specified character variable C1. Then:
The following example illustrates the use of character intrinsic function INDEX(C1,C2). C234567890 CHARACTER*26 ALPHABET,INTEG*6 DATA ALPHABET /'ABCDEFGHIJKLMNOPQRSTUVWXYZ'/ DATA INTEG /'IJKLMN'/ L= INDEX(ALPHABET,INTEG) In this example, two character variables ALPHABET and INTEG are declared and assigned constant values ABCDEFGHIJKLMNOPQRSTUVWXYZ and IJKLMN. INTEG is seen to be a substring of ALPHABET, starting with character number 9. The intrinsic function INDEX returns the value L = 9. The character intrinsic function ICHAR(C) takes the argument C, a character variable, and returns an integer equivalent in ASCII code. If C is longer than one character, only the first character is considered; the remainder is ignored. Table 10.1 shows ASCII code equivalences. The following example illustrates the use of character intrinsic function ICHAR(C). CHARACTER BLETTER DATA BLETTER /'B'/ IEQUIVB= ICHAR(BLETTER) WRITE(6,*) IEQUIVB This example declares a character variable BLETTER, of length one character. (Note that the declaration statement does not include a length. In this case, the length is assumed to be 1 by default; see Section 3.7). A DATA statement is used to assign a value of B to the character variable BLETTER. According to Table 10.1, the ASCII code equivalent of letter B is 66. Therefore: IEQUIVB = 66.
The character intrinsic function CHAR(I) perform the opposite task as intrinsic function ICHAR(C), that is, it takes the argument I, an integer value, and returns a character equivalent in ASCII code. The use of the CHAR(I) function is illustrated by the following example: CHARACTER BLETTER BLETTER= CHAR(66) WRITE(6,*) BLETTER According to Table 10.1, the value of character variable BLETTER is B. Lexical Comparison Intrinsic Functions Fortran provides the lexical comparison intrinsic functions listed in Table 10.2. These functions take the form: func(c1,c2) where func is any of the functions listed in Table 10.2, and c1 and c2 are character constants, variables, or expressions. The lexical comparison functions are used for al phabetic sorting of character arrays, as shown below. CHARACTER*5 NAME(6),TEMP IF(LGE(NAME(J),NAME(J+1))) THEN TEMP= NAME(J+1) NAME(J+1)= NAME(J) NAME(J)= TEMP ENDIF This example compares two consecutive names in a list, NAME(J) and NAME(J+1). If NAME(J) is greater than or equal to NAME(J+1) in alphabetic order (B is greater than A), they are sorted by accomplishing the following steps:
Function Meaning
Equivalence LLT(X,Y) Lexical function less than (X.LT.Y) LLE(X,Y) Lexical function less than or equal to (X.LE.Y) LGT(X,Y) Lexical function greater than (X.GT.Y) LGE(X,Y) Lexical function greater than or equal to (X.GE.Y)
Example Program: Lexical Comparison Functions
This program sorts in alphabetical order a list of six last names. The output of this program is the sorted list: FIELD JONES LYONS MARKS PRICE SMITH Note the following features of this program:
PROBLEMS
|
Documents in Portable Document Format (PDF) require Adobe Acrobat Reader 5.0 or higher to view; download Adobe Acrobat Reader. |
FORTRAN FOR SCIENTISTS AND ENGINEERS VICTOR M. PONCE • ONLINE EDITION • | |||||||
Copyright © 2014 • Victor M. Ponce • All rights reserved. |