Ch. 1 Introduction To Computers And The Fortran Language

Download Report

Transcript Ch. 1 Introduction To Computers And The Fortran Language

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:00
2. Tues. 11:10~12:00
14:40~15:30
3. Fri. 10:10~12:00
Midterm
90
|
99
1
80
|
89
1
70
|
79
60
|
69
50
|
59
1
40
|
49
5
30
|
39
3
20
|
29
15
10
|
19
33
0
|
9
27
Tot: 86 students
Prob. 1(a)
Prob. 1(b)
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
n=
n=
n=
n=
n=
2
4
8
10
4
Prob. 1(c)
□□□F□□15□□120.0□test
Prob. 2
PROGRAM gave
IMPLICIT NONE
CHARACTER (len = 20) :: filename
INTEGER :: nvals = 0
INTEGER :: ierror1, ierror2
REAL :: value, x_ave=1.0
WRITE(*,*) 'Please enter input file name:'
READ (*,*) filename
OPEN (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
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 readif
ELSE openif
WRITE(*, 1040) ierror1
1040 FORMAT ('Error opening file: IOSTAT=', I6)
END IF openif
CLOSE(3)
END PROGRAM
Test:
GAVE.TXT:
1.
2.
4.
output
x_ave = 2.000
Ch. 1 Introduction To Computers And
The Fortran Language
Sec. 1.1 The Computer
Fig 1-1
Main
Memory
Input
devices
Secondary
Memory
CPU
(Central processing unit)
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
102 101 100
= 1 x 102 + 2 x 101 + 3 x 100 = 123.
The base 2 number system:
1 0 1
2
= 1 x 22 + 0 x 21 + 1 x 20 = 5
2
= 1 x 22 + 1 x 21 + 1 x 20 = 7
22 21 20
1 1 1
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)
exponent
mantissa
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
(1966)
(1977)
(1991)
Fortran 95
(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
100
output = input1 &
+ input2
! Sum the inputs
or
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
Declaration
section
Execution
section
Termination
section
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
(Compile)
Executable
program
Object
file
(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. INTEGER
(numeric)
2. REAL
3. COMPLEX
(logical)
4. LOGICAL
5. CHARACTER (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,
7/4 = 1,
6/4 = 1
9/4 = 2
Sec. 2.6.2 Real Arithmetic (or floating-point arithmetic)
e.g.,
3./4. = 0.75,
7./4. = 1.75,
6./4. = 1.50
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.
(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.
c=3.
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.,
(a integer variable)
nres = 1.25 + 9/4
= 1.25 + 2
= 3.25
=3
(a real variable)
ave = (5 + 2) / 2
= 7/2
= 3.
Logarithm
• Base 10:
If 10x = N, then x = ?
e.g., N = 100
N=3
log N = x
log 100 = log (102) = 2
log 3 = 0.47712…
• Base e (=2.71828…): (Natural logarithm)
If ex = N, then x = ?
e.g., N = e2
N=3
* If N < 0
ln N = x
ln (e2) = 2
ln 3 = 1.09861…
( 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
==
/=
>
>=
<
<=
e.g.,
equal to
not equal to
greater than
greater than or equal to
less than
less than or equal to
operation
result
3<4
.TRUE.
3<=4
.TRUE.
3==4
.FALSE.
‘A’ < ‘B’
.TRUE. (in ASCII, A
7+3 < 2+11 .TRUE.
65, B
66, p.493)
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.
.OR.
.EQV.
.NEQV.
.NOT.
logical AND
logical OR
logical equivalence
logical non-equivalence
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.,
(a) .NOT. L1
(b) L1 .OR. L3
L3 = .FALSE.
.FALSE.
.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 specifications
2. concatenation
Sec. 2.8.1 Substring Specifications
E.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
‘a’ < ‘A’ (false, ∵ a
65, B
97)
‘AAAAAB’ > ‘AAAAAA’ (true)
‘AB’ > ‘AAAA’ (true)
‘AAAAA’ > ‘AAAA’ (true)
66)
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)
y = sin(SQRT(x))
NINT(2.9995) = 3
(rounds the real number)
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
(Try it out!)
2
3.00000
This one.
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
Fig. 3-1 (a formal program design process)
Start
State the
problem
Design the
algorithm
Convert algorithm into
Fortran statements
Test the program
Finished !
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 to
enter temp_f
(an oval for start or stop)
(a parallelogram for I/O)
Get temp_f
Calculate
temp_k
(a rectangle for computation)
Write temp_k
Stop
Sec. 3.3 Control Constructs: Branches
Branches are Fortran statements that permit us to select and
execute specific sections of code (called blocks) while skipping
other sections of code.
• IF Statement
• SELECT CASE
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)
(a diamond for choice)
.FALSE.
logical_expr
.TRUE.
Statement 1
Statement 2
.
.
Example:
ax2 + bx + c = 0,
x=
If
-b ± ( b2 – 4ac )1/2
2a
b2 – 4ac > 0
two distinct real roots
b2 – 4ac = 0
a single repeated root
b2 – 4ac < 0
two complex roots
Problem: Tell the user if the eq. has complex roots.
Fig . 3-6
b2
(Flowchart)
– 4ac < 0
.TRUE.
WRITE ‘two
complex roots’
.FALSE.
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
Block 1
.
.
ELSE IF (logical_expr_2) THEN
Statement 1
Statement 2
Block 2
.
.
ELSE
Statement 1
Statement 2
Block 3
.
.
END IF
Fig . 3-7
(flowchart)
.FALSE.
logical_expr_1
.TRUE.
Block 1
logical_expr_2
.FALSE.
.TRUE.
Block 2
Block 3
Example: Tell the user whether the eq. has two complex roots,
two identical real roots, or two distinct real roots.
Fig . 3-8 (flowchart)
b2 -
4ac < 0
.FALSE.
.TRUE.
WRITE ‘two
complex roots’
b2
- 4ac = 0
.FALSE.
.TRUE.
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
(Try it out!)
Write a complete Fortran program for a quadratic
equation 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’
PROGRAM abc
IMPLICIT NONE
REAL :: 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: roots
real
repeated real
complex
PROGRAM root
IMPLICIT NONE
REAL :: a, b, c, d, re, im, x1, x2
WRITE(*,*)'Enter the coeffs. a, b, and c:‘
READ(*,*) a, b, c
d = b**2 – 4.*a*c
IF ( 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=‘, x2
END IF
END 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) =
Input: x, y
Output: f
x + y,
x + y2 ,
x2 + y,
x2 + y2,
x≧0 and y ≧ 0
x≧0 and y < 0
x < 0 and y ≧ 0
x < 0 and y < 0
Start
Fig . 3-11 (flowchart)
READ x, y
x≧0
&
y≧0
.FALSE.
.TRUE.
f=x+y
WRITE f
Stop
x≧0
&
y<0
.FALSE.
.TRUE.
f=x+
y2
x<0
&
y≧0
.FALSE.
.TRUE.
f = x2 + y
f = x2 + y2
PROGRAM funxy
IMPLICIT NONE
REAL :: x, y, f
WRITE(*,*)'Enter x and y:‘
READ(*,*) x, y
IF ((x >= 0.) .AND. (y >= 0. )) THEN
f=x+y
ELSE IF ((x >= 0.) .AND. (y < 0. )) THEN
f = x + y**2
ELSE IF ((x < 0.) .AND. (y >= 0. )) THEN
f = x**2 + y
ELSE
f = x**2 + y**2
END IF
WRITE(*,*) ‘f = ‘, f
END PROGRAM
Test: (Try it out!)
x
y
f
2.
2.
-2.
-2.
3.
-3.
3.
-3.
5.
11.
7.
13.
Sec. 3.3.4 Named Block IF Constructs
[name:] IF (logical_expr_1) THEN
Statement 1
Statement 2
Block 1
.
.
ELSE IF (logical_expr_2) THEN [name]
Statement 1
Statement 2
Block 2
.
.
optional
ELSE [name]
Statement 1
Statement 2
Block 3
.
.
END IF [name]
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
86 < GRADE < 95
76 < GRADE < 86
66 < GRADE < 76
0 < GRADE < 66
Input: grade
Output:
or
or
or
or
‘The grade is A.’
‘The grade is B.’
‘The grade is C.’
‘The grade is D.’
‘The grade is F.’
A
B
C
D
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 if2
END 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
Sec. 3.3.7 The CASE Construct
[name:] SELECT CASE (case_expr)
optional
CASE (case_selector_1) [name]
Statement 1
Block 1
Statement 2
. . .
optional
CASE (case_selector_2) [name]
Statement 1
Statement 2
Block 2
. . .
optional
CASE DEFAULT [name]
Statement 1
Statement 2
Block 3
. . .
END SELECT [name]
case_expr: an integer, character, or logical expression.
The case_selector can take one of four forms:
1.
2.
3.
4.
case_value
Execute block if case_value == case_expr
low_value:
Execute block if low_value <= case_expr
: high_value: Execute block if case_expr <= high_value
low value: high_value
Execute block if low_value <= case_expr <= high_value
Fig . 3-13
Not
in range
case_sel_1
In range
Block 1
(flowchart for a CASE construct)
case_sel_2
Not
In range
In range
Block 2
case_sel_n
Not
in range
In range
Block n
Default
Block
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 selectc
IMPLICIT NONE
INTEGER :: temp_c
WRITE(*,*) “Enter today’s temp. in degree C:”
READ(*,*) temp_c
temp: 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 temp
END PROGRAM
Problem: Determine whether an integer between 1 and 10 is
even or odd. (Try it out!)
PROGRAM selectv
INTEGER :: value
WRITE(*,*) 'Enter an inter between 1-10:'
READ(*,*) value
SELECT 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 SELECT
END 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)
Statement 1
. . .
.TRUE.
logical_expr
.FALSE.
Statement 1
. . .
Example 3-4 Statiscal Analysis:
Average:
N
Σxi
x_ave =
i=1
N
Standard deviation:
N
N
i=1
i=1
N Σxi2 – ( Σxi )2
S=
N (N-1)
Input: x (i.e., xi , i = 1, 2, …, N) ≧ 0
Output: x_ave and S
1/2
Fig . 3-15
Start
READ x
x<0
(Flowchart for Example 3-4)
Initial values:
n=0
sum_x = 0
Sum_x2 = 0
1
Calculate
x_ave, s
.TRUE.
.FALSE.
n=n+1
sum_x = sum_x + x
sum_x2=sum_x2 + x2
WRITE
x_ave, s, n
Stop
1
Fig . 3-16
PROGRAM stats_1
IMPLICIT NONE
INTEGER :: n = 0
REAL :: 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**2
END DO
x_ave = sum_x / n
s = sqrt (( n*sum_x2 – sum_x**2) / (n*(n-1)))
WRITE(*,*) ‘n = ‘ , n, ‘ x_ave = ‘, x_ave, &
‘ s = ‘, s
END 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 n
END DO
e.g.,
(1)
Do i = 1, 10
Statement 1
...
Statement n
END DO
( incr = 1 by default)
(2)
Do i = 1, 10, 2
Statement 1
...
Statement n
END DO
( i = 1, 3, 5, 7, 9 )
Fig. 3-18 (Flowchart for a Do loop construct)
.FALSE.
index =
index*incr
istart
≦iend * incr
incr
.TRUE.
Statement 1
Statement 2
...
Example 3-5 The Factorial Function:
N ! = N × (N-1) × (N-2) … × 3 × 2 × 1,
0!=1
N > 0.
e.g.,
4 ! = 4 × 3 × 2 × 1 = 24
5 ! = 5 × 4 × 3 × 2 × 1 = 120
Fortran Code:
n_factorial = 1
DO i = 1, n
n_factorial = n_factorial * i
END DO
Problem: Write a complete Fortran program for the factorial
function.
N ! = N × (N-1) × (N-2) … × 3 × 2 × 1,
0!=1
Input: n ( n > = 0 )
Output: n!
N > 0.
PROGRAM factorial
IMPLICIT NONE
INTEGER :: i, n, n_fact
WRITE(*,*) ’Enter an integer n ( > = 0 ):’
READ(*,*) n
n_fact = 1
IF ( n > 0 ) THEN
DO i = 1, n
n_fact = n_fact * i
END DO
END IF
WRITE(*,*) n, ‘! = ‘, n_fact
END PROGRAM
Example 3-7 Statistical Analysis: (modified)
Start
Fig . 3-20
READ n
.TRUE.
n<2
Initial values:
sum_x = 0
sum_x2 = 0
.FALSE.
.FALSE.
1
i=1 i≦n
i=i+1 ?
.TRUE.
1
READ x
Calculate
x_ave, s
WRITE
‘At least
2 values!’
WRITE
x_ave, s, n
Stop
sum_x =
sum_x + x
sum_x2 =
sum_x2+x2
Fig . 3-21
PROGRAM stats_3
IMPLICIT NONE
INTEGER :: i, n
REAL :: x, x_ave, s , sum_x = 0., sum_x2 = 0.
WRITE(*,*) ‘Enter the number of points n:’
READ(*,*) n
IF ( 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 / n
s = sqrt (( n*sum_x2 – sum_x**2) / (n*(n-1)))
WRITE(*,*) ‘n = ‘ , n, ‘ x_ave = ‘, x_ave, &
‘ s = ‘, s
END IF
END 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_cycle
INTEGER :: i
DO i = 1, 5
IF ( i == 3 ) CYCLE
WRITE(*,*) i
END DO
WRITE(*,*) ‘End of loop!’
END PROGRAM
Output:
1
2
4
5
End of loop!
PROGRAM test_exit
INTEGER :: I
DO i = 1, 5
IF ( i == 3 ) EXIT
WRITE(*,*) i
END DO
WRITE(*,*) ‘End of loop!’
END PROGRAM
Output:
1
2
End of loop!
Sec. 3.4.4 Named Loops
While loop:
[name:] DO
...
IF (logical_expr) CYCLE [name]
...
IF (logical_expr) EXIT [name]
...
END DO [name]
optional
Counting loop:
[name:] DO index = istart, iend, incr
...
IF (logical_expr) CYCLE [name]
...
END DO [name]
optional
Sec. 3.4.5 Nesting Loops and Block IF Construct
e.g.,
PROGRAM nested_loops
INTEGER :: i, j, product
DO i = 1, 3
DO j = 1, 3
product = i * j
WRITE(*,*) i, ‘*’, j, ‘=‘, product
END DO
END DO
END PROGRAM
Output:
1*1=1
1*2=2
1*3=3
2*1=2
2*2=4
2*3=6
3*1=3
3*2=6
3*3=9
PROGRAM test_cycle_1
INTEGER :: i, j, product
DO i = 1, 3
DO j = 1, 3
IF ( j == 2 ) CYCLE
product = i * j
WRITE(*,*) i, ‘*’, j, ‘=‘, product
END DO
END DO
END PROGRAM
Output:
1*1=1
1*3=3
2*1=2
2*3=6
3*1=3
3*3=9
PROGRAM test_cycle_2
INTEGER :: i, j, product
outer: DO i = 1, 3
inner: DO j = 1, 3
IF ( j == 2 ) CYCLE outer
product = i * j
WRITE(*,*) i, ‘*’, j, ‘=‘, product
END DO inner
END DO outer
END PROGRAM
Output:
1*1=1
2*1=2
3*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 inner
END IF outer
illegal!
legal:
outer: IF ( a < b ) THEN
...
inner: DO i = 1, 3
...
END DO inner
...
ELSE
...
END IF outer
Ch. 4 Basic I/O Concepts
READ (*,*)
WRITE (*,*)
Not always convenient!
Not always pretty!
Sec. 4.1 FORMATS and FORMETED WRITE
STATEMENTS
e.g,.
PROGRAM free_format
INTEGER :: i = 21
REAL :: result = 3.141593
WRITE(*,100) i, result
100 FORMAT (‘□The□result□for□iteration□’, &
I3, ‘□is□’, F7.3)
END PROGRAM
∵ F7.3
∵ I3
Output: □The□result□for□iteration□□21□is□□□3.142
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
I6
F10.2
Output: □□□□21□□□□□□3.14
PROGRAM format
INTEGER :: i = 21
REAL :: result = 3.141593
CHARACTER ( len=20 ) :: string
WRITE (*, 100) i, result
100 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
c
d
m
r
w
meaning
column number
# of digits to the right of the decimal point
min. # of digit
repeat count
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)
I5
I5
I6
I10
Output:
□□-12□□□□0□□□□□4□□□□-12345
□□-12□□□□□□□□□□4□-00012345
□-012□□000□□□□4*****
(Not in scale!)
PROGRAM iformat
IMPLICIT NONE
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)
220FORMAT (2I5.3, I6, I5)
END PROGRAM
Output:
-12
0
-12
-012 000
4
-12345
4 -00012345
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)
F6.3
F6.3
F8.3
(Not in scale!)
Output: ******□0.123□123.456
□□□□-12.30□□□□□□0.12□□□□123.46
F10.2
F10.2
F10.2
PROGRAM rformat
IMPLICIT NONE
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)
END PROGRAM
Output: ****** 0.123 123.456
-12.30
0.12
(Not in scale!)
123.46
Sec. 4.3.3 Real Output – The E Descriptor
Scientific notation: 6.02 ×
(Expomential notation)
1023
Exponential notation: 0.602 × 1024
(E Descriptor)
0.602 E+24
(∵‘E+**’ , ‘0.’, and ‘-’)
rFw.d ( w≧ d + 7 )
e.g.,
REAL :: a = 1.2346E6, b = 0.001, c = -77.7E10, d = -77.7E10
WRITE (*,200) a, b, c, d
200 FORMAT (2E14.4, E13.6, E11.6)
Output:
E14.4
E14.4
E13.6
(∵ 11 < 6 + 7)
E11.6
□□□□0.1235E+07□□□□0.1000E-02-0.777000E+12***********
PROGRAM routput
IMPLICIT NONE
REAL :: a = 1.2346E6, b = 0.001, c = -77.7E10, d = -77.7E10
WRITE (*, 200) a, b, c, d
200 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.7E10
WRITE (*,200) a, b, c
200 FORMAT (2ES14.4, ES12.6)
Output:
ES14.4
ES14.4
ES12.6
□□□□1.2346E+06□□□□1.0000E-03************
PROGRAM esformat
IMPLICIT NONE
REAL :: a = 1.2346E6, b = 0.001, c = -77.7E10
WRITE (*, 200) a, b, c
200 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, debug
200 FORMAT (2L5)
Output:
L5
L5
□□□□T□□□□F
PROGRAM loutput
IMPLICIT NONE
LOGICAL :: output = .TRUE., debug = .FALSE.
WRITE (*, 200) output, debug
200 FORMAT (2L5)
END PROGRAM
Sec. 4.3.6 Character Output – The A Descriptor
rAw or rA
(i.e., the width is the same as the # of
characters being displayed.)
e.g.,
CHARACTER (len = 17) :: string = ‘This□is□a□string.’
WRITE (*, 10) string
WRITE (*, 11) string
17 characters
WRITE (*, 12) string
10 FORMAT (A)
11 FORMAT (A20)
12 FORMAT (A6)
Output:
This□is□a□string.
□□□This□is□a□string.
This□i
PROGRAM aoutput
IMPLICIT NONE
CHARACTER (len = 17) :: string = 'This is a string.‘
WRITE (*, 10) string
WRITE (*, 11) string
WRITE (*, 12) string
10 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 = 92
WRITE(*,100) first_name, initial, last_name, grade, class
100 FORMAT (A10, 1X, A1, 1X, A10, 4X, I3, T51, A9)
Output:
A10
1X A1 1X
A10
4X
I3
A9
James□□□□□□R□Johnson□□□□□□□□92 . . . COSC□2301
(51th column, ∵T51)
or
CHARACTER (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, class, grade
100 FORMAT (A10, T13, A1, T15, A10, T51, A9, T29, I3)
Output:
A1
A10
A10
I3
A9
James□□□□□□□R□Johnson□□□□□□□□92 . . . COSC□2301
(51th column, ∵T51)
(15th column, ∵T15)
(13th column, ∵T13)
(29th column, ∵T29)
or
CHARACTER (len = 10) :: first_name = ‘James□’
CHARACTER :: initial = ‘R’
CHARACTER (len = 16) :: last_name = ‘Johnson□’
CAHRACTER (len = 9) :: class = ‘COSC□2301’
INTEGER :: grade = 92
WRITE(*,100) first_name, initial, last_name, class, grade
100 FORMAT (A10, T13, A1, T15, A10, T17, A9, T29, I3)
Output:
A1
A10
A10
I3
James□□□□□□□R□JoCOSC□2301□□□□92
(17th column, ∵T17)
(15th column, ∵T15)
(13th column, ∵T13)
(29th column, ∵T29)
PROGRAM tformat
CHARACTER (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, class
WRITE(*,110) first_name, initial, last_name, class, grade
WRITE(*,120) first_name, initial, last_name, class, grade
100 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, phase
100 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 . . .
(skip 2 lines)
Time = . . .
Depth = . . .
Amplitude = . . .
Phase = . . .
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
====== ==========
1
1.000000
2
1.414214
...
...
9
3.000000
10
3.162278
Square
======
1
4
...
81
100
Cube
====
1
8
...
729
1000
PROGRAM table
IMPLICIT NONE
INTEGER :: i, square, cube
REAL :: 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 DO
END PROGRAM
Sec. 4.4 Formatted READ Statements
e.g.,
READ (*,100) increment
100 FORMAT (6X, I6)
(col. 7~12: an integer)
(skip the 1st six column)
Sec. 4.4.1 Integer Input – The I Descriptor
rIw
e.g.,
READ(*, 100) a, b, c
100 FORMAT(3I5)
Input:
I5
I5
I5
□□□15□□15□□15□□
a = 15
b = 15
c = 15
PROGRAM iinput
IMPLICIT NONE
INTEGER :: a, b, c
READ(*, 100) a, b, c
100 FORMAT(3I5)
WRITE(*,*) 'a= ', a
WRITE(*,*) 'b= ', b
WRITE(*,*) 'c= ', c
END PROGRAM
Sec. 4.4.2 Real Input – The F Descriptor
rFw.d
e.g.,
READ (*, ‘(3F10.4)’ ) a, b, c
Input:
F10.4
F10.4
F10.4
1.5□□□□□□□□0.15E+01□□□15.0E-01
a = 1.5
b = 1.5
c = 1.5
PROGRAM rinput
IMPLICIT NONE
REAL :: a, b, c
READ (*, '(3F10.4)' ) a, b, c
WRITE(*,*) 'a= ', a
WRITE(*,*) 'b= ', b
WRITE(*,*) '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.,
Input:
READ (*, ‘(3F10.4)’ ) a, b, c
F10.4
F10.4
F10.4
□□□□□□□□15□□□150□□□□□□15000□□□
a = 0.0015
b = 0.0150
c = 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:
L5
L5
L5
□□□□T□□□□F□□□□T
(or T□□□□F□□□□T□□□□ )
a= T
b= F
c= T
PROGRAM linput
IMPLICIT NONE
LOGICAL :: a, b, c
READ (*, '(3L5)' ) a, b, c
WRITE(*,*) 'a= ', a
WRITE(*,*) 'b= ', b
WRITE(*,*) 'c= ', c
END PROGRAM
Sec. 4.4.4 Character Input – The A Descriptor
rA or rAw
e.g.,
Input:
CHARACTER (len=10) :: string_1, string_2
CHARACTER (len=5) :: string_3
CHARACTER (len=15) :: string_4, string_5
READ (*, ‘(A)’ ) string_1
READ (*, ‘(A10)’ ) string_2
READ (*, ‘(A10)’ ) string_3
READ (*, ‘(A10)’ ) string_4
READ (*, ‘(A)’ ) string_5
ABCDEFGHIJKLMNO
ABCDEFGHIJKLMNO
ABCDEFGHIJKLMNO
ABCDEFGHIJKLMNO
ABCDEFGHIJKLMNO
String_1 = ‘ABCDEFGHIJ’
String_2 = ‘ABCDEFGHIJ’
String_3 = ‘FGHIJ’
String_4 = ‘ABCDEFGHIJ □□□□□’
String_5 = ‘ABCDEFGHIJKLMNO’
PROGRAM ainput
IMPLICIT NONE
CHARACTER (len=10) :: string_1, string_2
CHARACTER (len=5) :: string_3
CHARACTER (len=15) :: string_4, string_5
READ (*, '(A)' ) string_1
READ (*, '(A10)' ) string_2
READ (*, '(A10)' ) string_3
READ (*, '(A10)' ) string_4
READ (*, '(A)' ) string_5
WRITE(*,*)string_1
WRITE(*,*)string_2
WRITE(*,*)string_3
WRITE(*,*)string_4
WRITE(*,*)string_5
END PROGRAM
Sec. 4.4.5 Horizontal Positioning – The X and
T Descriptor
e.g.,
CHARACTER (len=6) :: string
INTEGER :: i
READ (*, ‘(I6, T1, A6)’ ) i, string
Input:
123456
i = 123456
string = ‘123456’
PROGRAM hposition
IMPLICIT NONE
CHARACTER (len=6) :: string
INTEGER :: i
READ (*, '(I6, T1, A6)' ) i, string
WRITE(*,'(I6)') i
WRITE(*,'(A)') string
END PROGRAM
Sec. 4.4.6 Vertical Positioning – The Slash (/) Descriptor
e.g.,
REAL :: a, b, c, d
READ (*, 300) a, b, c, d
300 FORMAT (2F10.2, //, 2F10.2)
Input:
F10.2
F10.2
F10.2
□□□□□□□1.0□□□□□□□2.0□□□□□□□3.0
□□□□□□□4.0□□□□□□□5.0□□□□□□□6.0
□□□□□□□7.0□□□□□□□8.0□□□□□□□9.0
a = 1.0
b = 2.0
c = 7.0
d = 8.0
PROGRAM vposition
IMPLICIT NONE
REAL :: a, b, c, d
READ (*, 300) a, b, c, d
300 FORMAT (2F10.2, //, 2F10.2)
WRITE(*,*)'a= ',a
WRITE(*,*)'b= ',b
WRITE(*,*)'c= ',c
WRITE(*,*)'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 :: ierror
OPEN ( UNIT = 8, FILE = ‘INPUT.DAT’, &
STATUS = ‘OLD’, ACTION = ‘READ’, &
IOSTAT = ierror)
Example 2 (Opening a file for output)
INTEGER :: ierror
OPEN ( UNIT = 25, FILE = ‘OUTPUT.DAT, &
STATUS = ‘NEW’, ACTION = ‘WRITE’, &
IOSTAT = ierror)
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, z
100 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,
If the READ statement is fail,
ierror = 0.
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.
Fig 4-8 (Flowchart)
Initial values:
Start
nvals = 0
1
READ value
READ filename
OPEN filename
ierror2 = 0
?
ierror1 = 0
?
.TRUE.
.FALSE.
.TRUE.
1
nvals = nvals +1
.FALSE.
.TRUE.
WRITE ‘Error
reading line’
WRITE
nvals, value
WRITE ‘Error
opening file’
WRITE
‘End of
file’
2
Stop
ierror2 > 0
?
.FALSE.
2
PROGRAM read
IMPLICIT NONE
CAHRACTER (len = 20) :: filename
INTEGER :: nvals = 0
INTEGER :: ierror1, ierror2
REAL :: value
WRITE(*,*) ‘Please enter input file name:’
READ (*,*) filename
OPEN (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 readif
ELSE openif
WRITE(*, 1040) ierror1
1040 FORMAT (‘Error opening file: IOSTST=‘, I6)
END IF openif
CLOSE(3)
END PROGRAM
Test the program:
(1) The valid input file READ1.TXT: (e.g., use Notepad)
-17.0
30.001
1.0
12000.
-0.012
Output:
Please enter input file name:
READ1.TXT
Line
1: value =
-17.0000
Line
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.0
30.001
ABCDEF
12000.
-0.012
Output:
Please enter input file name:
READ2.TXT
Line
1: value = -17.0000
Line
2: value = 30.0000
Error reading Line
3
(3) A file does not exist:
Output:
Please enter input file name:
JUNK.DAT
Error opening file: IOSTAT =
128
(depends on machine)
Sec. 4.5.4 File Positioning
BACKSPACE ( UNIT = a unit # )
and
REWIND ( UNIT = a unit #)
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 scratch
IMPLICIT NONE
INTEGER, PARAMETER :: unit = 8
REAL :: data
INTEGER :: 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) icount
130 FORMAT (1X, ‘Which record do you want to see ( 1 to’, I4, ‘)? ’)
READ (*,*) irec
IF ( ( 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 IF
END PROGRAM
Output:
Enter positive or zero input values.
A negative input value terminates input.
Enter sample 1:
234.
Enter sample 2:
12.34
Enter sample 3:
0.
Enter sample 4:
16.
Enter sample 5:
11.235
Enter sample 6:
2.
Enter sample 7:
-1.
Which recore do you want to see ( 1 to 6)?
5
The 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:
y
(x4, y4)
(x2, y2)
The best fit:
y = mx + b
(x3 , y3)
(x1 , y1)
x
m=?
b=?
The method of least squares:
m=
N
N
i=1
i=1
(Σxi yi ) - (Σxi ) y
N
(Σxi2
i=1
N
) - (Σxi ) x
i=1
where
N
N
y=
Σyi
i=1
and
N
b=y–mx
x=
Σxi
i=1
N
PROGRAM least_squares_fit
IMPLICIT NONE
INTEGER, PARAMETER :: unit = 18
CHARACTER (len = 24) :: filename
INTEGER :: ierror, n = 0
REAL :: m, b
REAL :: 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)’) filename
OPEN (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
2.2
3.3
4.4
5.5
6.6
7.7
1.1
2.2
3.3
4.4
5.5
6.6
7.7
Output:
m = 1.000
b = 0.000
N=7
(2) The input file INPUT1.TXT:
1.1
2.2
3.3
4.4
5.5
6.6
7.7
1.01
2.30
3.05
4.24
5.75
6.48
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)
...
e.g.,
array a
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.
• Shape: the combination of rank and extent in each dimension
e.g.,
The shape of sum = 3 6
• Size: the # of elements
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) :: index
LOGICAL, DIMENSION (2) :: lval
REAL, DIMENSION (3) :: temp
Index(1) = 1
Lval(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) :: j
WRITE(*,*) ‘ j(1)=‘, j(1)
uninitialized
array
?
• Initialization arrays with assignment statements:
e.g.,
REAL, DIMENDION (10) :: array1
DO i = 1, 10
array1(i) = 0.0
END DO
or
REAL, DIMENDION (10) :: array1
array1 = (/ 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
INTEGER, DIMENDION (5) :: array2 = (/ ( i, i = 1, 5) /)
or
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
REAL, DIMENDION (100) :: array5 = 1.
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.,
4
c = Σ an = a0 + a1 + a2 + a3 + a4
n=0
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)
or
(5 elements)
REAL, DIMENSION (5:9) :: c
c(5), c(6), c(7), c(8), c(9)
(5 elements)
Example (Fig. 5-4)
i
-5
-4
…
+4
+5
i2
25
16
…
16
25
PROGRAM squares_2
IMPLICIT NONE
INTEGER :: I
INTEGER, 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 DO
END 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 = 1000
REAL, DIMENSION (isize) :: array1
REAL, DIMENSION (isize) :: array2
REAL, DIMENSION (2*isize) :: array3
Example 5-1 (Finding the largest and smallest values in a data set)
PROGRAM extremes
IMPLICIT NONE
INTEGER, PARAMETER :: max_size = 10
INTEGER, DIMENSION (max_size) :: input
INTEGER :: ilarge, ismall, j, nvals, temp
WRITE(*,*) ' Enter number of values in data set:'
READ(*,*) nvals
size: 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
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 out
ELSE size
WRITE(*, 120) nvals, max_size
120 FORMAT(1X, ' Too many input values: ', I6, '>', I6)
END IF size
END PROGRAM
Test:
Enter number of values in data set:
6
Enter value 1:
-6
Enter value 2:
Output
5
Enter value 3:
-11
Enter value 4:
16
Enter value 5:
9
Enter value 6:
0
The values are:
-6
5
-11 SMALLEST
16
LARGEST
9
0
Sec. 5.3
Using Whole Arrays and Array Subsets
in Fortran Statements
Sec. 5.3.1 Whole Array Operations
e.g.,
a(1)
1.
b(1)
5.
6.
a(2)
2.
b(2)
6.
8.
a(3)
3.
b(3)
10.
a(4)
4.
7.
8.
b
c
a
+
b(4)
=
12.
Fig. 5-6
PROGRAM add_arrays
IMPLICIT NONE
INTEGER :: I
REAL, 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 DO
d=a+b
WRITE(*, 100) ‘c’, c
WRITE(*, 100) ‘d’, d
100 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) :: c
c=a+b
or
REAL, DIMENSION(4) :: a = (/ 1., 2., 3., 4. /)
REAL :: b = 10
REAL, DIMENSION(4) :: c
c=a*b
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. /), y
INTEGER :: i
DO i = 1, 4
or use y = SIN(x)
y(i) = SIN(x(i))
END DO
or
REAL, DIMENSION(4) :: a = (/ -1., 2., -3., 4. /), y
y = ABS(a)
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 = 1
to the last subscript
to the 1st subscript
Example 5-5
INTEGER :: i = 3, j = 7
REAL, 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:
e.g.,
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(6) a(4) a(1) a(9)
*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) :: b
b(vec) = a (Incorrect!)
Sec. 5.4
Input and Output
Just like any other variables.
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)
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_io
IMPLICIT NONE
REAL, DIMENSION(5) :: a = (/ 1., 2., 3., 20., 10. /)
INTEGER, DIMENSION(4) :: vec = (/ 4, 3, 4, 5 /)
WRITE(*, 100) a
100 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.000
20.000 3.000 20.000 10.000
Sec. 5.5
Examples
Example 5-3
Sorting Data
Ascending order (the lowest to the highest)
or
Descending order (the highest to the lowest)
e.g.,
(sorting)
(10, 3, 6, 4, 9)
(3, 4, 6, 9, 10)
Fig. 5-10
(selection sort)
(no swap)
10
(swap)
3
3
10
6
6
(swap)
3
3
3
4
4
4
6
6
6
(swap)
4
4
10
10
9
9
9
9
9
10
Steps:
1.
2.
3.
4.
5.
Get the input filename
Open the input file
Read the input data into an array
Sort the data in ascending order
Write the sorted data
Fig. 5-13
PROGRAM sort1
IMPLICIT NONE
INTEGER, PARAMETER :: max_size = 10
REAL, DIMENSION (max_size) :: a
CHARACTER (len = 20) :: filename
INTEGER :: i, iptr, j, status
INTEGER :: nvals = 0
REAL :: temp
WRITE(*, 1000)
1000 FORMAT (1X, ‘ Enter the file name’)
READ(*, ‘(A20)’) filename
OPEN (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 fileopen
WRITE(*, 1050)status
1050 FORMAT (1X, ‘File open failed: ’, I6)
END IF fileopen
END PROGRAM
Test:
INPUT2.TXT
13.3
12.
-3.0
0.
4.0
6.6
4.
-6.
output
Enter the file name
INPUT2.TXT
The sorted data are:
-6.0000
-3.0000
0.0000
4.0000
6.6000
12.0000
13.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-dim array
(b) 2-dim array
row 1
a(1)
row 1
b(1,1) b(1,2) b(1,3)
row 2
a(2)
row 2
b(2,1) b(2,2) b(2,3)
row 3
a(3)
row 4
a(4)
a(irow)
col 1
col 2
col 3
b(irow, icol))
Sec. 5.6.1
Declaring Rank-2 Arrays
e.g.,
REAL, DIMENSION(3,6) :: sum
INTEGER, 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,1) a(2,2) a(2,3)
a(1,1)
a(2,1)
a(1,2)
a(2,2)
column
major order
a(1,3)
a(irow, icol)
a(2,3)
(Memory allocation)
Sec. 5.6.3
Initializing Rank-2 Array
1. Use assignment statements
e.g.,
1
2
3
1
2
3
1
2
3
1
2
3
use
INTEGER, DIMENSION(4,3) :: istat
DO i = 1, 4
DO j = 1, 3
istat(i, j) = j
END DO
END DO
or
DO j = 1, 3
istat(:, j) = j
END 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) :: istat
OPEN(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 = 2) (i = 3) (i = 4)
Sec. 5.6.4
Examples
Examples 5-5
power =
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
use
REAL,DIMENSION(6,4) :: power
…
OPEN(9, FILE = ‘INPUT1’, STATUS = ‘OLD’, &
ACTION = ‘READ’)
READ (9, *) power
INPUT1:
20.0
40.3
42.0
20.4
19.8
40.1
41.5
26.9
20.1
40.0
41.3
38.4
20.0
39.5
41.1
42.0
20.0 19.9
39.9 40.0
39.8 41.0
12.2 6.0
or
OPEN(9, FILE = ‘INPUT2’, STATUS = ‘OLD’, &
ACTION = ‘READ’)
READ (9, *) ((power(i, j), j = 1, 4), i = 1, 6)
INPUT2:
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
Sec. 5.6.5 Whole Array Operation and Array Subsets
e.g.,
a=
1
6
11
16
21
2 3 4 5
7 8 9 10
12 13 14 15
17 18 19 20
22 23 24 25
a(:, 1) =
1
6
11
16
21
a(1:3, 1:5:2) =
a(1, :) = [ 1 2 3 4 5 ]
1 3 5
6 8 10
11 13 15
Sec. 5.7 Multidimensional or Rank-n Array
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)
(up to 7)
Sec. 5.8 Using Fortran Intrinsic Functions with Arrays
Sec. 5.8.1 Elemental Intrinsic Functions
ABS, SIN, COS, TAN, EXP, LOG, LOG10, MOD, AND SQRT.
e.g.,
REAL, DIMENSION :: x = (/ 10., 3.14, 1., 2. /), y
INTEGER :: i
DO i = 1, 4
equiv.
y(i) = sin(x(i))
y = sin(x)
END DO
Sec. 5.8.2 Inquiry Intrinsic Functions
Table 5-1
LBOUND (ARRAY, DIM)
SHAPE (SOURCE)
(a particular dimension, e.g., 1 or 2)
SIZE(ARRAY, DIM)
UBOUND (ARRAY, DIM)
Example 5-6 (Determining the Properties of an Array)
PROGRAM check_array
REAL, 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
Construct
e.g.,
DO i = 1, ndim1
DO j = 1, ndim2
logical(i, j) = LOG (value(i, j))
END DO
END 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 DO
END DO
equiv.
WHERE (value > 0.)
logval = LOG(value)
ELSEWHERE
logical = -99999.
END WHERE
The general form:
[name:] WHERE (mask_expr)
Array Assignment Statements
ELSEWHERE [name:]
Array Assignment Statements
END WHERE [name:]
Example 5-7
! Block1
! Block2
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.)