Introduction to Fortran 90/95 by Stephen J. Chapman
Grading system:1. Presence: 30%2. Midterm: 30%3. Final: 40%
Office hours: (PH224)1. Mon. 10:10~12:002. Tues. 11:10~12:00 14:40~15:303. Fri. 10:10~12:00
Midterm
90 |99
80 |89
70 |79
60 |69
50 |59
40 |49
30 |39
20 |29
10 |19
0 | 9
1 1 1 5 3 15 33 27
Tot: 86 students
Prob. 1(a)
4 + 1 = 5 4 + 2 = 6 2 + 1 = 3 2 + 2 = 4 0 + 1 = 1 0 + 2 = 2-2 + 1 = -1-2 + 2 = 0-4 + 1 = -3-4 + 2 = -2
Prob. 1(b)
n = 2n = 4n = 8n = 10n = 4
Prob. 1(c)
□□□F□□15□□120.0□test
PROGRAM gaveIMPLICIT NONECHARACTER (len = 20) :: filenameINTEGER :: nvals = 0INTEGER :: ierror1, ierror2REAL :: value, x_ave=1.0
WRITE(*,*) 'Please enter input file name:'READ (*,*) filenameOPEN (UNIT = 3, FILE = filename, STATUS = 'OLD', & ACTION = 'READ', IOSTAT = ierror1)
openif: IF(ierror1 ==0) THEN readloop: DO READ(3,*, IOSTAT = ierror2) value IF (ierror2 /= 0) EXIT nvals = nvals + 1 x_ave=x_ave*value WRITE(*, 1010) nvals, value 1010 FORMAT ('Line ', I6, ': value=', F10.4) END DO readloop
Prob. 2
readif: IF (ierror2 > 0) THEN WRITE(*, 1020) nvals + 1 1020 FORMAT ('Error reading line', I6) ELSE x_ave=x_ave**(1./nvals) WRITE(*, 1030) nvals, x_ave 1030 FORMAT ('End of file. There are ', & I6, ' values in the file.', //'x_ave =' , F7.3) END IF readifELSE openif WRITE(*, 1040) ierror1 1040 FORMAT ('Error opening file: IOSTAT=', I6)END IF openifCLOSE(3)END PROGRAM
Test: GAVE.TXT: 1. 2. 4.
outputx_ave = 2.000
Ch. 1 Introduction To Computers And
The Fortran Language Sec. 1.1 The Computer
Fig 1-1
Main Memory
Secondary Memory
C P U
(Central processing unit)
Input devices
Output devices
Sec 1.2 Data Representation in a Computer
bit : Each switch represents one binary digit.
ON 1
OFF 0
byte : a group of 8 bits
e.g.,
825 MB hard disk. ( 1MB = 106 byte)
Sec 1.2.1 The Binary Number System
The base 10 number system:
1 2 3 10 = 1 x 102 + 2 x 101 + 3 x 100 = 123.
102 101 100
The base 2 number system:
1 0 1 2 = 1 x 22 + 0 x 21 + 1 x 20 = 5
1 1 1 2 = 1 x 22 + 1 x 21 + 1 x 20 = 7
22 21 20
3 bits can represent 8 possible values :
0 ~ 7 (or 0002 ~ 1112 )
In general, n bits 2n possible values.
e.g.,
8 bits ( = 1 byte) 28 = 256. (-128 ~ +127)
16 bits ( = 2 byte) 216 = 65,536. (-32,768 ~ +32,767)
Sec 1.2.2 Types of Data Stored in Memory• Character data : (western language, < 256, use 1 byte)
A ~ Z (26)
a ~ z (26)
0 ~ 9 (10)
Miscellaneous symbols: ( ) { } ! …
Special letters or symbols: à ë …
Coding systems: (see App. A, 8-bit codes) • ASCII (American Standard Code for Information Interchange)• EBCDIC (Extended Binary Coded Decimal Interchange Code)
*The unicode coding system uses 2 bytes for each character. (for any language)
• Integer data: (negative, zero, positive) For an n-bit integer, Smallest Integer value = - 2n-1
Largest Integer value = 2n-1 - 1 e.g., a 4-byte (= 32-bit) integer, the smallest = -2,147,483,648 ( = - 232-1) the largest = 2,147,483,647 ( = 232-1-1)
*Overflow condition: An integer > the largest or < the smallest.
• Real data: (or floating-point data) The base 10 system: 299,800,000 = 2.998 x 108 (scientific notation)
mantissa exponent
The base 2 system: e.g., a 4-byte real number = 24-bit mantissa + 8-bit exponent
value = mantissa x 2exponent
Precision: The number of significant digits that can be preserved in a number. e.g., 24-bit mantissa ± 223 (~ seven significant digits)
Range: The diff. between the largest and the smallest numbers. e.g., 8-bit exponent 2-128 ~ 2127 (range ~ 10-38 to 1038)
Sec 1.3 Computer Languages• Machine language: The actual language that a computer recognizes
and executes.
• High-level languages: Basic, C, Fortran, …
*The History of the Fortran Language
Fortran = Formula translation
Fortran 66 Fortran 77 Fortran 90 Fortran 95
(1966) (1977) (1991) (1997)
Sec. 2.3 The Structure of a Fortran Statement
A Fortran program = a series of statements
• Executable statements: e.g., additions, subtractions, …• Non-executable statements: providing information.
Free-source form: Fortran statements may be entered anywhere on a line, up to 132 characters long.
e.g., 100 output = input1 + input2 ! Sum the inputs or 100 output = input1 & ! Sum the inputs + input2
Sec. 2.4 The Structure of a Fortran Program
Fig 2-1 (A simple Fortran program)
PROGRAM my_first_program
! Purpose: …
! Declare the variables
INTEGER :: i, j, k !All variable are integers
! Get the variables WRITE (*,*) " Enter the numbers to multiply:" READ (*,*) i, j k = i * j ! Write out the result WRITE (*,*) 'Result = ', k STOP END PROGRAM
Declarationsection
Executionsection
Terminationsection
Sec. 2.4.4 Program Style
Text book : • Capitalizing Fortran keywords ( e.g., READ, WRITE)• Using lowercase for variables, parameters
Sec. 2.4.5 Compiling, Linking, and Executing the Fortran Program
Fig 2-2
Fortran program
Object file
Executable program
(Compile) (Link)
Sec. 2.5 Constants and Variables
Valid variable names: time distance z123456789 I_want_to_go_home(up to 31 chracters, and the 1st character in a name must always be alphabetic)
Invalid variable names: this_is _a_very_long_variable_name 3_days A$ ($ is an illegal character) my-help (“-” is an illegal character)
Five intrinsic types of Fortran constants and variables:1. INTEGER2. REAL3. COMPLEX4. LOGICAL5. CHARACTER
(numeric)
(logical)(character)
Sec. 2.5.1 Integer Constant and Variables
Integer constants: (no decimal point) e.g., 0 -999 +17 1,000,000 (X) -100. (X)
Integer variables: 16-bit integers 32-bit integers(diff. kinds of integers, Ch. 7)
Sec. 2.5.2 Real Constants and Variables Real constants: (with a decimal point) e.g., 10. -999.9 1.0E-3 (= 1.0 x 10-3 or 0.001) 123.45E20 0.12E+1 1,000,000. (X) 111E3 (X) -12.0E1.5 (X)
Real variables: 32-bit real numbers 64-bit real numbers(diff. kinds of real numbers, Ch. 7)
Sec. 2.5.3 Character Constants and Variables Character constants: [enclosed in single (‘) or double (“) quotes)] e.g., ‘This is a test!’ “This is a test!” ‘ ‘ (a single blank) ‘{^}’ ‘3.141593’ (not a number) This is a test! (X) ‘This is a test!” (X)
A character variable contains a value of the character data type.
Sec. 2.5.4 Logical Constants and Variables Character constants: e.g., .TRUE. .FALSE.
TRUE (X) .FALSE (X)
A logical variable contains a value of the logical data type.
Sec. 2.5.5 Default and Explicit Variable Typing Default typing: Any variable names beginning with the letters I, J, K, L, M, or N are assumed to be of type INTEGER. e.g., incr (integer data type) big (real data type)
Explicit typing: The type of a variable is explicitly defined in the declaration section. e.g., PROGRAM example INTEGER :: day, month, year REAL :: second LOGICAL :: test1, test2 CHARACTER :: initial
(Executable statements)
*No default names for the character data type!
Sec. 2.5.6 Keeping Constants Consistent in a Program Using the PARAMETER attribute : type, PARAMETER :: name=value e.g., REAL, PARAMETER :: pi=3.14159 CHARACTER, PARAMETER :: error=‘unknown’
Sec. 2.6 Assignment Statements and Arithmetic Calculations Assignment statement: variable_name = expression e.g., I = I + 1 ( I + 1 I )
Arithmetic operators:• binary operators: a + b (a + b, addition) a – b (a – b, subtraction) a * b (a x b, multiplication) a / b (a/b, division) a ** b (ab, exponentiation)• unary operators: + a - b
Rules:
1. No two operators may occur side by side. e.g., a*-b (X) a*(-b) a**-2 (X) a**(-2)
2. Implied multiplication is illegal. e.g., x (y + z) (X) x*(y + z)
3. Parentheses may be used to group terms whenever desired e.g.,
2**((8+2) / 5)
Sec. 2.6.1 Integer Arithmetic e.g., 3/4 = 0, 6/4 = 1 7/4 = 1, 9/4 = 2
Sec. 2.6.2 Real Arithmetic (or floating-point arithmetic) e.g., 3./4. = 0.75, 6./4. = 1.50 7./4. = 1.75, 9./4. = 2.25
Sec. 2.6.3 Hierarchy (order) of Operators e.g., x = 0.5 * a * t **2 is equal to x = 0.5 * a * (t **2) ? or x = (0.5 * a * t ) **2 ?
Order: 1. Parentheses, from inward to outward.2. Exponentials, from right to left.3. Multiplications and divisions, from left to right.4. Additions and subtractions, from left to right.
Example 2-1 a = 3. b = 2. c=5. d=4. e = 10. f = 2. g= 3.(1) output = a * b + c * d + e / f **g(2) output = a * (b + c) * d + (e / f) **g(3) output = a * (b + c) * (d + e) / f **g
Sol. (1) output = 3. * 2. + 5. * 4. + 10. / 2. ** 3. = 6. + 20. + 1.25 = 27.25 (2) output = 3. * (2. + 5.) * 4. + (10. / 2.) ** 3. = 84. + 125. = 209. (3) output = 3. * (2. + 5.) * (4. + 10.) / 2. ** 3. = 3. * 7. * 14. / 8. = 294. / 8. = 36.75
Example 2-2 a = 3. b = 2. c=3. (1) output = a ** (b ** c)(2) output = (a ** b) ** c(3) output = a ** b ** c
Sol. (1) output = 3. ** (2. ** 3.) = 3. ** 8. = 6561. (2) output = (3. ** 2.) ** 3. = 9. ** 3. = 729. (3) output = 3. ** 2. ** 3. = 3. ** 8. = 6561.
Sec. 2.6.4 Mixed-Mode Arithmetic In the case of an operation between a real number and an integer,the integer is converted by the computer into a real number. e.g., 3. / 2 = 1.5 1 + 1/4 = 1 1. + 1/4 = 1. 1 + 1./4 = 1.25
Automatic type conversion:
e.g., nres = 1.25 + 9/4 ave = (5 + 2) / 2 = 1.25 + 2 = 7/2 = 3.25 = 3. = 3
(a integer variable) (a real variable)
Logarithm
• Base 10: If 10x = N, then x = ? log N = x e.g., N = 100 log 100 = log (102) = 2
N = 3 log 3 = 0.47712…
• Base e (=2.71828…): (Natural logarithm)
If ex = N, then x = ? ln N = x e.g., N = e2 ln (e2) = 2
N = 3 ln 3 = 1.09861…
* If N < 0 ( log N ) or ( ln N ) is undefined !
Sec. 2.6.5 Mixed-Mode Arithmetic and Exponentiation
If result and y are real, and n is an integer,
result = y ** n = y * y * y…*y (real arithmetic, not mixed-mode)
But if result, y and x are real,
result = y ** x = ?
use yx = e x ln y ( e ∵ x ln y = e ln (yx) = yx )
e.g., (4.0) ** 1.5 = 8.
(8.0)**(1./3)=2.
(-2.0) ** 2 = 4. [ (-2.0) * (-2.0) = 4.]∵
(-2.0) ** 2.0 [X, ln (-2.0) is undefined!]∵
Sec. 2.7 Assignment Statements and Logical Calculations Assignment statements: logical variable name = logical expression
Logical operators: • relational operators• combinational operators
Sec. 2.7.1 Relational Operators
a1 op a2
a1, a2: arithmetic expressions, variables, constants, or character strings.op: the relational logical operators. (see Table 2-3)
Table 2-3
operation meaning
= = equal to / = not equal to > greater than > = greater than or equal to < less than < = less than or equal toe.g., operation result 3 < 4 .TRUE. 3 < = 4 .TRUE. 3 = = 4 .FALSE. ‘A’ < ‘B’ .TRUE. (in ASCII, A 65, B 66, p.493) 7+3 < 2+11 .TRUE.
Sec. 2.7.2 Combinational Logic Operators
l1 .op. l2 and .NOT. l1 (.NOT. is a unary operator)
l1, l2: logical expressions, variables, or constants.op: the binary operators. (see Table 2-4)
Table 2-4
operation meaning
.AND. logical AND .OR. logical OR .EQV. logical equivalence .NEQV. logical non-equivalence .NOT. logical NOT
The order of operations:
1. Arithmetic operators.
2. All relational operators, from left to right.
3. All .NOT. operators.
4. All .AND. operators, from left to right.
5. All .OR. operators, from left to right.
6. All .EQV. And .NEQV. operators, from left to right.
Example 2-3
L1 = .TRUE., L2 = .TRUE., L3 = .FALSE. (a) .NOT. L1 .FALSE.
(b) L1 .OR. L3 .TRUE.
(c) L1 .AND. L3 .FALSE.
(d) L2 .NEQV. L3 .TRUE.
(e) L1 .AND. L2 .OR. L3 .TRUE.
(f) L1 .OR. L2 .AND. L3 .TRUE.
(g) .NOT. (L1 .EQV. L2) .FALSE.
Sec. 2.7.3 The Significance of Logical Variables and Expressions
Most of the major branching and looping structures of Fortran are controlled by logical values.
Sec. 2.8 Assignment Statements and Character Variables
character variables name = character expression
Character operators:1. substring specifications2. concatenation
Sec. 2.8.1 Substring SpecificationsE.g., str1 = ‘123456’ str1(2:4) contains the string ‘234’.
Example 2-4 PROGRAM substring CHARACTER (len=8) :: a,b,c a = ‘ABCDEFGHIJ’ b = ‘12345678’ c = a(5:7) b(7:8) = a(2:6) WRITE(*,*) 'a=', a WRITE(*,*) 'b=', b WRITE(*,*) 'c=', c END PROGRAM
a = ? b = ? c = ? (Try it out!)
Solu: a = ‘ABCDEFGH’ ( len = 8)∵
∵ b(7:8) = a(2:6) = ‘BC’
b = ‘123456BC’
c = a(5:7) = ‘EFG’ = ‘EFG□□□□□‘ ( len = 8)∵
(Cont.)
Sec. 2.8.2 The Concatenation Operator
E.g., PROGRAM concate CHARACTER (len=10) :: a CHARACTER (len=8) :: b,c a = ‘ABCDEFGHIJ’ b = ‘12345678’ c = a(1:3) // b(4:5) // a(6:8) WRITE(*,*)’c=‘,c END PROGRAM
c = ? (Try it out: c =‘ABC45FGH’)
Sec. 2.8.3 Relational Operators with Character Data
E.g., ‘123’ = = ‘123’ (true)
‘123’ = = ‘1234’ (false)
‘A’ < ‘B’ (true, ASCII, A 65, B 66)∵
‘a’ < ‘A’ (false, a 97)∵
‘AAAAAB’ > ‘AAAAAA’ (true)
‘AB’ > ‘AAAA’ (true)
‘AAAAA’ > ‘AAAA’ (true)
Sec. 2.9 Intrinsic Functions• Intrinsic functions are the most common functions built directly into the Fortran language. ( see Table 2-6 and App. B)• External functions are supplied by the user. (see Ch. 6)
e.g., y = sin(3.141593) INT(2.9995) = 2 (truncates the real number) y = sin(x)
y = sin(pi*x) NINT(2.9995) = 3 (rounds the real number) y = sin(SQRT(x))
Generic functions: (can use more than one type of input data) e.g., If x is a real number, ABS(x) is real. If x is an integer, ABS(x) is integer.
Specific functions: (can use only one specific type of input data) e.g., IABS(i)
(integer only)
*See Appendix B for a complete list of all intrinsic functions.
Sec. 2.10 List-directed (or free-format) Input and Output Statements
• The list-directed input statement: READ (*,*) input_list
I/O unit format
• The list-directed output statement: WRITE (*,*) output_list I/O unit format
e.g., PROGRAM input_example INTEGER :: i, j REAL :: a CHARACTER (len=12) :: chars READ(*,*) i, j, a, chars WRITE(*,*) i, j, a, chars END PROGRAM
Input: 1, 2, 3., ‘This one.’ (or 1 2 3. ‘This one.’)
Output: 1 2 3.00000 This one.
(Try it out!)
Sec. 2.11 Initialization of Variables
E.g., PROGRAM init INTEGER :: i WRITE(*,*) I END PROGRAM
Output: i = ??? (uninitialized variable)
Run-time error! (depends on machines)
(Try it out!)
Three ways to initialize variables:
1. Assignment statements: e.g., PROGRAM init_1 INTEGER :: i i = 1 WRITE(*,*) i END PROGRAM
2. READ statements: e.g., PROGRAM init_2 INTEGER :: i READ(*,*) i WRITE(*,*) i END PROGRAM
3. Type declaration Statements: type :: var1 = value1, [var2 = value2, …]
e.g., REAL :: time = 0.0, distance = 5128. INTEGER :: loop = 10 LOGICAL :: done = .FALSE. CARACTER (len=12) :: string = ‘characters’
or
PROGRAM init_3 INTEGER :: i = 1 WRITE(*,*) i END PROGRAM
Sec. 2.12 The IMPLICIT NONE Statement
When the IMPLICIT NONE statement is included in a program, any variable that does not appear in an explicit type declaration statement is considered an error. e.g., PROGRAM test_1 REAL :: time time = 10.0 WRITE(*,*) ‘Time=‘, tmie END PROGRAM
Output:
Run-time error! (depends on machines)
+ IMPLICIT NONE,
PROGRAM test_1 IMPLICIT NONE REAL :: time time = 10.0 WRITE(*,*) ‘Time=‘, tmie END PROGRAM
Output:
Compile-time error! (depends on machines)
Sec. 2.13 Program Examples
Example 2-5 (Temperature conversion)
T (0F) = (9/5) T(0C) + 32
Fig. 2-6 PROGRAM temp IMPLICIT NONE REAL :: temp_c, temp_f WRITE(*,*) ’Enter T in degrees C:’ READ(*,*) temp_c temp_f = (9./5.) * temp_c + 32. WRITE(*,*) temp_c,’ degrees C =‘, temp_f, & ‘degrees F’ END PROGRAM
(Try it out!)
Example (extra)
Write a program for converting a 4 bits integer into a base 10 number, e.g.,
1 0 1 1 = 1 x 23 + 0 x 22 + 1 x 21 + 1 x 20 = 11
Ch. 3 Control Structures and Program Design
Ch. 2: Sequential programs (simple and fixed order)
Here: Complex programs (using two control statements)
(1) branches
(2) loops
Sec. 3.1 Introduction to Top-down Design Techniques
Start
State the problem
Design thealgorithm
Convert algorithm into Fortran statements
Test the program
Finished !
Fig. 3-1 (a formal program design process)
Sec. 3.2 Pseudocode and Flowcharts
(1) Pseudocode : a mixture of Fortran and English
(2) Flowcharts : graphical symbolsl
e.g.,
(1) The pseudocode for Example 2-5: Prompt user to enter temp. in degree Farenheit Read temp. in degree Farenheit temp_k in Kelvins (5./9.)*(temp_f-32.)+273.15 Write temp. in Kelvins
(2) The flowcharts for Example 2-5:
Start
Tell user toenter temp_f
Get temp_f
Calculate temp_k Write temp_k Stop
(an oval for start or stop)
(a parallelogram for I/O)
(a rectangle for computation)
Sec. 3.3 Control Constructs: Branches
• IF Statement
• SELECT CASE
Branches are Fortran statements that permit us to select and execute specific sections of code (called blocks) while skipping other sections of code.
Sec. 3.3.1 The Block IF Construct
This construct specifies that a block of code will be executed if and only if a certain logical expression is true.
IF (logical_expr) THEN Statement 1 Statement 2 . . .END IF
a block
Fig . 3-5 (Flowchart for a simple block IF construct)
logical_expr
Statement 1Statement 2 . .
.TRUE.
.FALSE.
(a diamond for choice)
Example:
ax2 + bx + c = 0,
x = -b ± ( b2 – 4ac )1/2
2a
If b2 – 4ac = 0
b2 – 4ac > 0
b2 – 4ac < 0
two distinct real roots
two complex roots
a single repeated root
Fig . 3-6 (Flowchart)
.TRUE.
.FALSE.
Problem: Tell the user if the eq. has complex roots.
b2 – 4ac < 0
WRITE ‘two complex roots’
Fortran: IF ( (b**2 – 4.*a*c) < 0. ) THEN WRITE(*,*) ‘Two complex roots!’ END IF
Sec. 3.3.2 The ELSE and ELSE IF Clauses
For many different options to consider,
IF + ELSE IF (one or more) + an ELSE
IF (logical_expr_1) THEN Statement 1 Statement 2 . .ELSE IF (logical_expr_2) THEN Statement 1 Statement 2 . .ELSE Statement 1 Statement 2 . .END IF
Block 1
Block 2
Block 3
Fig . 3-7 (flowchart)
.TRUE.
.FALSE.logical_expr_1
Block 1
logical_expr_2
Block 2
.TRUE.
.FALSE.
Block 3
Fig . 3-8 (flowchart)
.TRUE.
.FALSE.b2 - 4ac < 0
WRITE ‘two complex roots’
.TRUE.
.FALSE.
Example: Tell the user whether the eq. has two complex roots, two identical real roots, or two distinct real roots.
b2 - 4ac = 0
WRITE ‘two identical real roots’
WRITE ‘two distinct real roots’
Fortran: IF ( (b**2 – 4.*a*c) < 0. ) THEN WRITE(*,*) ‘two complex roots’ ELSE IF ( (b**2 – 4.*a*c) == 0. ) THEN WRITE(*,*) ‘two identical real roots’ ELSE WRITE(*,*) ‘two distinct real roots’ END IF
Write a complete Fortran program for a quadraticequation ax2 + bx + c = 0.
Input: a, b, c (e.g., 1., 5., 6. or 1., 4., 4. or 1., 2., 5.)
Output: ‘distinct real’ or ‘identical real’ or ‘complex roots’
(Try it out!)
PROGRAM abcIMPLICIT NONEREAL :: a, b, c
WRITE(*,*)'Enter the coeffs. a, b, and c:‘READ(*,*) a, b, c
IF ( (b**2-4.*a*c) < 0. ) THEN WRITE(*,*) 'two complex root‘ELSE IF ( (b**2-4.*a*c) == 0. ) THEN WRITE(*,*) 'two identical real roots‘ELSE WRITE(*,*) 'two distinct real roots‘END IF
END PROGRAM
Sec. 3.3.3 Examples Using Block IF Constructs
Example 3-1 The Quadratic Equation: (ax2 + bx + c =0) Write a program to solve for the roots of a quadratic equation, regardless of type.
Input: a, b, c
Output: rootsrealrepeated realcomplex
PROGRAM rootIMPLICIT NONEREAL :: a, b, c, d, re, im, x1, x2
WRITE(*,*)'Enter the coeffs. a, b, and c:‘READ(*,*) a, b, cd = b**2 – 4.*a*cIF ( d < 0. ) THEN WRITE(*,*) 'two complex root:‘ re = (-b)/(2.*a) im = sqrt(abs(d))/(2.*a) WRITE(*,*) ’x1=‘, re, ‘+ i’, im WRITE(*,*) ’x2=‘, re, ‘- i’, im ELSE IF ( d == 0. ) THEN WRITE(*,*) 'two identical real roots:‘ x1 = (-b) / (2.*a) WRITE(*,*) ’x1=x2=‘, x1
ELSE WRITE(*,*) 'two distinct real roots:‘ x1 = (-b + sqrt(d)) / (2.*a) x2 = (-b – sqrt(d)) / (2.*a) WRITE(*,*) ’x1=‘, x1 WRITE(*,*) ‘x2=‘, x2END IFEND PROGRAM
Test: (Try it out!)
x2 + 5x + 6 = 0, x1,2 = -2, -3
x2 + 4x + 4 = 0, x1,2 = -2
x2 + 2x + 5 = 0, x1,2 = -1 ± i 2
Example 3-2 Evaluation a Function of Two Variables:
f(x,y) =
x + y, x 0 ≧ and y 0≧x + y2, x 0 ≧ and y < 0x2 + y, x < 0 and y 0≧x2 + y2, x < 0 and y < 0
Input: x, y
Output: f
Fig . 3-11 (flowchart)
.TRUE.
.FALSE.x ≧ 0 &y 0≧
f = x + y
x 0 ≧ &y < 0
f = x2 + y
.TRUE.
.FALSE.
f = x2 + y2f = x + y2
x < 0 &y 0≧
.TRUE.
.FALSE.
WRITE f
Stop
Start
READ x, y
PROGRAM funxyIMPLICIT NONEREAL :: x, y, f
WRITE(*,*)'Enter x and y:‘READ(*,*) x, yIF ((x >= 0.) .AND. (y >= 0. )) THEN f = x + yELSE IF ((x >= 0.) .AND. (y < 0. )) THEN f = x + y**2ELSE IF ((x < 0.) .AND. (y >= 0. )) THEN f = x**2 + yELSE f = x**2 + y**2END IFWRITE(*,*) ‘f = ‘, fEND PROGRAM
Test: (Try it out!)
x y f
2. 3. 5. 2. -3. 11.-2. 3. 7.-2. -3. 13.
[name:] IF (logical_expr_1) THEN Statement 1 Statement 2 . .ELSE IF (logical_expr_2) THEN [name] Statement 1 Statement 2 . .ELSE [name] Statement 1 Statement 2 . .END IF [name]
Block 1
Block 2
Block 3
Sec. 3.3.4 Named Block IF Constructs
optional
optional
Sec. 3.3.5 Notes Concerning the Use of Logical IF Constructs
Nested IF Constructs:
outer: IF ( x > 0. ) THEN . . inner: IF ( y < 0. ) THEN . . END IF inner . .END IF outer
Example 3-3 Assigning Letter Grades:
95 < GRADE A86 < GRADE < 95 B76 < GRADE < 86 C66 < GRADE < 76 D 0 < GRADE < 66 F
Input: grade
Output: ‘The grade is A.’ or ‘The grade is B.’ or ‘The grade is C.’ or ‘The grade is D.’ or ‘The grade is F.’
Method (a): IF + ELSE IF
IF (grade > 95.) THEN WRITE(*,*) ‘The grade is A.’ELSE IF (grade > 86.) THEN WRITE(*,*) ‘The grade is B.’ELSE IF (grade > 76.) THEN WRITE(*,*) ‘The grade is C.’ELSE IF (grade > 66.) THEN WRITE(*,*) ‘The grade is D.’ELSE WRITE(*,*) ‘The grade is F.’END IF
Method (b): nested IF
if1: IF (grade > 95.) THEN WRITE(*,*) ‘The grade is A.’ELSE if2: IF (grade > 86.) THEN WRITE(*,*) ‘The grade is B.’ ELSE if3: IF (grade > 76.) THEN WRITE(*,*) ‘The grade is C.’ ELSE if4: IF (grade > 66.) THEN WRITE(*,*) ‘The grade is D.’ ELSE WRITE(*,*) ‘The grade is F.’ END IF if4 END IF if3 END IF if2END IF if1
Sec. 3.3.6 The Logical IF Statement
IF (logical_expr) Statement
e.g., IF ( (x >= 0.) .AND. (y >= 0.) ) f = x + y
[name:] SELECT CASE (case_expr)CASE (case_selector_1) [name] Statement 1 Statement 2 . . .CASE (case_selector_2) [name] Statement 1 Statement 2 . . .CASE DEFAULT [name] Statement 1 Statement 2 . . .END SELECT [name]
Block 1
Block 2
Block 3
Sec. 3.3.7 The CASE Construct
optional
optional
optional
case_expr: an integer, character, or logical expression.
The case_selector can take one of four forms:
1. case_value Execute block if case_value == case_expr2. low_value: Execute block if low_value <= case_expr3. : high_value: Execute block if case_expr <= high_value4. low value: high_value Execute block if low_value <= case_expr <= high_value
Fig . 3-13 (flowchart for a CASE construct)
In range
Not in range
case_sel_1
Block 1
case_sel_2
Block n
In range
NotIn range
Default BlockBlock 2
case_sel_n
In range
Not in range
e.g., (modified)
REAL :: temp_c. . .temp: SELECT CASE (temp_c)CASE (: -1.0) WRITE (*,*) ‘ It’s below freezing today!’CASE (0.0) WRITE (*,*) ‘ It’s exactly at the freezing point!’CASE (1.0:20.0) WRITE (*,*) ‘ It’s cool today!’CASE (21.0:33.0) WRITE (*,*) ‘ It’s warm today!’CASE (34.0:) WRITE (*,*) ‘ It’s hot today!’END SELECT temp
PROGRAM selectcIMPLICIT NONEINTEGER :: temp_cWRITE(*,*) “Enter today’s temp. in degree C:”READ(*,*) temp_ctemp: SELECT CASE (temp_c)CASE (: -1) WRITE (*,*) “It’s below freezing today!”CASE (0) WRITE (*,*) “It’s exactly at the freezing point!”CASE (1:20) WRITE (*,*) “It’s cool today!”CASE (21:33) WRITE (*,*) “It’s warm today!”CASE (34:) WRITE (*,*) “It’s hot today!”END SELECT tempEND PROGRAM
Problem: Determine whether an integer between 1 and 10 is even or odd. (Try it out!)
PROGRAM selectvINTEGER :: valueWRITE(*,*) 'Enter an inter between 1-10:'READ(*,*) valueSELECT CASE (value) CASE (1,3,5,7,9) WRITE(*,*) 'The value is odd.' CASE (2,4,6,8,10) WRITE(*,*) 'The value is even.' CASE (11:) WRITE(*,*) 'The value is too high' CASE DEFAULT WRITE(*,*) 'The value is negative or zero.'END SELECTEND PROGRAM
Sec. 3.4 Control Constructs: Loops
• while loops• iterative (or counting) loops
Sec. 3.4.1 The While Loop
DO . . . IF (logical_expr) EXIT . . .END DO
a code block
Fig . 3-14 (Flowchart for a while loop)
.TRUE.
.FALSE.
logical_expr
Statement 1 . . .
Statement 1 . . .
Example 3-4 Statiscal Analysis:
Average: x_ave =
Σxii=1
N
N
Standard deviation:
S = N Σxi
2 – (i=1 i=1
N N
Σxi )2
N (N-1)
1/2
Input: x (i.e., xi , i = 1, 2, …, N) 0 ≧
Output: x_ave and S
Fig . 3-15 (Flowchart for Example 3-4)
.TRUE.
.FALSE.
x < 0
READ x
n = n + 1sum_x = sum_x + xsum_x2=sum_x2 + x2
Start
1
1
Calculate x_ave, s
Stop
WRITE x_ave, s, n
Initial values:n = 0sum_x = 0Sum_x2 = 0
Fig . 3-16 PROGRAM stats_1IMPLICIT NONEINTEGER :: n = 0REAL :: x, x_ave, s , sum_x = 0., sum_x2 = 0.
DO WRITE(*,*) ‘Enter the value x:’ READ (*,*) x IF ( x < 0. ) EXIT n = n + 1 sum_x = sum_x + x sum_x2 = sum_x2 + x**2END DOx_ave = sum_x / ns = sqrt (( n*sum_x2 – sum_x**2) / (n*(n-1)))WRITE(*,*) ‘n = ‘ , n, ‘ x_ave = ‘, x_ave, & ‘ s = ‘, sEND PROGRAM
Test:
Input: 3. 4. 5. -1.
Output: n = 3 x_ave = 4.00000 s = 1.00000
Sec. 3.4.2 The Iterative Counting Loop
DO index = istart, iend, incr Statement 1 . . . Statement nEND DO
e.g.,
(1) Do i = 1, 10 Statement 1 . . . Statement nEND DO
( incr = 1 by default)
(2) Do i = 1, 10, 2 Statement 1 . . . Statement nEND DO
( i = 1, 3, 5, 7, 9 )
Fig. 3-18 (Flowchart for a Do loop construct)
index*incr ≦iend * incr
index =istart
incr
Statement 1Statement 2 . . .
.TRUE..FALSE.
Example 3-5 The Factorial Function:
N ! = N × (N-1) × (N-2) … × 3 × 2 × 1, N > 0.0 ! = 1
e.g.,
4 ! = 4 × 3 × 2 × 1 = 24 5 ! = 5 × 4 × 3 × 2 × 1 = 120
Fortran Code: n_factorial = 1DO i = 1, n n_factorial = n_factorial * iEND DO
Problem: Write a complete Fortran program for the factorial function.
Input: n ( n > = 0 )
N ! = N × (N-1) × (N-2) … × 3 × 2 × 1, N > 0.
0 ! = 1
Output: n!
PROGRAM factorialIMPLICIT NONEINTEGER :: i, n, n_fact
WRITE(*,*) ’Enter an integer n ( > = 0 ):’READ(*,*) nn_fact = 1IF ( n > 0 ) THEN DO i = 1, n n_fact = n_fact * i END DOEND IF
WRITE(*,*) n, ‘! = ‘, n_factEND PROGRAM
Fig . 3-20
.TRUE. .FALSE.n < 2
READ n
sum_x = sum_x + xsum_x2 = sum_x2+x2
Start
1
1
Calculate x_ave, s
Stop
WRITE x_ave, s, n
Initial values:sum_x = 0sum_x2 = 0
Example 3-7 Statistical Analysis: (modified)
WRITE‘At least 2 values!’
i=1
i=i+1i n≦ ?
READ x
.FALSE. .TRUE.
Fig . 3-21PROGRAM stats_3IMPLICIT NONEINTEGER :: i, nREAL :: x, x_ave, s , sum_x = 0., sum_x2 = 0.
WRITE(*,*) ‘Enter the number of points n:’READ(*,*) nIF ( n < 2 ) THEN WRITE(*,*) ‘ At least 2 values!’ELSE DO i = 1, n WRITE(*,*) ‘Enter the value x:’ READ (*,*) x sum_x = sum_x + x sum_x2 = sum_x2 + x**2 END DO
x_ave = sum_x / ns = sqrt (( n*sum_x2 – sum_x**2) / (n*(n-1)))WRITE(*,*) ‘n = ‘ , n, ‘ x_ave = ‘, x_ave, & ‘ s = ‘, sEND IFEND PROGRAM
Test:
Input: 3 3. 4. 5.
Output: n = 3 x_ave = 4.00000 s = 1.00000
Sec. 3.4.3 The CYCLE and EXIT Statements
E.g., PROGRAM test_cycleINTEGER :: iDO i = 1, 5 IF ( i == 3 ) CYCLE WRITE(*,*) iEND DOWRITE(*,*) ‘End of loop!’END PROGRAM
Output: 1 2 4 5 End of loop!
PROGRAM test_exitINTEGER :: IDO i = 1, 5 IF ( i == 3 ) EXIT WRITE(*,*) iEND DOWRITE(*,*) ‘End of loop!’END PROGRAM
Output: 1 2 End of loop!
[name:] DO . . . IF (logical_expr) CYCLE [name] . . . IF (logical_expr) EXIT [name] . . . END DO [name]
Sec. 3.4.4 Named Loops
While loop:
optional
[name:] DO index = istart, iend, incr . . . IF (logical_expr) CYCLE [name] . . . END DO [name]
Counting loop:
optional
Sec. 3.4.5 Nesting Loops and Block IF Construct
e.g.,PROGRAM nested_loopsINTEGER :: i, j, productDO i = 1, 3 DO j = 1, 3 product = i * j WRITE(*,*) i, ‘*’, j, ‘=‘, product END DOEND DOEND PROGRAM
Output:
1 * 1 = 11 * 2 = 21 * 3 = 32 * 1 = 22 * 2 = 42 * 3 = 63 * 1 = 33 * 2 = 63 * 3 = 9
PROGRAM test_cycle_1INTEGER :: i, j, productDO i = 1, 3 DO j = 1, 3 IF ( j == 2 ) CYCLE product = i * j WRITE(*,*) i, ‘*’, j, ‘=‘, product END DOEND DOEND PROGRAM
Output: 1 * 1 = 11 * 3 = 32 * 1 = 22 * 3 = 63 * 1 = 33 * 3 = 9
PROGRAM test_cycle_2INTEGER :: i, j, productouter: DO i = 1, 3 inner: DO j = 1, 3 IF ( j == 2 ) CYCLE outer product = i * j WRITE(*,*) i, ‘*’, j, ‘=‘, product END DO innerEND DO outerEND PROGRAM
Output:1 * 1 = 12 * 1 = 23 * 1 = 3
Nesting loops within IF constructs and vice versa:
e.g.,outer: IF ( a < b ) THEN . . . inner: DO i = 1, 3 . . . ELSE . . . END DO innerEND IF outer
illegal!
outer: IF ( a < b ) THEN . . . inner: DO i = 1, 3 . . . END DO inner . . . ELSE . . . END IF outer
legal:
Ch. 4 Basic I/O Concepts
Sec. 4.1 FORMATS and FORMETED WRITE STATEMENTS
READ (*,*) Not always convenient!
WRITE (*,*) Not always pretty!
e.g,. PROGRAM free_formatINTEGER :: i = 21REAL :: result = 3.141593WRITE(*,100) i, result100 FORMAT (‘□The□result□for□iteration□’, & I3, ‘□is□’, F7.3)END PROGRAM
Output: □The□result□for□iteration□□21□is□□□3.142
∵ I3 ∵ F7.3
The following three WRITE statements are equivalent:
• WRITE (*, 100) i, result 100 FORMAT (I6, F10.2)
• CHARACTER ( len=20 ) :: string string = ‘(I6, F10.2)’ WRITE(*,string) i, result
• WRITE(*, ‘(I6,F10.2)’) i, result
Output: □□□□21□□□□□□3.14
I6 F10.2
PROGRAM formatINTEGER :: i = 21REAL :: result = 3.141593CHARACTER ( len=20 ) :: string
WRITE (*, 100) i, result100 FORMAT (I6, F10.2)
string = '(I6, F10.2)'WRITE(*,string) i, result
WRITE(*, '(I6,F10.2)') i, result
END PROGRAM
Output: □□□□21□□□□□□3.14
Sec. 4.2 Output Devices
Line printers, laser printers, and terminals.
Sec. 4.3 Format Descriptors
Table 4-2 (Symbols used with format descriptors)
Symbol meaning
c column number d # of digits to the right of the decimal point m min. # of digit r repeat count w field width
Sec. 4.3.1 Integer Output – The I Descriptor
rIw or rIw.m
e.g., INTEGER :: index = -12, junk = 4, number = -12345 WRITE(*,200) index, index+12, junk, number WRITE(*,210) index, index+12, junk, number WRITE(*,220) index, index+12, junk, number 200 FORMAT ( 2I5, I6, I10) 210 FORMAT (2I5.0, I6, I10.8) 220 FORMAT (2I5.3, I6, I5)
Output: □□-12□□□□0□□□□□4□□□□-12345 □□-12□□□□□□□□□□4□-00012345 □-012□□000□□□□4*****
(Not in scale!)
I5 I5 I6 I10
PROGRAM iformatIMPLICIT NONEINTEGER :: index = -12, junk = 4, number = -12345
WRITE(*,200) index, index+12, junk, numberWRITE(*,210) index, index+12, junk, numberWRITE(*,220) index, index+12, junk, number200 FORMAT ( 2I5, I6, I10)210 FORMAT (2I5.0, I6, I10.8)220FORMAT (2I5.3, I6, I5)
END PROGRAM
Output: -12 0 4 -12345 -12 4 -00012345 -012 000 4*****
(Not in scale!)
Sec. 4.3.2 Real Output – The F Descriptor
rFw.d
e.g., REAL :: a = -12.3, b = .123, c = 123.456 WRITE(*,200) a, b, c WRITE(*,210) a, b, c 200 FORMAT (2F6.3, F8.3) 210 FORMAT (3F10.2)
Output: ******□0.123□123.456 □□□□-12.30□□□□□□0.12□□□□123.46
(Not in scale!)
F6.3 F6.3 F8.3
F10.2 F10.2F10.2
PROGRAM rformatIMPLICIT NONEREAL :: a = -12.3, b = .123, c = 123.456
WRITE(*,200) a, b, cWRITE(*,210) a, b, c200 FORMAT (2F6.3, F8.3)210 FORMAT (3F10.2)
END PROGRAM
Output: ****** 0.123 123.456 -12.30 0.12 123.46
(Not in scale!)
Sec. 4.3.3 Real Output – The E Descriptor
(Expomential notation)Scientific notation: 6.02 × 1023
Exponential notation: 0.602 × 1024(E Descriptor)
0.602 E+24
rFw.d ( w d + ≧ 7 )
e.g., REAL :: a = 1.2346E6, b = 0.001, c = -77.7E10, d = -77.7E10WRITE (*,200) a, b, c, d200 FORMAT (2E14.4, E13.6, E11.6)
□□□□0.1235E+07□□□□0.1000E-02-0.777000E+12***********
E14.4 E11.6E13.6E14.4
Output:
( ‘E+**’ , ‘0.’, and ‘-’)∵
( 11 < 6 + 7)∵
PROGRAM routputIMPLICIT NONEREAL :: a = 1.2346E6, b = 0.001, c = -77.7E10, d = -77.7E10
WRITE (*, 200) a, b, c, d200 FORMAT (2E14.4, E13.6, E11.6)
END PROGRAM
Sec. 4.3.4 True Scientific Notation – The ES Descriptor
rESw.d ( w d + ≧ 7 )
e.g.,
REAL :: a = 1.2346E6, b = 0.001, c = -77.7E10WRITE (*,200) a, b, c200 FORMAT (2ES14.4, ES12.6)
□□□□1.2346E+06□□□□1.0000E-03************
ES14.4 ES12.6 ES14.4
Output:
PROGRAM esformatIMPLICIT NONE
REAL :: a = 1.2346E6, b = 0.001, c = -77.7E10WRITE (*, 200) a, b, c200 FORMAT (2ES14.4, ES12.6)
END PROGRAM
Sec. 4.3.5 Logical Output – The L Descriptor
rLw
e.g.,
LOGICAL :: output = .TRUE., debug = .FALSE.WRITE (*, 200) output, debug200 FORMAT (2L5)
□□□□T□□□□F
L5 L5
Output:
PROGRAM loutputIMPLICIT NONELOGICAL :: output = .TRUE., debug = .FALSE.
WRITE (*, 200) output, debug200 FORMAT (2L5)
END PROGRAM
Sec. 4.3.6 Character Output – The A Descriptor
rAw or rA
e.g.,
CHARACTER (len = 17) :: string = ‘This□is□a□string.’WRITE (*, 10) stringWRITE (*, 11) stringWRITE (*, 12) string10 FORMAT (A)11 FORMAT (A20)12 FORMAT (A6)
Output:
(i.e., the width is the same as the # of characters being displayed.)
17 characters
This□is□a□string.□□□This□is□a□string.This□i
PROGRAM aoutputIMPLICIT NONECHARACTER (len = 17) :: string = 'This is a string.‘
WRITE (*, 10) stringWRITE (*, 11) stringWRITE (*, 12) string10 FORMAT (A)11 FORMAT (A20)12 FORMAT (A6)
END PROGRAM
Sec. 4.3.7 Horizontal Position – The X and T Descriptors
X descriptor: nX
(the # of blanks to insert)
T descriptor:
Tc
(the column # to go to)
e.g,.
CHARACTER (len = 10) :: first_name = ‘James□’CHARACTER :: initial = ‘R’CHARACTER (len = 16) :: last_name = ‘Johnson□’CAHRACTER (len = 9) :: class = ‘COSC□2301’INTEGER :: grade = 92WRITE(*,100) first_name, initial, last_name, grade, class100 FORMAT (A10, 1X, A1, 1X, A10, 4X, I3, T51, A9)
Output:
James□□□□□□R□Johnson□□□□□□□□92 . . . COSC□2301
A10 A10 4X I3 A91X A1 1X
(51th column, T51)∵
orCHARACTER (len = 10) :: first_name = ‘James□’CHARACTER :: initial = ‘R’CHARACTER (len = 16) :: last_name = ‘Johnson□’CHARACTER (len = 9) :: class = ‘COSC□2301’INTEGER :: grade = 92WRITE(*,100) first_name, initial, last_name, class, grade100 FORMAT (A10, T13, A1, T15, A10, T51, A9, T29, I3)
Output:
James□□□□□□□R□Johnson□□□□□□□□92 . . . COSC□2301
A10 A10 I3 A9 A1
(13th column, T13)∵
(15th column, T15)∵ (29th column, T29)∵
(51th column, T51)∵
orCHARACTER (len = 10) :: first_name = ‘James□’CHARACTER :: initial = ‘R’CHARACTER (len = 16) :: last_name = ‘Johnson□’CAHRACTER (len = 9) :: class = ‘COSC□2301’INTEGER :: grade = 92WRITE(*,100) first_name, initial, last_name, class, grade100 FORMAT (A10, T13, A1, T15, A10, T17, A9, T29, I3)
Output:
James□□□□□□□R□JoCOSC□2301□□□□92
A10 A10 I3 A1
(13th column, T13)∵
(15th column, T15)∵
(29th column, T29)∵
(17th column, T17)∵
PROGRAM tformatCHARACTER (len = 10) :: first_name = 'James 'CHARACTER :: initial = 'R'CHARACTER (len = 16) :: last_name = 'Johnson 'CHARACTER (len = 9) :: class ='COSC 2301'INTEGER :: grade = 92
WRITE(*,100) first_name, initial, last_name, grade, classWRITE(*,110) first_name, initial, last_name, class, gradeWRITE(*,120) first_name, initial, last_name, class, grade100 FORMAT (A10, 1X, A1, 1X, A10, 4X, I3, T51, A9) 110 FORMAT (A10, T13, A1, T15, A10, T51, A9, T29, I3) 120 FORMAT (A10, T13, A1, T15, A10, T17, A9, T29, I3)
END PROGRAM
Sec. 4.3.8 Repeating Groups of Format Descriptors
E.g.,
320 FORMAT (1X, I6, I6, F10.2, F10.2, I6, F10.2, F10.2)321 FORMAT (1X, I6, 2(I6, 2F10.2))
320 FORMAT (1X, I6, F10.2, A, F10.2, A, I6, F10.2, A, F10.2, A)321 FORMAT (1X, 2(I6, 2(F10.2, A)))
Sec. 4.3.9 Changing Output Lines – The Slash ( / ) Descriptor e.g.,
WRITE (*, 100) index, time, depth, amplitude, phase100 FORMAT (T20, ‘Results for Test Number ‘, I3, ///, & 1X, ‘Time = ‘, F7.0/, & 1X, ‘Depth = ‘, F7.1, ‘ meters’, / , & 1X, ‘Amplitude = ‘, F8.2/, & 1X, ‘Phase = ‘, F7.1)
Output:
Results for Test Number . . .
Time = . . .Depth = . . . Amplitude = . . .Phase = . . .
(skip 2 lines)
Sec. 4.3.10 How Format Statements Are Used during WRITES
Example 4-1 Generating a Table of Information
Output:
Table of Square Roots, Squares, and Cubes
Number Square Root Square Cube====== ========== ====== ==== 1 1.000000 1 1 2 1.414214 4 8 . . . . . . . . . . . . 9 3.000000 81 729 10 3.162278 100 1000
PROGRAM tableIMPLICIT NONEINTEGER :: i, square, cubeREAL :: square_root
WRITE(*, 100)100 FORMAT(T4, ‘Table of Square Roots, Squares, and Cubes’/ )WRITE(*, 110)110 FORMAT(T4, ‘Number’, T13, ‘Square Root’, T29, ‘Square’, T39, ‘Cube’)WRITE(*, 120)120 FORMAT(T4, ‘======‘, T13, ‘===========‘, T29, & ‘======‘, T39, ‘====‘)DO i = 1, 10 square_root = SQRT(REAL(i)) square = i**2 cube = i**3 WRITE(*, 130) i, square_root, square, cube 130 FORMAT(T4, I4, T13, F10.6, T27, I6, T37, I6)END DOEND PROGRAM
Sec. 4.4 Formatted READ Statements
e.g., READ (*,100) increment100 FORMAT (6X, I6)
(skip the 1st six column)(col. 7~12: an integer)
Sec. 4.4.1 Integer Input – The I Descriptor
rIw
e.g.,READ(*, 100) a, b, c100 FORMAT(3I5)
Input:
□□□15□□15□□15□□
I5 I5 I5a = 15b = 15c = 15
PROGRAM iinputIMPLICIT NONEINTEGER :: a, b, c
READ(*, 100) a, b, c100 FORMAT(3I5)WRITE(*,*) 'a= ', aWRITE(*,*) 'b= ', bWRITE(*,*) 'c= ', c
END PROGRAM
Sec. 4.4.2 Real Input – The F Descriptor
rFw.d
e.g.,
READ (*, ‘(3F10.4)’ ) a, b, c
Input:
1.5□□□□□□□□0.15E+01□□□15.0E-01
F10.4 F10.4 F10.4
a = 1.5b = 1.5c = 1.5
PROGRAM rinputIMPLICIT NONEREAL :: a, b, c
READ (*, '(3F10.4)' ) a, b, cWRITE(*,*) 'a= ', aWRITE(*,*) 'b= ', bWRITE(*,*) 'c= ', c
END PROGRAM
If a number without a decimal point appears in the field, then a decimal point is assumed to be in the position specified by the d term of the format descriptor.
e.g.,READ (*, ‘(3F10.4)’ ) a, b, c
Input:
□□□□□□□□15□□□150□□□□□□15000□□□
F10.4 F10.4 F10.4
a = 0.0015b = 0.0150c = 1.5000
*The E and ES format descriptors are identical to the F descriptor.
Sec. 4.4.3 Logical Input – The L Descriptor
rLw
e.g.,READ (*, ‘(3L5)’ ) a, b, c
Input:
□□□□T□□□□F□□□□T
L5 L5 L5
a = Tb = Fc = T
(or T□□□□F□□□□T□□□□ )
PROGRAM linputIMPLICIT NONELOGICAL :: a, b, c
READ (*, '(3L5)' ) a, b, cWRITE(*,*) 'a= ', aWRITE(*,*) 'b= ', bWRITE(*,*) 'c= ', c
END PROGRAM
Sec. 4.4.4 Character Input – The A Descriptor
rA or rAw
e.g., CHARACTER (len=10) :: string_1, string_2CHARACTER (len=5) :: string_3CHARACTER (len=15) :: string_4, string_5READ (*, ‘(A)’ ) string_1READ (*, ‘(A10)’ ) string_2READ (*, ‘(A10)’ ) string_3READ (*, ‘(A10)’ ) string_4READ (*, ‘(A)’ ) string_5
Input:
ABCDEFGHIJKLMNOABCDEFGHIJKLMNOABCDEFGHIJKLMNOABCDEFGHIJKLMNOABCDEFGHIJKLMNO
String_1 = ‘ABCDEFGHIJ’String_2 = ‘ABCDEFGHIJ’String_3 = ‘FGHIJ’String_4 = ‘ABCDEFGHIJ □□□□□’String_5 = ‘ABCDEFGHIJKLMNO’
PROGRAM ainputIMPLICIT NONECHARACTER (len=10) :: string_1, string_2CHARACTER (len=5) :: string_3CHARACTER (len=15) :: string_4, string_5
READ (*, '(A)' ) string_1READ (*, '(A10)' ) string_2READ (*, '(A10)' ) string_3READ (*, '(A10)' ) string_4READ (*, '(A)' ) string_5WRITE(*,*)string_1WRITE(*,*)string_2WRITE(*,*)string_3WRITE(*,*)string_4WRITE(*,*)string_5
END PROGRAM
Sec. 4.4.5 Horizontal Positioning – The X and T Descriptor
e.g., CHARACTER (len=6) :: stringINTEGER :: iREAD (*, ‘(I6, T1, A6)’ ) i, string
Input: 123456
i = 123456string = ‘123456’
PROGRAM hpositionIMPLICIT NONECHARACTER (len=6) :: stringINTEGER :: i
READ (*, '(I6, T1, A6)' ) i, stringWRITE(*,'(I6)') iWRITE(*,'(A)') string
END PROGRAM
Sec. 4.4.6 Vertical Positioning – The Slash (/) Descriptor
e.g.,REAL :: a, b, c, dREAD (*, 300) a, b, c, d300 FORMAT (2F10.2, //, 2F10.2)
Input:
□□□□□□□1.0□□□□□□□2.0□□□□□□□3.0□□□□□□□4.0□□□□□□□5.0□□□□□□□6.0□□□□□□□7.0□□□□□□□8.0□□□□□□□9.0
a = 1.0b = 2.0c = 7.0d = 8.0
F10.2 F10.2 F10.2
PROGRAM vpositionIMPLICIT NONEREAL :: a, b, c, d
READ (*, 300) a, b, c, d300 FORMAT (2F10.2, //, 2F10.2)WRITE(*,*)'a= ',aWRITE(*,*)'b= ',bWRITE(*,*)'c= ',cWRITE(*,*)'d= ',d
END PROGRAM
Sec. 4.5 An Introduction to Files and File Processing
• i/o unit number:
e.g., READ (8, 100)
Typically, (vary from processor to processor)
READ (5,*) = READ (*,*)WRITE (6,*) = WRITE (*,*)
• I/O statement: (see Table 4-3)
OPEN, CLOSE, READ, WRITE, REWIND, and BACKSPACE.
Sec. 4.5.1 The OPEN Statement
OPEN ( open_list )
The five most important items from the list:
1. (the i/o unit number) UNIT = int_expr
2. (the file name of the file to be opened) FILE = char_expr
3. (the status of the file) STATUS = char_expr (‘OLD’, ‘NEW’, ‘REPLACE’, ‘SCRATCH’, or ‘UNKNOWN’)
4. (whether a file is to be opened for reading only, for writing only, or for both reading and writing) ACTION = char_expr (‘READ’, ‘WRITE’, or ‘READWRITE’)
5. (the status of the open operation) IOSTAT = int_var (If the OPEN statement is successful, a zero will be returned)
Example 1 (Opening a file for input)
INTEGER :: ierrorOPEN ( UNIT = 8, FILE = ‘INPUT.DAT’, & STATUS = ‘OLD’, ACTION = ‘READ’, & IOSTAT = ierror)
INTEGER :: ierrorOPEN ( UNIT = 25, FILE = ‘OUTPUT.DAT, & STATUS = ‘NEW’, ACTION = ‘WRITE’, & IOSTAT = ierror)
Example 2 (Opening a file for output)
Example 3 (Opening a scratch file)
OPEN ( UNIT = 12, STATUS = ‘SCRATCH’, & IOSTAT = ierror)
Sec. 4.5.2 The CLOSE Statement
CLOSE ( close_list )
e.g.,
CLOSE( UNIT = 8 )or
CLOSE( 8 )
Sec. 4.5.3 READS and WRITES to Disk Files
e.g.,OPEN ( UNIT = 8, FILE = ‘INPUT.DAT’, & STATUS = ‘OLD’, IOSTAT = ierror)READ (8,*) x, y, z
OPEN ( UNIT = 9, FILE = OUTPUT.DAT’, & STATUS = ‘REPLACE’, IOSTAT = ierror)READ (9,100) x, y, z100 FORMAT(‘ X= ‘, F10.2, ‘ Y = ‘, F10.2, ‘Z= ‘, F10.2)
Sec. 4.5.4 The IOSTAT = clause in the READ Statement
IOSTAT = int_var
e.g.,READ (8,*, IOSTAT = ierror)
If the READ statement is successful, ierror = 0.
If the READ statement is fail, ierror > 0 (format error) = -1 (end of file) = -2 (end of record)
Example 4-3 Reading Data from a File
1. State the problem. Write a program that can read in an unknown number of real values from a user-specified input data file and detect the end of the data file.
2. Define the input and output. input: (1) the filename of the data file (2) the data in that file output: the values in the data file
3. Describe the algorithm
4. Turn the algorithm into Fortran statements.
.TRUE.
.FALSE.
ierror1 = 0 ?
READ filename
Start1
nvals = nvals +1
Stop
WRITE nvals, value
Initial values:nvals = 0
Fig 4-8 (Flowchart)
WRITE ‘Error
opening file’
READ value
.FALSE.
.TRUE.
OPEN filename
1
2
ierror2 = 0 ?
ierror2 > 0 ?
WRITE ‘Error reading line’
WRITE ‘End of file’
.FALSE.
2
.TRUE.
PROGRAM readIMPLICIT NONECAHRACTER (len = 20) :: filenameINTEGER :: nvals = 0INTEGER :: ierror1, ierror2REAL :: value
WRITE(*,*) ‘Please enter input file name:’READ (*,*) filenameOPEN (UNIT = 3, FILE = filename, STATUS = ‘OLD’, & ACTION = ‘READ’, IOSTAT = ierror1)
openif: IF(ierror1 ==0) THEN readloop: DO READ(3,*), IOSTAT = ierror2) value IF (ierror2 /= 0) EXIT nvals = nvals + 1 WRITE(*, 1010) nvals, value 1010 FORMAT (‘Line ‘, I6, ‘:value=‘, F10.4) END DO readloop
readif: IF (ierror2 > 0) THEN WRITE(*, 1020) nvals + 1 1020 FORMAT (‘Error reading line’, I6) ELSE WRITE(*, 1030) nvals 1030 FORMAT (‘End of file. There are ‘, & I6, ‘ values in the file.’) END IF readifELSE openif WRITE(*, 1040) ierror1 1040 FORMAT (‘Error opening file: IOSTST=‘, I6)END IF openifCLOSE(3)END PROGRAM
Test the program:
(1) The valid input file READ1.TXT: (e.g., use Notepad)
-17.030.0011.012000.-0.012
Output: Please enter input file name:READ1.TXTLine 1: value = -17.0000Line 2: value = 30.0000 Line 3: value = 1.0000 Line 4: value = 12000.0000 Line 5: value = -0.0120 End of file. There are 5 values in the file.
(2) The invalid input file READ2.TXT:
-17.030.001ABCDEF12000.-0.012
Output:
Please enter input file name:READ2.TXTLine 1: value = -17.0000Line 2: value = 30.0000Error reading Line 3
(3) A file does not exist:
Output:Please enter input file name:JUNK.DATError opening file: IOSTAT = 128
(depends on machine)
Sec. 4.5.4 File Positioning
BACKSPACE ( UNIT = a unit # )
REWIND ( UNIT = a unit #)
and
Example 4-4 Using File-Positioning Commands:
(1) Write a program that accepts a series of nonnegative real values and stores them in a scratch file.
(2) Ask the user for a record number to display.
(2) Rewind the file, get that value, and display it.
PROGRAM scratchIMPLICIT NONEINTEGER, PARAMETER :: unit = 8REAL :: dataINTEGER :: icount = 0, irec, j
OPEN (UNIT = unit, STATUS = ‘SCRATCH’)WRITE(*, 100)100 FORMAT (1X, ‘Enter positive or zero input values.’, / , & 1X, ‘A negative value terminates input.’)DO WRITE(*, 110) icount + 1 110 FORMAT (1X, ‘Enter sample ‘, I4, ‘:’) READ (*,*) data IF ( data < 0. ) EXIT icount = icount + 1 WRITE(unit, 120) data 120 FORMAT (1X, ES16.6)END DO
WRITE(*, 130) icount130 FORMAT (1X, ‘Which record do you want to see ( 1 to’, I4, ‘)? ’)READ (*,*) irecIF ( ( irec >= 0) .AND. (irec <= icount) )THEN REWIND (UNIT = unit) DO j = 1, irec READ( unit, *) data END DO WRITE(*, 140) irec, data 140 FORMAT (1X, ‘ The value of record ‘, I4, ‘is’, ES14.5)ELSE WRITE(*, 150) irec 150 FORMAT (1X, ‘ Illegal record number entered: ‘, I8)END IFEND PROGRAM
Output:Enter positive or zero input values.A negative input value terminates input.Enter sample 1:234.Enter sample 2:12.34Enter sample 3:0.Enter sample 4:16.Enter sample 5:11.235Enter sample 6:2.Enter sample 7:-1.Which recore do you want to see ( 1 to 6)?5The value of record 5 is 1.12350E+01
Example 4-5 The linear fit problem:
Given a set of measurements (xi , yi), i = 1, . . . , N:
(x2, y2)
(x4, y4)
(x3 , y3)
(x1 , y1)
The best fit: y = mx + b
x
y
m = ?b = ?
The method of least squares:
m =
(Σxi yi ) - (Σxi ) y i=1
N
where
y = Σyii=1 i=1
N N
Σxi
N
b = y – m x
i=1
N
(Σxi2 ) - (Σxi ) x
N
i=1i=1
N
and x = N
PROGRAM least_squares_fitIMPLICIT NONEINTEGER, PARAMETER :: unit = 18CHARACTER (len = 24) :: filenameINTEGER :: ierror, n = 0REAL :: m, bREAL :: sum_x = 0., sum_x2 = 0., sum_xy = 0., sum_y = 0.REAL :: x, y, x_bar, y_bar
WRITE(*, 1000)1000 FORMAT (1X, ‘Enter the file name: ‘)READ (*, ‘(A)’) filenameOPEN (UNIT = unit, FILE = filename, STATUS = ‘OLD’, & ACTION = ‘READ’, IOSTAT = ierror)
errorcheck: IF (ierror > 0) THEN WRITE(*, 1020) filename 1020 FORMAT (1X, ‘ERROR: File ‘, A, ‘ does not exist! ’)ELSE
DO READ (unit, *, IOSTAT = ierror) x, y IF ( ierror /= 0 ) EXIT n = n + 1 sum_x = sum_x + x sum_y = sum_y + y sum_x2 = sum_x2 + x ** 2 sum_xy = sum_xy + x * y END DO x_bar = sum_x / n y_bar = sum_y / n m = (sum_xy – sum_x * y_bar) / (sum_x2-sum_x * x_bar) b = y_bar – m * x_bar WRITE(*, 1030) m, b, n 1030 FORMAT (1X, ‘ m = ‘, F12.3, / , & 1X, ‘ b = ‘, F12.3, / , & 1X, ‘ N = ‘, I12) CLOSE(18)END IF errorcheck END PROGRAM
Test the program:
(1) The input file INPUT.TXT:
1.1 1.12.2 2.23.3 3.34.4 4.45.5 5.56.6 6.67.7 7.7
Output:
m = 1.000 b = 0.000 N = 7
(2) The input file INPUT1.TXT:
1.1 1.012.2 2.303.3 3.054.4 4.245.5 5.756.6 6.487.7 7.84
Output:
m = 1.024 b = -0.12 N = 7
Ch. 5 Arrays
Fig. 5-1
a(1)
a(2)
a(3)
a(4)
a(5)
. . .
. . .
array a
e.g.,DO i = 1, 100 a(i) = SQRT (a(i))END DO
Sec. 5.1 Declaring Arrays
• Type: real, integer, logical, or character
e.g.,
REAL, DIMENSION (16) :: voltage
voltage(1), voltage(2), . . . , voltage(16)
or
CHARACTER (len = 20), DIMENSION (50) :: last_name
last_name(1), . . . , last_name(50)
• Rank: The # of subscripts declared for a given array
e.g., REAL, DIMENSION (3, 6) :: sum
a rank-2 array
• Extent: The # of elements in a given dimension of an array
e.g., The extent of the 1st subscript of sum is 3.
The extent of the 2nd subscript of sum is 6.
• Size: the # of elements
• Shape: the combination of rank and extent in each dimension
e.g., The shape of sum = 3 6
e.g., The size of sum = 18
Array constructor:
e.g., INTEGER, DIMENDION (5) :: a = (/ 1, 2, 3, 4, 5 /)
Sec. 5.2 Using Array Elements in Fortran Statements
Sec. 5.2.1 Array Elements Are Just Ordinary Variables
e.g.,
INTEGER, DIMENDION (10) :: indexLOGICAL, DIMENSION (2) :: lvalREAL, DIMENSION (3) :: temp
Index(1) = 1Lval(2) = .TRUE.Temp(3) = REAL(index(1)) / 4.WRITE(*,*) ‘ index(1) = ‘, index(1)
Sec. 5.2.2 Initialization of Array Elements
e.g.,INTEGER, DIMENDION (10) :: jWRITE(*,*) ‘ j(1)=‘, j(1)
uninitialized array
?• Initialization arrays with assignment statements:
e.g.,REAL, DIMENDION (10) :: array1DO i = 1, 10 array1(i) = 0.0END DO
orREAL, DIMENDION (10) :: array1array1 = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /)
• Initialization arrays in type declaration statements:
e.g.,
INTEGER, DIMENDION (5) :: array2 = (/ 1, 2, 3, 4, 5 /)
or
REAL, DIMENDION (100) :: array5 = 1.
or
INTEGER, DIMENDION (5) :: array2 = (/ ( i, i = 1, 5) /)
INTEGER, DIMENDION (25) :: array4 = (/ ((0, i = 1, 4), & 5*j, j = 1, 5) /)
0, 0, 0, 0, 5, 0, 0, 0, 0, 10, 0, 0, 0, 0, 15, . . .
or
array5(1) = 1., . . . , array5(100) = 1.
•Initialization arrays with Fortran READ statements:
Just like any other variables. (See Sec. 5.4: I/O of Array Elements)
Sec. 5.2.3 Changing the Subscript Range of an Array
e.g.,
REAL, DIMENSION(5) :: arr
arr(1), arr(2), arr(3), arr(4), arr(5)
but arr(0) = ?
e.g., c = Σ an = a0 + a1 + a2 + a3 + a4n=0
4
need a(0)!
Use
REAL, DIMENSION ( lower_bound : upper_bound ) :: arrar
e.g.,REAL, DIMENSION (-2:2) :: b
b(-2), b(-1), b(0), b(1), b(2)
orREAL, DIMENSION (5:9) :: c
c(5), c(6), c(7), c(8), c(9)
(5 elements)
(5 elements)
Example (Fig. 5-4)
i i2
-5 25-4 16… …+4 16+5 25
PROGRAM squares_2IMPLICIT NONEINTEGER :: IINTEGER, DIMENSION(-5:5) :: number, square
DO i = -5, 5 number(i) = I square(i) = number(i)**2 WRITE(*, 100) number(i), square(i) 100 FORMAT (1X, ‘Number = ‘, I6, ‘ Square= ‘, I6)END DOEND PROGRAM
Sec. 5.2.4 Out-of-bound Array Subscripts
e.g.,REAL, DIMENSION(5) :: a
a(1), a(2), a(3), a(4), a(5)
but if use a(6), out of bound!
Sec. 5.2.5 The Use of Named Constants with Array Declarations
e.g.,INTEGER, PARAMETER :: isize = 1000REAL, DIMENSION (isize) :: array1REAL, DIMENSION (isize) :: array2REAL, DIMENSION (2*isize) :: array3
PROGRAM extremesIMPLICIT NONEINTEGER, PARAMETER :: max_size = 10INTEGER, DIMENSION (max_size) :: inputINTEGER :: ilarge, ismall, j, nvals, tempWRITE(*,*) ' Enter number of values in data set:'READ(*,*) nvalssize: IF (nvals <= max_size) THEN in: DO j = 1, nvals WRITE(*, 100) ' Enter value ', j 100 FORMAT (' ', A, I3, ':' ) READ(*,*) input(j) END DO in temp = input(1) ilarge = 1 large: DO j = 2, nvals IF (input(j) > temp) THEN temp = input(j) ilarge = j END IF END DO large
Example 5-1 (Finding the largest and smallest values in a data set)
temp = input(1) ismall = 1 small: DO j = 2, nvals IF (input(j) < temp) THEN temp = input(j) ismall = j END IF END DO small WRITE(*, 110) 110 FORMAT(1X, 'The values are:') out: DO j = 1, nvals IF (j == ilarge) THEN WRITE(*, '(1X, I6, 2X, A)') input(j), 'LARGEST' ELSE IF (j == ismall) THEN WRITE(*, '(1X, I6, 2X, A)') input(j), 'SMALLEST' ELSE WRITE(*, '(1X, I6)') input(j) END IF END DO outELSE size WRITE(*, 120) nvals, max_size 120 FORMAT(1X, ' Too many input values: ', I6, '>', I6)END IF sizeEND PROGRAM
Test:
Enter number of values in data set:6Enter value 1:-6Enter value 2:5Enter value 3:-11Enter value 4:16Enter value 5:9Enter value 6:0
The values are: -6 5 -11 SMALLEST 16 LARGEST 9 0
Output
Sec. 5.3 Using Whole Arrays and Array Subsets in Fortran Statements
Sec. 5.3.1 Whole Array Operations
e.g.,
1.
2.
3.
4.
a(1)
a(4)
a(3)
a(2)
a
+
b(1)
b(2)
b(3)
b(4)
5.
6.
7.
8.
b
=
c
12.
10.
8.
6.
Fig. 5-6
PROGRAM add_arraysIMPLICIT NONEINTEGER :: IREAL, DIMENSION(4) :: a = (/ 1., 2., 3., 4. /)REAL, DIMENSION(4) :: b = (/ 5., 6., 7., 8. /)REAL, DIMENSION(4) :: c, d
DO i = 1,4 c(i) = a(i) + b(i)END DOd = a + bWRITE(*, 100) ‘c’, cWRITE(*, 100) ‘d’, d100 FORMAT (1X, A, ‘ =‘, 5(F6.1, 1X))END PROGRAM
If arrays a and b have the same shape,
Conformable!
e.g.,REAL, DIMENSION(1:4) :: a = (/ 1., 2., 3., 4. /)REAL, DIMENSION(5:8) :: b = (/ 5., 6., 7., 8. /)REAL, DIMENSION(101:104) :: cc = a + b
REAL, DIMENSION(4) :: a = (/ 1., 2., 3., 4. /)REAL :: b = 10REAL, DIMENSION(4) :: cc = a * b
or
c = (/ 10., 20., 30., 40. /)
(Not matrix multiplication)
Elemental intrinsic functions: (see App. B for a complete list)
ABS, SIN, COS, EXP, and LOG.
e.g.,REAL, DIMENSION(4) :: x = (/ 0., 3.14, 1., 2. /), yINTEGER :: iDO i = 1, 4 y(i) = SIN(x(i))END DO
or use y = SIN(x)
REAL, DIMENSION(4) :: a = (/ -1., 2., -3., 4. /), yy = ABS(a)
or
y = (/ 1., 2., 3., 4. /)
Sec. 5.3.2 Selecting Subsets of Arrays for Use in Calculations
Array section: A subset of an array.
• Subscript triplet:
subscript_1 : subscript_2 : stride
e.g.,
INTEGER, DIMENSION(10) :: a = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
array(1:10:2) = [1, 3, 5, 7, 9]
Alternative forms: subscript_1 : subscript_2 subscript_1 : : subscript_2
stride = 1to the last subscriptto the 1st subscript
Example 5-5
INTEGER :: i = 3, j = 7REAL, DIMENSION(10) :: a = (/ 1., -2., -3., -4., 5, -6., 7., -8., & 9., -10. /)(a) a(:) = [1., -2., -3., -4., 5, -6., 7., -8., 9., -10.](b) a(i:j) = a(3:7:1) = [3., -4., 5., -6., 7.](c) a(i:j:i) = a(3:7:3) = [3., -6.](d) a(i:j:j) = a(3:7:7) = [3.](e) a(i:) = a(3:10:1) = [3., -4., 5., -6., 7., -8., 9., -10.](f) a(:j) = a(1:7:1) = [1., -2., 3., -4., 5., -6., 7.](g) a(::i) = a(1:10:3) = [1., -4., 7., -10.]
• Vector subscript:
INTEGER, DIMENSION(5) :: vec = (/ 1, 6, 4, 1, 9 /)REAL, DIMENSION(10) :: a = (/ 1., -2., -3., -4., 5, -6., 7., -8., & 9., -10. /)
a(vec) = [1., -6., -4., 1., 9.]
a(1) a(1) a(9)a(4)a(6)
e.g.,
*Vector subscript cannot be used on the left side of an assignment statement.
e.g., INTEGER, DIMENSION(3) :: vec = (/ 1, 2, 1 /)REAL, DIMENSION(3) :: a = (/ 10., 20., 30. /)REAL, DIMENSION(2) :: bb(vec) = a (Incorrect!)
Sec. 5.4 Input and Output
Sec. 5.4.1 Input and Output of Array Elements
e.g., WRITE(*, 100) a(1), a(2), a(3), a(4), a(5)100 FORMAT (1X, ‘a=‘, 5F10.2)
Just like any other variables.
Sec. 5.4.2 The Implied DO LOOP
e.g.,
WRITE(*, 100) (a(i), I = 1, 5)100 FORMAT (1X, ‘a=‘, 5F10.2)
Sec. 5.4.3 Input and Output of Whple Arrays and Array Sections
Fig. 5-9 (array I/O)
PROGRAM array_ioIMPLICIT NONEREAL, DIMENSION(5) :: a = (/ 1., 2., 3., 20., 10. /)INTEGER, DIMENSION(4) :: vec = (/ 4, 3, 4, 5 /)WRITE(*, 100) a100 FORMAT (2X, 5F8.3)WRITE(*, 100) a(2: :2)WRITE(*, 100) a(vec)END PROGRAM
(Output) 1.000 2.000 3.000 20.000 10.000 2.000 20.00020.000 3.000 20.000 10.000
Sec. 5.5 Examples
Example 5-3 Sorting Data
Ascending order (the lowest to the highest)
Descending order (the highest to the lowest)
or
e.g.,
(10, 3, 6, 4, 9)(sorting)
(3, 4, 6, 9, 10)
Fig. 5-10 (selection sort)
10
9
4
6
3
(swap)3
10
6
4
9
(swap)3
4
6
10
9
(no swap)
3
4
6
10
9
(swap)
3
4
6
10
9
Steps:
1. Get the input filename2. Open the input file3. Read the input data into an array4. Sort the data in ascending order5. Write the sorted data
Fig. 5-13PROGRAM sort1IMPLICIT NONEINTEGER, PARAMETER :: max_size = 10REAL, DIMENSION (max_size) :: aCHARACTER (len = 20) :: filenameINTEGER :: i, iptr, j, statusINTEGER :: nvals = 0REAL :: tempWRITE(*, 1000)1000 FORMAT (1X, ‘ Enter the file name’)READ(*, ‘(A20)’) filenameOPEN (UNIT = 9, FILE = filename, STATUS = ‘OLD’, & ACTION = ‘READ’, IOSTAT = status)fileopen: IF(status == 0) THEN DO READ (9, *, IOSTAT = status) temp IF (status /= 0) EXIT nvals = nvals + 1 a(nvals) = temp END DO
outer: DO i = 1, nvals – 1 iptr = I inner: DO j = i + 1, nvals minval: IF (a(j) < a(iptr)) THEN iptr = j END IF minval END DO inner ! swap a(iptr) with a(i) if i /= iptr swap: IF ( I /= iptr ) THEN temp = a(i) a(i) = a(iptr) a(iptr) = temp END IF swap END DO outer WRITE(*, ‘(A)’) ‘ The sorted data are:’ WRITE(*, 1040) ( a(i), i = 1, nvals) 1040 FORMAT (4X, F10.4)ELSE fileopenWRITE(*, 1050)status1050 FORMAT (1X, ‘File open failed: ’, I6)END IF fileopenEND PROGRAM
Test:
INPUT2.TXT
13.312.-3.00.4.06.64.-6.
output
Enter the file nameINPUT2.TXTThe sorted data are: -6.0000 -3.0000 0.0000 4.0000 6.600012.000013.3000
Sec. 5.6 Two-Dimensional Features of Arrays
• 1-dim. array: rank-1 array or vector• 2-dim. array: rank-2 array or matrix
Fig. 5-17
a(1)
a(4)
a(2)
a(3)
row 1
row 3
row 2
row 4
a(irow)
(a) 1-dim array
b(1,1) b(1,2)
b(2,1) b(2,2)
b(1,3)
b(2,3)
row 1
row 2
col 1 col 2 col 3
b(irow, icol))
(b) 2-dim array
Sec. 5.6.1 Declaring Rank-2 Arrays
e.g.,REAL, DIMENSION(3,6) :: sumINTEGER, DIMENSION(0:100, 0:20) :: hist
Sec. 5.6.2 Rank-2 Array Storage
Fig. 5-19
a(1,1) a(1,2) a(1,3)
a(2,2)a(2,1) a(2,3)
a(irow, icol)
(Memory allocation)
a(1,1)
a(2,1)
a(1,2)
a(2,2)
a(1,3)
a(2,3)
column major order
Sec. 5.6.3 Initializing Rank-2 Array
1. Use assignment statements
e.g., 1
1
1
1
2
2
2
2
3
3
3
3
INTEGER, DIMENSION(4,3) :: istatDO i = 1, 4 DO j = 1, 3 istat(i, j) = j END DOEND DO
use
orDO j = 1, 3 istat(:, j) = jEND DO
cannot use
istat = (/ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 /)
(Array constructors always produce rank-1 array!)
use
istat = RESHAPE ( (/ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 /), (/4, 3/) )
(column major) (data to be reshaped)
(a new shape)
2. Use type declaration statements
INTEGER, DIMENSION(4, 3) :: istat (4,3) = & RESHAPE ( (/ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 /), (/4, 3/) )
3. Use READ statements
INTEGER, DIMENSION(4,3) :: istatOPEN(7, FILE = ‘INITIAL.DAT’, STATUS = ‘OLD’, & ACTION = ‘READ’)READ (7, *) istat
(INITIAL.DAT: 1 1 1 1 2 2 2 2 3 3 3 3 )
or
READ (7, *) ((istat(i,j), j = 1, 3), i = 1, 4)
(INITIAL.DAT: 1 2 3 1 2 3 1 2 3 1 2 3 )
(i = 1) (i = 4)(i = 3)(i = 2)
Sec. 5.6.4 Examples
Examples 5-5
power =
20.0 40.3 42.0 20.419.8 40.1 41.5 26.920.1 40.0 41.3 38.420.0 39.5 41.1 42.020.0 39.9 39.8 12.219.9 40.0 41.0 6.0
use
REAL,DIMENSION(6,4) :: power…OPEN(9, FILE = ‘INPUT1’, STATUS = ‘OLD’, & ACTION = ‘READ’)READ (9, *) power
INPUT1: 20.0 19.8 20.1 20.0 20.0 19.9 40.3 40.1 40.0 39.5 39.9 40.0 42.0 41.5 41.3 41.1 39.8 41.0 20.4 26.9 38.4 42.0 12.2 6.0
OPEN(9, FILE = ‘INPUT2’, STATUS = ‘OLD’, & ACTION = ‘READ’)READ (9, *) ((power(i, j), j = 1, 4), i = 1, 6)
INPUT2:
or
20.0 40.3 42.0 20.419.8 40.1 41.5 26.920.1 40.0 41.3 38.420.0 39.5 41.1 42.020.0 39.9 39.8 12.219.9 40.0 41.0 6.0
Sec. 5.6.5 Whole Array Operation and Array Subsets
e.g.,
a =
1 2 3 4 5 6 7 8 9 1011 12 13 14 1516 17 18 19 2021 22 23 24 25
a(:, 1) =
1 6111621
a(1, :) = [ 1 2 3 4 5 ]
a(1:3, 1:5:2) =
1 3 5 6 8 1011 13 15
Sec. 5.7 Multidimensional or Rank-n Array
(up to 7)Fig. 5-22 ( A 2 × 2 × 2 array a)
a(1, 1, 1)
a(2, 1, 1)
a(1, 2, 1)
a(2, 2, 1)
a(1, 1, 2)
a(2, 1, 2)
a(1, 2, 2)
a(2, 2, 2)
(memory allocation)
Sec. 5.8 Using Fortran Intrinsic Functions with Arrays
Sec. 5.8.1 Elemental Intrinsic Functions
e.g.,
ABS, SIN, COS, TAN, EXP, LOG, LOG10, MOD, AND SQRT.
REAL, DIMENSION :: x = (/ 10., 3.14, 1., 2. /), yINTEGER :: iDO i = 1, 4 y(i) = sin(x(i))END DO
equiv.y = sin(x)
Sec. 5.8.2 Inquiry Intrinsic Functions
Table 5-1
LBOUND (ARRAY, DIM)SHAPE (SOURCE)SIZE(ARRAY, DIM)UBOUND (ARRAY, DIM)
(a particular dimension, e.g., 1 or 2)
Example 5-6 (Determining the Properties of an Array)
PROGRAM check_arrayREAL, DIMENSION(-5:5, 0:3) :: a = 0.WRITE(*, ‘(A, 7I6)’) ‘ The shape is: ‘, SHAPE(a)WRITE(*, ‘(A, I6)’) ‘ The size is: ‘, SIZE(a)WRITE(*, ‘(A, 7I6)’) ‘ The lower bounds are: ‘, LBOUND(a)WRITE(*, ‘(A, 7I6)’) ‘ The upper bounds are: ‘, UBOUND(a)END PROGRAM
Output:
11 5 (size(a, 1) = 11, size(a, 2) = 4)44-5 0 (LBOUND(a, 1) = -5, LBOUND(a, 2) = 0) 5 3 (UBOUND(a, 1) = 5, UBOUND(a, 2) = 3)
Sec. 5.8.3 Transformational Intrinsic Functions
Table 5-2
DOT_PRODUCT (VECTOR_A, VECTOR_B)MATMUL (MATRIX_A, MATRIX_B)RESHAPE (SOURCE, SHAPE)
Sec. 5.9 Masked Array Assignment: The WHERE Constructe.g.,
DO i = 1, ndim1 DO j = 1, ndim2 logical(i, j) = LOG (value(i, j)) END DOEND DO
equiv.logval = LOG(value)
But if value(i, j) 0≦ LOG(value(i, j) is not defined!(run-time errors!)
DO i = 1, ndim1 DO j = 1, ndim2 IF (value(i, j) > 0.) THEN logical(i, j) = LOG (value(i, j)) ELSE logical(i, j) = -99999. END IF END DOEND DO
equiv.
WHERE (value > 0.) logval = LOG(value)ELSEWHERE logical = -99999.END WHERE
The general form:
[name:] WHERE (mask_expr) Array Assignment Statements ! Block1ELSEWHERE [name:] Array Assignment Statements ! Block2END WHERE [name:]
Example 5-7 Limiting the Maximum and Minimum Values in an Array (-1000 input(i) 1000)≦ ≦
DO i = 1, 10000 IF ( input(i) > 1000. ) THEN input(i) = 1000. ELSE IF (input(i) < -1000.) THEN input(i) = -1000. END IF END DO
equiv. WHERE ( ABS(input) > 1000.) input = SIGN(1000., input)END WHERE
( SIGN(A, B): returns the value of A with the sign of B.)
Top Related