8/8/2019 Basic Comphy Ch3
1/38
1
Ch. 3 Fortran 90: Selective & Repetitiveexecutions
References:
1. T.M.R. Ellis et al., Fortran 90 programming, Chs. 5, 6
2. L. Nyhoff & S. Leestma, Introduction to FORTRAN 90, Ch. 3, 4
8/8/2019 Basic Comphy Ch3
2/38
2
Outline
3.1 Selective execution
3.2 Repetitive execution
8/8/2019 Basic Comphy Ch3
3/38
3
3.1 Selective execution
Decision-making
How would I spend this Sunday?
Ifmy wife and son don't complaint, thenI will go back to office alone :-)
but ifthey complaint, thenI will stay home :-( [....what next is usually not my decision!]
but ifonly my son complaints, thenI will ask whether he wants to go with me:
Ifyes, thenI will go back to office with my son :-|
Ifno, thenI will stay home :-( [...what next is usually not my decision!]
but ifonly my wife complaints, then I will ask whether she wants to go with me: Ifyes, thenI will go back to office with my wife and son :-|
Ifno, thenI will go back to office alone anyway ;-)
8/8/2019 Basic Comphy Ch3
4/38
4
Logical expressions
* We see in the previous example that each decision depends upon whethersome criterion is true or false.
* An expression which can take one of these two values (true or false) is called a logicalexpression.
Logical values
Example: x < 3 is a logical expression
ifx = 2, the logical expression x < 3 is true.
ifx = 4, the logical expression x < 3 is false.
relational operator
* In Fortran, the logical values are given by:
.TRUE..FALSE.
8/8/2019 Basic Comphy Ch3
5/38
5
* Fortran provides the following 6 relational operators:
Symbol Meaning
< or .LT. Is less than
> or .GT. Is greater than
== or .EQ. Is equal to
= or .GE. Is greater than or equal to
/= or .NE. Is not equal to
expression1 relational-operator expression
2Usage:
* expression1
& expression2
must be both arithmetic or both be strings
* All arithmetic operators have a higher priority than any relational operator
All relational operatorshave equal priority
8/8/2019 Basic Comphy Ch3
6/38
6
Example: For the expression b**2 >= 4*a*c ,
b**2 and 4*a*c are evaluated before >= is evaluated
Example: The following expressions give the same results
b**2 >= 4*a*cb**2 4*a*c >= 0
4*a*c = 4*a*c ) is .FALSE.
Remark: The 6 relational operators can also be used to compare character strings.But we shall not discuss this issue.(see, e.g., Sec. 5.5 of Ellis et al.)
8/8/2019 Basic Comphy Ch3
7/38
7
Question: How to represent the comparisonsx
8/8/2019 Basic Comphy Ch3
8/38
8
* Let p and q be logical expressions, the logical operators are defined by :
p .NOT. p
.TRUE. .FALSE.
.FALSE. .TRUE.
p q p .AND. q p .OR. q p .EQV. q p .NEQV. q
.TRUE. .TRUE. .TRUE. .TRUE. .TRUE. .FALSE.
.TRUE. .FALSE. .FALSE. .TRUE. .FALSE. .TRUE.
.FALSE. .TRUE. .FALSE. .TRUE. .FALSE. .TRUE.
.FALSE. .FALSE. .FALSE. .FALSE. .TRUE. .FALSE.
Priority order:
1. Arithmetic operations (and functions)2. Relational operations3. Logical operations in the order .NOT., .AND., .OR., .EQV. (or .NEQV.)
Usage: expression1 logical-operator expression
2
* expression1
& expression2
are logical expressions
8/8/2019 Basic Comphy Ch3
9/38
9
Example: ifN = 4, what is the logical value of the following logical expression?
(N**2 + 1 > 10) .AND. .NOT. (N < 3)
.TRUE.
.FALSE.
.TRUE.
=> The logical value of the entire expression is .TRUE.
Example: The following 2 expressions are equivalent in their effect
.NOT. (a < b .AND. b < c)
a >= b .OR. b >= c
8/8/2019 Basic Comphy Ch3
10/38
10
Classwork 1
8/8/2019 Basic Comphy Ch3
11/38
11
The block IF construct
block IF constructIF (logical-expression) THEN
statement-sequence
END IF
Example:
IF ( b**2 > 4*a*c ) THEN
PRINT *, ' There are two real roots '
END IF
IF ( b**2 == 4*a*c ) THEN
PRINT *, ' There is one (repeated) root '
END IF
IF ( b**2 < 4*a*c ) THEN
PRINT *, ' There is no real root '
END IF
8/8/2019 Basic Comphy Ch3
12/38
12
IF-ELSE IF construct
IF (logical-expression1) THEN
statement-sequence1
ELSE IF (logical-expression2) THEN
statement-sequence2
ELSE IF (logical-expression3) THEN
.
.
.
ELSE
END IF
Example: IF ( b**2 > 4*a*c ) THEN
PRINT *, ' There are two real roots '
ELSE IF ( b**2 == 4*a*c ) THEN
PRINT *, ' There is one (repeated) root '
ELSE
PRINT *, ' There is no real root '
ENDIF
8/8/2019 Basic Comphy Ch3
13/38
13
Example: (Quadratic equation)
PROGRAM Quadratic
IMPLICIT NONE
REAL :: a, b, c, Delta, root_1, root_2
PRINT *, 'Enter the coefficients a, b, c'
READ(*,*) a, b, c
Delta = b**2 - 4*a*c
IF ( Delta > 0.0 ) THEN
Delta = SQRT(Delta)
root_1 = ( -b + Delta ) / (2.0*a)
root_2 = ( -b - Delta ) / (2.0*a)
PRINT *, ' Two real roots = ', root_1, root_2
ELSE IF ( Delta == 0.0 ) THEN
root_1 = - b / (2.0*a)
PRINT *, ' One repeated root = ', root_1
ELSE
PRINT *, ' No real root '
END IF
END PROGRAM Quadratic
This line can also be written asELSE IF(Delta < 0.0 ) THEN
8/8/2019 Basic Comphy Ch3
14/38
14
What happens if a = 0.0?
Enter the coefficients a, b, c
0.0, 2.0, 1.0
Two real roots = NaN -Infinity
My input
(Not aNumber)
* We can modify the code by
....
....
....
PRINT *, 'Enter the coefficients a, b, c'
READ(*,*) a, b, c
IF ( a == 0.0 ) THEN
PRINT *, ' the coefficient a should not be zero! '
STOPEND IF
...
...
...
This terminates the execution of the program immediately
8/8/2019 Basic Comphy Ch3
15/38
15
Remark: Consider the following part of the code
ELSE IF (Delta == 0.0 ) THEN
root_1 = - b / (2.0*a)
PRINT *, ' One repeated root = ', root_1
Remember that real arithmetic is only an approximation.=> two numbers which are mathematically equal will often
differ very slightly in numerical calculations
Hence, we should not compare two real numbers for equality.
* A better way to write the above part of the code is:
ELSE IF ( ABS(Delta) < epsilon ) THEN
....
....
where the parameter epsilon is a very small number (eg, 1.E-8) defined by the user:
REAL, PARAMETER :: epsilon = 1.E-8
8/8/2019 Basic Comphy Ch3
16/38
16
Logical IF statement
IF (logical-expression) Fortran-statement
* This is equivalent to the following simplest block IF construct:
Only one statement
IF (logical-expression) THEN
Fortran-statement
END IF
Example:PROGRAM Absolute
IMPLICIT NONE
REAL :: x, abs_x
PRINT *, ' Input a number x'
READ(*,*) x
abs_x = x
IF (x < 0.0) abs_x = x
PRINT *, '|x| = ', abs_x
END PROGRAM Absolute
IF (x < 0.0) THEN
abs_x = x
END IF
A 'shorthand' version of
8/8/2019 Basic Comphy Ch3
17/38
17
LOGICAL variables
* We have two logical values: .TRUE. & .FALSE.
* We can declare LOGICAL variables to store these values:
LOGICAL :: var_1, var_2, var_3,....
Example: Let us illustrate how to use the various concepts together by writing a Fortran codeto decide what should I do on Sunday.
LOGICAL :: wife_complaint, son_complaint
LOGICAL :: wife_go, son_go
First, we need to define some logical variables:
wife_complaint = .TRUE. (if my wife complaints) = .FLASE. (if my wife doesn't complaint)
wife_go = .TRUE. (if my wife agrees to go to my office)
= .FALSE. (if my wife doesn't want to go to my office)
Similar meanings apply to son_complaint & son_go
Meaning:
8/8/2019 Basic Comphy Ch3
18/38
18
PROGRAM My_Sunday
IMPLICIT NONE
LOGICAL :: wife_complaint, son_complaint
LOGICAL :: wife_go, son_go
PRINT *, 'Input the logical values of wife_complaint, son_complaint'
READ(*,*) wife_complaint, son_complaint
IF (wife_complaint .AND. son_complaint ) THENPRINT *, ' Stay home :-( '
ELSE IF ( .NOT. wife_complaint ) THEN
IF (son_complaint) THEN
PRINT *, ' Input the logical value of son_go '
READ(*,*) son_go
IF (son_go) PRINT *, ' Take him to office :-| '
IF (.NOT. son_go) PRINT *, ' Stay home :-( ' ELSE
PRINT *, ' Go to office alone :-) '
ENDIF
ELSE IF ( .NOT. son_complaint ) THEN
IF (wife_complaint) THEN
PRINT *, ' Input the logical value of wife_go '
READ(*,*) wife_go
IF (wife_go) PRINT *, ' Take them to office :-| '
IF (.NOT. wife_go) PRINT *, 'Go to office alone ;-) '
ELSE
PRINT *, ' Go to office alone :-) '
ENDIF
ENDIF
END PROGRAM My_Sunday
Nested IF:
block IF constructs
inside another blockIF construct
8/8/2019 Basic Comphy Ch3
19/38
19
Sample runs of the program My_Sunday:
Input the logical values of wife_complaint, son_complaint
.TRUE., .TRUE.
Stay home :-(
Input the logical values of wife_complaint, son_complaint
.FALSE., .TRUE.
Input the logical value of son_go
.FALSE.
Stay home :-(
Input the logical values of wife_complaint, son_complaint
.TRUE., .FALSE.
Input the logical value of wife_go
.FALSE.
Go to office alone ;-)
8/8/2019 Basic Comphy Ch3
20/38
20
Classwork 2
8/8/2019 Basic Comphy Ch3
21/38
21
The CASE construct
* Besides the block IF construct, Fortran 90 provides another form of selective execution
statement:
SELECT CASE (case-expression)
CASE (case_selector1)
statement-sequence1
CASE (case_selector2)
statement-sequence2
CASE (case_selector3)
.
.
.
CASE DEFAULT
statement-defaultEND SELECT
CASE construct
may be integer expression,character expression orlogical expression(BUT not real expression)
This part is optional
* The case construct can deal with the alternative situation in which the variousalternatives are mutually exclusive (and the order is unimportant)
8/8/2019 Basic Comphy Ch3
22/38
22
* case_selector can take the following forms:
case_value
low_value:
:high_value
low_value:high_value
1. case_value the statement-sequence is executed iff
case_expression == case_value (when case_expression is an
integer expression)
case_expression .EQV. case_value (when case_expression is alogical expression)
2. low_value: the statement-sequence is executed iff
low_value
8/8/2019 Basic Comphy Ch3
23/38
23
Example: (This program determines in which season a specified date lies)
PROGRAM Seasons
IMPLICIT NONE
CHARACTER(LEN=10) :: date
CHARACTER(LEN=2) :: month
PRINT *, 'Type a date in the form yyyy-mm-dd'
READ(*,*) date
month = date(6:7)
SELECT CASE (month)
CASE ("03":"05")
PRINT *, date, ' is in the spring'
CASE ("06":"08")
PRINT *, date, ' is in the summer'
CASE("09":"11")
PRINT *, date, ' is in the autumn'
CASE("12","01","02")
PRINT *, date, ' is in the winter'
CASE DEFAULT
PRINT *, date, ' is not a valid date'
END SELECT
END PROGRAM Seasons
recall: substring (Ch. 2)
CASE (03,04,05)
can also be written as
E l (Q d i b )
8/8/2019 Basic Comphy Ch3
24/38
24
PROGRAM Quadratic_case
IMPLICIT NONE
REAL :: a, b, c, Delta
INTEGER :: selector
REAL, PARAMETER :: epsilon = 1.E-8
PRINT *, 'Enter the coefficients a, b, c'
READ(*,*) a, b, c
Delta = b**2 - 4*a*c
selector = Delta / epsilon
SELECT CASE (selector)
CASE (1:)
PRINT *, ' Two real roots '
CASE (0)
PRINT *, 'One (repeated) root 'CASE (:-1)
PRINT *, 'No real root'
END SELECT
END PROGRAM Quadratic_case
Example: (Quadratic by CASE)
The result will be truncated to aninteger(Note: it is usually a bad idea to
divide by a very small number)
If|Delta| < epsilon, then
their ratio will be between -1 & +1=> selector = 0
(selector is an integer)
3 2 Repetitive execution
8/8/2019 Basic Comphy Ch3
25/38
25
3.2 Repetitive execution
Program repetition
* In numerical calculations, it is often required to carry out the same, or similar,actions repeatedly (Repetitive execution).
* Two basic types of repetition:
1. Repetition controlled by a counter
(ie, repeat sequences of statements a predetermined number of times)
2. Repetition controlled by a logical expression(ie, repeat sequences of statements until some condition is satisfied)
Examples:
1. Calculate 1 + 2 + 3 + ......+ 98 + 99 + 100.
2. Calculate 1 + 2 + 3 +...... until the sum is larger than 50.
The block DO construct
8/8/2019 Basic Comphy Ch3
26/38
26
The block DO construct
Count-controlledDO loop
DO count = initial, final, step
.
.
block-of-statements
.
.
END DO
INTEGER :: sum, i
sum = 0
DO i=1,100, 1
sum = sum + i
END DO
PRINT *, 'sum = ', sum
Example:
count = integer variable
initial = initial value (integer expression)final = final value (integer expression)
step = step size (integer expression & cannot be 0)
step is optional. The default
value is1
.This line can also be written asDO i=1,100
Note: It is not permitted to
change these variablesinside the DO loop
8/8/2019 Basic Comphy Ch3
27/38
27
Examples:
DO statement Iteration count DO variable values
DO j=20,50,5 7 20,25,30,35,40,45,50
DO p=7,19,4 4 7,11,15,19
DO p=7,19,5 3 7,12,17
DO q=4,5,6 1 4
DO x=-20,20,6 7 -20,-14,-8,-2,4,10,16
DO m=20,-20,-6 7 20,14,8,2,-4,-10,-16
step < 0 (ie, counting down)
Example: (Nested DO loop)
8/8/2019 Basic Comphy Ch3
28/38
28
Example: (Nested DO loop)
PROGRAM Multiplication_table
IMPLICIT NONEINTEGER :: i, j
OPEN(UNIT=15, FILE='multi_table.dat', STATUS='UNKNOWN')
DO i=1,10
WRITE(15,*), ' '
WRITE(15,*), i, ' times tables '
DO j=1,10
WRITE(15,*), i, ' times ', j, ' is ', i*j
END DO
END DO
CLOSE (15)
END PROGRAM Multiplication_table
* This program print a set of multiplication tables from 1 to 10
a Do loop inside another Do loop
Output file
8/8/2019 Basic Comphy Ch3
29/38
29
.
.
1 times 8 is 8
1 times 9 is 91 times 10 is 10
2 times tables
2 times 1 is 2
2 times 2 is 4
2 times 3 is 6
2 times 4 is 8
2 times 5 is 10
2 times 6 is 12
2 times 7 is 14
2 times 8 is 16
2 times 9 is 18
2 times 10 is 20
3 times tables
3 times 1 is 3
3 times 2 is 6
3 times 3 is 9
.
.
Part of the results produced by the program Multiplication_table :
8/8/2019 Basic Comphy Ch3
30/38
30
Classwork 3
Example: (Read data file)
8/8/2019 Basic Comphy Ch3
31/38
31
Example: (Read data file)
PROGRAM Read_data
IMPLICIT NONE
INTEGER :: i, N
REAL :: t, v
OPEN(UNIT=10, FILE='expt.dat', STATUS='OLD')
OPEN(UNIT=15, FILE='log_v.dat',STATUS='UNKNOWN')
N = 10
DO i = 1, N
READ(10,*) t, v
WRITE(15,*) t, LOG(v)
END DO
CLOSE (10)
CLOSE (15)
END PROGRAM Read_data
Number of data
Read dataOutput data
File: expt.dat (experimental data)
8/8/2019 Basic Comphy Ch3
32/38
32
0.0 10.25
1.0 8.37
2.0 6.88
3.0 5.64
4.0 4.615.0 3.76
6.0 3.08
7.0 2.54
8.0 2.07
9.0 1.68
10.0 1.39
File: expt.dat ( experimental data )
0.0000000E+00 2.327278
1.000000 2.124654
2.000000 1.928619
3.000000 1.729884
4.000000 1.528228
5.000000 1.324419
6.000000 1.124930
7.000000 0.9321641
8.000000 0.7275486
9.000000 0.5187938
10.00000 0.3293037
Output file: log_v.dat
Example: Calculate 1+2+3+.... until the sum is larger than (or equal to) 50
8/8/2019 Basic Comphy Ch3
33/38
33
INTEGER :: sum, i
sum = 0
DO i=1,2000
IF ( sum >= 50 ) EXIT
sum = sum + i
PRINT *, i, sum
END DO
PRINT *, 'Final sum = ', sum
a p e Ca cu ate 3 u t t e su s a ge t a (o equa to) 50
EXITstatement
Predefined maximum number ofiterations
If the condition is satisfied(ie, sum >= 50), EXITwill
transfer the control to thestatement immediatelyafter the DO loop.
1 1
2 3
3 6
4 10
5 15
6 21
7 28
8 36
9 45
10 55
Final sum = 55
Output:
8/8/2019 Basic Comphy Ch3
34/38
34
INTEGER :: sum, i
sum = 0
DO i=1,2000
IF ( sum >= 50 ) THEN
GO TO 100
ELSE
sum = sum + i
PRINT *, i, sum
ENDIF
END DO
100 PRINT *, 'Final sum = ', sum
GO TO statement
Line label
* The result is the same as the previous code using the EXIT statement
8/8/2019 Basic Comphy Ch3
35/38
35
DO
statement-sequence1
IF (logical-expression1) EXIT
statement-sequence2END DO
General DO-Loop with EXIT
INTEGER :: sum, n
sum = 0
n = 0
DO
n = n + 1
IF (sum >= 50) EXIT
sum = sum + nPRINT *, n, sum
END DO
PRINT *, 'Final sum = ', sum
Example:
No counter (hence, no need to put in a predefined maximumnumber of iterations)
Exit the DO loop only if the condition
(sum >= 50) is satisfied
Example:
8/8/2019 Basic Comphy Ch3
36/38
36
DO
n = n + 1
IF (sum < 50) THEN
sum = sum + nPRINT *, n, sum
ELSE
EXIT
END IF
END DO
PRINT *, 'Final sum = ', sum
Example:
* The format is different from the previous code, but the results are the same.
Remark: In cases if the condition for obeying the EXIT statement never occur then
8/8/2019 Basic Comphy Ch3
37/38
37
Remark: In cases if the condition for obeying the EXIT statement never occur, then
the non-counting form of the general DO statement will become an infinite loop.
Example:Continue executing until the program isterminated by some external means(eg, killed by the user)
* If the input N is negative, then the code will continue executing!
READ(*,*) N
DO i = 1, max_step
IF (N==0) EXIT
N = N 1
END DO
* It is usually better to use the counting form & introduce a predefined maximum number ofiterations:
READ(*,*) N
DO
IF (N==0) EXIT
N = N 1
END DO
An integer value (usually a very large number)
defined by the user
* The EXIT statement terminates the DO loop by transferring control to the statement
8/8/2019 Basic Comphy Ch3
38/38
38
DO-CYCLE construct
p y g
immediately following the END DO statement.
* But sometimes it is necessary to terminate only the current step and jump ahead to the nextone:
DO control-info
statement-sequence1
CYCLE
statement-sequence2
END DO
control-info is empty for
a non-counting form
Example:DO i = 1, 20
IF ( MOD(i,3) == 0 ) CYCLE
PRINT *, i
END DO
This code only prints the integers(between 1 and 20) which arenot divisible by 3(ie, 1, 2, 4, 5, 7,....20)
Recall: intrinsic functions (Ch. 2)