You are on page 1of 209

Fortran 90 Basics

I dont
don t know what the programming language
of the year 2000 will look like, but I know it
will be called FORTRAN.

Charles Anthony Richard Hoare


1
Fall 2010
F90 Program Structure
A Fortran 90 program has the following form:
program-name is the name of that program
specification-part
specification part, execution
execution-part
part, and
subprogram-part are optional.
g IMPLICIT NONE is also optional,
Although p , this is
required in this course to write safe programs.

PROGRAM program-name
IMPLICIT NONE
[
[specification-part]
ifi ti t]
[execution-part]
[subprogram-part]
[subprogram part]
END PROGRAM program-name 2
Program Comments
Comments start with a !
Everything following ! will be ignored
This is similar to // in C/C++
! This is an example
!

PROGRAM Comment
..........
READ(*,*) Year ! read in the value of Year
..........
Year = Year + 1 ! add 1 to Year
..........
END PROGRAM Comment
3
Continuation Lines
Fortran 90 is not completely format
format-free!
free!
A statement must starts with a new line.
If a statement
t t t is
i too
t long
l to
t fit on one line,
li it has
h
to be continued.
The continuation character is &, which is not
part of the statement.
Total = Total + &
Amount * Payments
! Total = Total + Amount*Payments

PROGRAM &
ContinuationLine
i i i
! PROGRAM ContinuationLine 4
Alphabets
Fortran 90 alphabets include the following:
Upper and lower cases letters
Di it
Digits
Special characters
space
' "
( ) * + - / : =
_ ! & $ ; < >
% ? , .

5
Constants: 1/6
A Fortran 90 constant may be an integer, real,
logical, complex, and character string.
We will not discuss complex constants.
constants
An integer constant is a string of digits with an
optional sign: 12345,
12345 -345,
345 +789,
+789 +0.+0

6
Constants: 2/6
A real constant has two forms, decimal and
exponential:
In the decimal form,
form a real constant is a
string of digits with exactly one decimal
point A real constant may include an
point.
optional sign. Example: 2.45, .13, 13.,
-00.12,
12 -.12.
12

7
Constants: 3/6
A real constant has two forms, decimal and
exponential:
In the exponential form,
form a real constant
starts with an integer/real, followed by a E/e,
followed by an integer (i
(i.e.,
e the exponent)
exponent).
Examples:
12E3 (12 103),) -12e3
12e3 (-12( 12 103),
)
3.45E-8 (3.45 10-8), -3.45e-8
( 3 45 10-8).
(-3.45 )
0E0 (0 100=0). 12.34-5 is wrong!
8
Constants: 4/6
A logical
g constant is either .TRUE. or .FALSE.
S
Note that the periods surrounding TRUE and
FALSE are required!

9
Constants: 5/6
A character string or character constant is a
string of characters enclosed between two
double quotes or two single quotes. Examples:
abc, John Dow, #$%^, and ()().
The content of a character string consists of all
characters between the quotes. Example: The
content of John
John Dow
Dow is John Dow.
Dow
The length of a string is the number of
characters
h t between
b t the
th quotes.
t The
Th length
l th off
John Dowis 8, space included.

10
Constants: 6/6
A stringg has length
g zero (i.e.,
( , no content)) is an
empty string.
g (or
If single ( double)) quotes
q are used in a string,
g,
then use double (or single) quotes as delimiters.
Examples: Adams cat and I said
go away.
Two consecutive quotes are treated as one!
Loris Apple is Loris Apple
double quote is double quote
`abcdefxy is abcdefxy
abc def x y is abc
abcdefxy abcdefxy
def x y
11
Identifiers: 1/2
A Fortran 90 identifier can have no more than
31 characters.
The first one must be a letter.
letter The remaining
characters, if any, may be letters, digits, or
underscores.
underscores
Fortran 90 identifiers are CASE INSENSITIVE.
Examples: A, Name, toTAL123, System_,
myFile_01, my_1st_F90_program_X_.
Identifiers Name, nAmE, naME and NamE are
the same.
12
Identifiers: 2/2
Unlike Java,, C,, C++,, etc,, Fortran 90 does not
have reserved words. This means one may use
Fortran keywords as identifiers.
Therefore, PROGRAM, end, IF, then, DO, etc
may be used as identifiers. Fortran 90
compilers are able to recognize keywords from
their positions in a statement.
Yes, end = program + if/(goto
while) is legal!
However, avoid the use of Fortran 90 keywords
as identifiers to minimize confusion.
13
Declarations: 1/3
Fortran 90 uses the following for variable
declarations, where type-specifier is one
of the followingg keywords:
y INTEGER,, REAL,,
LOGICAL, COMPLEX and CHARACTER, and
list is a sequence
q of identifiers separated
p by
y
commas.
type-specifier
type specifier :: list
Examples:
INTEGER :: Zip, Total, counter
REAL :: AVERAGE, x, Difference
LOGICAL :: Condition, OK
COMPLEX :: Conjugate
14
Declarations: 2/3
Character variables require additional
information, the string length:
Keyword CHARACTER must be followed by
a length attribute (LEN = l) , where l is
the length of the string
string.
The LEN= part is optional.
If the length of a string is 1, one may use
CHARACTER without length attribute.
Other length attributes will be discussed
later.
15
Declarations: 3/3
Examples:
CHARACTER(LEN=20) :: Answer, Quote
Variables Answer and Quote can hold
strings up to 20 characters.
CHARACTER(20) :: Answer, Quote is
the same as above.
CHARACTER :: Keypress means variable
Keypress can only hold ONE character (i.e.,
length 1).

16
The PARAMETER Attribute: 1/4
A PARAMETER identifier is a name whose value
cannot be modified. In other words, it is a
named constant.
The PARAMETER attribute is used after the type
keyword.
keyword
Each identifier is followed by a = and followed
b a value
by l ffor th
thatt id
identifier.
tifi

INTEGER, PARAMETER :: MAXIMUM = 10


INTEGER
REAL, PARAMETER :: PI = 3.1415926, E = 2.17828
LOGICAL, PARAMETER :: TRUE = .true., FALSE = .false.

17
The PARAMETER Attribute: 2/4
Since CHARACTER identifiers have a length g
attribute, it is a little more complex when used
with PARAMETER.
Use (LEN = *) if one does not want to count
the number of characters in a PARAMETER
character string, where = * means the length of
this string is determined elsewhere
elsewhere.

CHARACTER(LEN=3), PARAMETER :: YES = yes


y ! Len = 3
CHARACTER(LEN=2), PARAMETER :: NO = no ! Len = 2
CHARACTER(LEN=*), PARAMETER :: &
PROMPT = What do you want? ! Len = 17

18
The PARAMETER Attribute: 3/4
Since Fortran 90 strings are of fixed length, one
must remember the following:
If a string is longer than the PARAMETER
length, the right end is truncated.
If a string is shorter than the PARAMETER
length, spaces will be added to the right.

CHARACTER(LEN=4), PARAMETER :: ABC = abcdef


CHARACTER(LEN=4), PARAMETER :: XYZ = xy

ABC = a b c d XYZ = x y

19
The PARAMETER Attribute: 4/4
Byy convention,, PARAMETER identifiers use all
upper cases. However, this is not mandatory.
For maximum flexibility,
flexibility constants other than 0
and 1 should be PARAMETERized.
A PARAMETER is an alias of a value and is not a
variable. Hence, one cannot modify the content of
a PARAMETER identifier.
identifier
One can may a PARAMETER identifier anywhere
in a program. It is equivalent to replacing the
identifier with its value.
The value part can use expressions. 20
Variable Initialization: 1/2
A variable receives its value with
Initialization: It is done once before the
program runs.
runs
Assignment: It is done when the program
executes
t an assignment
i t statement.
t t t
Input: It is done with a READ statement.

21
Variable Initialization: 2/2
Variable initialization is very similar to what we
learned with PARAMETER.
A variable name is followed by a =,= followed by
an expression in which all identifiers must be
constants or PARAMETERs defined previously.
previously
Using an un-initialized variable may cause un-
expected,
t d sometimes
ti disastrous
di t results.
lt
REAL :: Offset = 0.1, Length = 10.0, tolerance = 1.E-7
CHARACTER(LEN=2) :: State1 = "MI", State2 = "MD
INTEGER, PARAMETER :: Quantity = 10, Amount = 435
INTEGER, PARAMETER :: Period = 3
INTEGER :: Pay = Quantity*Amount, Received = Period+5
22
Arithmetic Operators
There are four types of operators in Fortran 90:
arithmetic, relational, logical and character.
The following shows the first three types:
Type Operator Associativity
** right to left
Arithmetic * / left to right
+ - left to right
Relational < <= > >= == /= none
.NOT. right
g to left
f
.AND. left to right
Logical
.OR. left to right
.EQV. .NEQV. left to right
23
Operator Priority
** is the highest;
g ; * and / are the next,, followed
by + and -. All relational operators are next.
operators, .EQV.
Of the 5 logical operators EQV and .NEQV.NEQV
are the lowest.
Type Operator Associativity highest
hi h
** right to left priority
Arithmetic * / left to right

+ - left to right

Relational < <= > >= == /= none


.NOT. right to left
.AND. left to right
Logical
.OR. left to right
.EQV. .NEQV. left to right
24
Expression Evaluation
Expressions are evaluated from left to right.
If an operator is encountered in the process of
evaluation its priority is compared with that of
evaluation,
the next one
if the
th nextt one is
i lower,
l evaluate
l t the
th currentt
operator with its operands;
if the next one is equal to the current, the
associativity laws are used to determine
which one should be evaluated;
if the next one is higher, scanning continues
25
Single Mode Expression
A single mode arithmetic expression is an
expression all of whose operands are of the
same type.
If the operands are INTEGERs (resp., REALs),
the result is also an INTEGER (resp.,
(resp REAL).
REAL)
1.0 + 2.0 * 3.0 / ( 6.0*6.0 + 5.0*44.0) ** 0.25
--> 1.0 + 6.0 / (6.0*6.0 + 5.0*44.0) ** 0.25
--> 1.0 + 6.0 / (36.0 + 5.0*44.0) ** 0.25
--> 1.0 + 6.0 / (36.0 + 220.0) ** 0.25
--> 1.0
1 0 + 6.0
6 0 / 256.0
256 0 ** 0
0.25
25
--> 1.0 + 6.0 / 4.0
--> 1.0 + 1.5
-->
> 2.5
2 5
26
Mixed Mode Expression: 1/2
If operands have different types, it is mixed
mode.
INTEGER and REAL yields REAL,
REAL and the
INTEGER operand is converted to REAL before
evaluation Example: 3.5
evaluation. 3 5*4 4 is converted to
3.5*4.0 becoming single mode.
Exception: x**INTEGER: x**3 is x*x*x and
x**(-3) is 1.0/(x*x*x).
x**REAL isi evaluated
l i h log() and
d with d exp().
Logical and character cannot be mixed with
arithmetic operands. 27
Mixed Mode Expression: 2/2
Note that a**b**c is a**(b**c)
( ) instead of
(a**b)**c, and a**(b**c) (a**b)**c.
This can be a big trap!

5 * (11.0 - 5) ** 2 / 4 + 9
--> 5 * (11.0 - 5.0) ** 2 / 4 + 9
--> 5 * 6.0 ** 2 / 4 + 9
--> 5 * 36.0 / 4 + 9
--> 5.0 * 36.0 / 4 + 9 6.0**2 is evaluated as 6.0*6.0
--> 180.0 / 4 + 9 rather than converted to 6.0**2.0!
-->
> 180.0
180 0 / 4.0
4 0 + 9
--> 45.0 + 9
--> 45.0 + 9.0
-->
> 54.0
54 0
red: type conversion 28
The Assignment Statement: 1/2
The assignment statement has a form of
variable = expression
If the type of variable
ariable and expression
e pression are
identical, the result is saved to variable.
If the type of variable and expression are
not identical, the result of expression is
converted to the type off variable.
If expression is REAL and variable is
INTEGER, the result is truncated.

29
The Assignment Statement: 2/2
The left example uses an initialized variable
Unit, and the right uses a PARAMETER PI.

INTEGER :: Total, Amount REAL, PARAMETER :: PI = 3.1415926


INTEGER :: Unit = 5 REAL :: Area
INTEGER :: Radius
Amount = 100.99
Total = Unit * Amount Radius = 5
Area = (Radius ** 2) * PI

This one is equivalent to Radius ** 2 * PI

30
Fortran Intrinsic Functions: 1/4
Fortran provides many commonly used
functions, referred to as intrinsic functions.
To use an intrinsic function
function, we need to know:
Name and meaning of the function (e.g.,
SQRT() for square root)
Number of arguments
The type and range of each argument (e.g.,
the argument of SQRT() must be non-
negative)
Thee type
ype oof thee returned
e u ed function
u c o value.
v ue.
31
Fortran Intrinsic Functions: 2/4
Some mathematical functions:
Function Meaning Arg. Type Return Type
INTEGER INTEGER
ABS(x) absolute
b l l off x
value
REAL REAL
SQRT(x) square root of x REAL REAL
SIN(x) sine of x radian REAL REAL
COS(x) cosine of x radian REAL REAL
TAN(x) tangent of x radian REAL REAL
ASIN(x) arc sine of x REAL REAL
ACOS(x) arc cosine of x REAL REAL
ATAN(x) arc tangent of x REAL REAL
EXP(x) exponential ex REAL REAL
LOG(x) natural logarithm of x REAL REAL
32
LOG10(x) is the common logarithm of x!
Fortran Intrinsic Functions: 3/4
Some conversion functions:
Function Meaning Arg. Type Return Type
INT(x) truncate to integer part x REAL INTEGER
NINT(x) round nearest integer to x REAL INTEGER
FLOOR(x) greatest integer less than or equal to x REAL INTEGER
FRACTION(x) the fractional part of x REAL REAL
REAL(x) convert x to REAL INTEGER REAL

INT(-3.5) -3
Examples: NINT(3.5) 4
NINT(-3.4) -3
FLOOR(3.6) 3
FLOOR(-3.5) -4
FRACTION(12.3)
C O (12 3) 0 3
0.3
REAL(-10) -10.0 33
Fortran Intrinsic Functions: 4/4
Other functions:
Function Meaning Arg. Type Return Type
INTEGER INTEGER
MAX(x1, x2, ..., xn) maximum of x1, x2, ... xn
REAL REAL
INTEGER INTEGER
MIN(x1 x2,
MIN(x1, x2 ..., xn) minimum of x1,
x1 x2,
x2 ... xn
REAL REAL
INTEGER INTEGER
MOD(x,y) remainder x - INT(x/y)*y
REAL REAL

34
Expression Evaluation
Functions have the highest priority.
Function arguments are evaluated first.
The returned function value is treated as a
value in the expression.
REAL :: A = 1.0, B = -5.0,
5.0, C = 6.0, R

R = (-B + SQRT(B*B - 4.0*A*C))/(2.0*A) R gets 3.0


(-B + SQRT(B*B - 4.0*A*C))/(2.0*A)
/
--> (5.0 + SQRT(B*B - 4.0*A*C))/(2.0*A)
--> (5.0 + SQRT(25.0 - 4.0*A*C))/(2.0*A)
--> (5.0 + SQRT(25.0 - 4.0
4.0*C))/(2.0*A)
C))/(2.0 A)
--> (5.0 + SQRT(25.0 - 24.0))/(2.0*A)
--> (5.0 + SQRT(1.0))/(2.0*A)
--> (5.0 + 1.0)/(2.0*A)
--> 6.0/(2.0*A)
6 0/(2 0* )
--> 6.0/2.0 35
--> 3.0
What is IMPLICIT NONE?
Fortran has an interestingg tradition: all
variables starting with i, j, k, l, m and n, if
not declared, are of the INTEGER type by
default.
This handy feature can cause serious
consequences if it is not used with care.
IMPLICIT NONE means all names must be
declared and there is no implicitly assumed
INTEGER type.
All programs in this class must use IMPLICIT
NONE. Points will be deducted if you do not use it!
it
36
List-Directed
List Directed READ: 1/5
Fortran 90 uses the READ(*,*)
( , ) statement to
read data into variables from keyboard:
READ(*,*)
READ( ) v1,
v1 v2 v2, , vn
READ(*,*)
The second form has a special meaning that will
be discussed later.
INTEGER :: Age
REAL :: Amount, Rate
CHARACTER(LEN=10) :: Name

READ(*,*) Name, Age, Rate, Amount

37
List-Directed
List Directed READ: 2/5
Data Preparation Guidelines
READ(*,*) reads data from keyboard by
default although one may use input
default,
redirection to read from a file.
If READ(*,*)
READ(* *) has n variables,
variables there must
be n Fortran constants.
Each constant must have the type of the
corresponding variable. Integers can be
readd iinto REAL variables
i bl but
b not vice
i versa.
Data items are separated by spaces and may
spread into multiple lines. 38
List-Directed
List Directed READ: 3/5
The execution off READ(*,*)
( , ) always y starts with
a new line!
Then it reads each constant into the
Then,
corresponding variable.
CHARACTER(LEN=5) :: Name
REAL :: height, length
INTEGER :: count, MaxLength

READ(*,*) Name, height, count, length, MaxLength

put: "Smith" 100.0 25 123.579 10000


Input:

39
List-Directed
List Directed READ: 4/5
Be careful when input items are on multiple lines.
INTEGER :: I,J,K,L,M,N
Input:
READ(*,*) I, J 100 200
READ(*,*) K, L, M 300 400 500
READ(*,*) N 600

ignored!
INTEGER :: I,J,K,L,M,N

READ(*,*) I, J, K 100 200 300 400


READ(*,*) L, M, N 500 600 700 800
900
READ(*,*) always starts with a new line

40
List-Directed
List Directed READ: 5/5
Since READ(*,*)
( , ) always y starts with a new line,,
a READ(*,*) without any variable means
skipping the input line!

INTEGER :: P, Q, R, S

READ(*,*) P, Q 100 200 300


READ(*,*)
( , ) 400 500 600
READ(*,*) R, S 700 800 900

41
List-Directed
List Directed WRITE: 1/3
Fortran 90 uses the WRITE(*,*)
( , ) statement to
write information to screen.
WRITE(*,*)
WRITE( ) has two forms
forms, where exp1,
exp1
exp2, , expn are expressions
WRITE(* *) e
WRITE(*,*) exp1,
p1 e exp2,
p2 , e expn
pn
WRITE(*,*)
WRITE(*,*) evaluates the result of each
expression and prints it on screen.
WRITE(*,*) always starts with a new line!

42
List-Directed
List Directed WRITE: 2/3
Here is a simple example:
means length is determined by actual count
INTEGER :: Target
REAL :: Angle, Distance
CHARACTER(LEN=*), PARAMETER :: &
Time = "The time to hit target , &
IS = " is , &
UNIT = " sec."

Target = 10 continuation
ti ti lilines Output:
Angle = 20.0
Angle = 20.0 Distance = 1350.0
Distance = 1350.0
The time to hit target 10 is 27000.0 sec.
WRITE(* *) 'Angle
WRITE(*,*) 'A l = ' ', Angle
A l
WRITE(*,*) 'Distance = ', Distance
WRITE(*,*)
WRITE(* *) Time,
WRITE(*,*) Time Target
Target, IS IS, &
Angle * Distance, UNIT 43
print a blank line
List-Directed
List Directed WRITE: 3/3
The pprevious examplep used LEN=* , which
means the length of a CHARACTER constant is
determined by actual count.
WRITE(*,*) without any expression advances
to the next line, producing a blank one.
A Fortran 90 compiler will use the best way to
print each value. Thus, indentation and
alignment are difficult to achieve with
WRITE(*,*).
One must use the FORMAT statement to produce
good looking output.
44
Complete Example: 1/4
This pprogram
g computes
p the p
position ((x and y
coordinates) and the velocity (magnitude and direction)
of a projectile, given t, the time since launch, u, the
launch velocity,
i a, the initial
i i i angle of launch (in i degree),
and g=9.8, the acceleration due to gravity.
The horizontal and vertical displacements, x and y, are
computed as follows:

x u cos(a ) t 2
g t
y u sin(a ) t
2
45
Complete Example: 2/4
The horizontal and vertical components
p of the velocity
y
vector are computed as

Vx u cos(a )
Vy u sin((a) g t
The magnitude of the velocity vector is
V Vx2 V y2
The angle between the ground and the velocity vector is
Vx
tan( )
Vy
46
Complete Example: 3/4
Write a pprogram
g to read in the launch angle
g a,, the time
since launch t, and the launch velocity u, and compute
the position, the velocity and the angle with the ground.
PROGRAM Projectile
IMPLICIT NONE
REAL, PARAMETER :: g = 9.8 ! acceleration due to gravity
REAL, PARAMETER :: PI = 3.1415926 ! you know this. don't you?
REAL :: Angle ! launch angle in degree
REAL :: Time ! time to flight
REAL :: Theta ! direction at time in degree
REAL :: U ! launch velocity
REAL :: V ! resultant velocity
REAL :: Vx ! horizontal velocity
REAL :: Vy ! vertical velocity
REAL :: X ! horizontal displacement
REAL :: Y ! vertical displacement
Other executable statements
END PROGRAM Projectile
47
Complete Example: 4/4
Write a pprogram
g to read in the launch angle
g a,, the time
since launch t, and the launch velocity u, and compute
the position, the velocity and the angle with the ground.
READ(*,*) Angle, Time, U

Angle = Angle * PI / 180.0 ! convert to radian


X = U * COS(Angle) * Time
Y = U * SIN(Angle) * Time - g*Time*Time / 2.0
Vx = U * COS(Angle)
g
Vy = U * SIN(Angle) - g * Time
V = SQRT(Vx*Vx + Vy*Vy)
Theta = ATAN(Vy/Vx) * 180.0 / PI ! convert to degree

WRITE(*,*) 'Horizontal displacement : ', X


WRITE(*,*) 'Vertical displacement : ', Y
WRITE(*,*) 'Resultant velocity : ', V
WRITE(*,*) 'Direction (in degree) : ', Theta 48
CHARACTER Operator //
Fortran 90 uses // to concatenate two strings.
g
If strings A and B have lengths m and n, the
concatenation A // B is a string of length m+n.
m+n

CHARACTER(LEN=4) :: John = "John", Sam = "Sam"


CHARACTER(LEN=6) :: Lori = "Lori", Reagan = "Reagan"
CHARACTER(LEN=10) :: Ans1, Ans2, Ans3, Ans4

Ans1 = John // Lori ! Ans1 = JohnLori


Ans2 = Sam // Reagan ! Ans2 = Sam Reagan
Ans3 = Reagan // Sam ! Ans3 = ReaganSam
Ans4 = Lori // Sam ! Ans4 = Lori Sam

49
CHARACTER Substring: 1/3
A consecutive pportion of a string
g is a substring.
g
To use substrings, one may add an extent
p f to a CHARACTER variable.
specifier
An extent specifier has the following form:
( integer-exp1 : integer-exp2 )
The first and the second expressions indicate
the start and end: (3:8) means 3 to 88,
If A = abcdefg , then A(3:5) means As
substring from position 3 to position 5 (i.e.,
(i e
cde ).

50
CHARACTER Substring: 2/3
In (
(integer-exp1:integer-exp2),
g p g p ), if the
first exp1 is missing, the substring starts from
the first character,, and if exp2
p is missing,
g, the
substring ends at the last character.
If A = 12345678
12345678 , then A(:5) is 12345
12345
and A(3+x:) is 5678 where x is 2.
As a good
A d programming
i practice,
ti iin general,
l
the first expression exp1 should be no less than
1 and the second expression exp2 should be no
1,
greater than the length of the string.

51
CHARACTER Substring: 3/3
Substrings
g can be used on either side of the
assignment operator.
pp
Suppose LeftHand = 123456789
(length is 10) .
LeftHand(3:5) = "abc yields LeftHand =
12abc67890
LeftHand(4:) = "lmnopqr yields
LeftHand = "123lmnopqr
LeftHand(3:8) = "abc yields LeftHand =
"12abc 90
LeftHand(4:7) = "lmnopq yields
LeftHand = "123lmno890"

52
Example: 1/5
This p
program
g uses the DATE_AND_TIME() ()
Fortran 90 intrinsic function to retrieve the
system date and system time. Then, it converts
the date and time information to a readable
format. This program demonstrates the use of
concatenation operator // and substring.
System date is a string ccyymmdd,
ccyymmdd where cc =
century, yy = year, mm = month, and dd = day.
System time is a string hhmmss.sss, where hh
= hour, mm = minute, and ss.sss = second.
53
Example: 2/5
The followingg shows the specification
p part.
p
Note the handy way of changing string length.

PROGRAM DateTime
IMPLICIT NONE
CHARACTER(LEN = 8) :: DateINFO ! ccyymmdd
CHARACTER(LEN = 4) :: Year, Month*2, Day*2
CHARACTER(LEN = 10) :: TimeINFO, PrettyTime*12 ! hhmmss.sss
CHARACTER(LEN = 2) :: Hour, Minute, Second*6

CALL DATE_AND_TIME(DateINFO, TimeINFO)


other executable statements
END PROGRAM DateTime

This is a handy way of changing string length


54
Example: 3/5
Decompose
p DateINFO into yyear,, month and
day. DateINFO has a form of ccyymmdd,
where cc = century,
y, yy = yyear,, mm = month,,
and dd = day.
Year = DateINFO(1:4)
Month = DateINFO(5:6)
Day = DateINFO(7:8)
WRITE(* *) 'Date
WRITE(*,*) Date information -> ', DateINFO
WRITE(*,*) ' Year -> ', Year
WRITE(*,*) ' Month -> ', Month
WRITE(*,*) ' Day -> ', Day

Output: Date information -> 19970811


Year -> 1997
Month -> 08
Day -> 11 55
Example: 4/5
Now do the same for time:
Hour = TimeINFO(1:2)
Minute = TimeINFO(3:4)
Second = TimeINFO(5:10)
PrettyTime = Hour // ':' // Minute // ':' // Second
WRITE(*,*)
WRITE(*,*) 'Time Information -> ', TimeINFO
WRITE(*,*) ' Hour -> ', Hour
WRITE(*,*) ' Minute -> ', Minute
WRITE(*,*)
WRITE( , ) ' Second ->
> ',
, Second
WRITE(*,*) ' Pretty Time -> ', PrettyTime

Output: Time Information -> 010717.620


Hour -> 01
Minute -> 07
S
Second
d -> 17 620
17.620
Pretty Time -> 01:07:17.620
56
Example: 5/5
We mayy also use substring
g to achieve the same
result:

PrettyTime = ! Initialize to all blanks


PrettyTime( :2) = Hour
PrettyTime(3:3) = ':'
PrettyTime(4:5) = Minute
PrettyTime(6:6) = ':'
PrettyTime(7: ) = Second

WRITE(*,*)
WRITE(*,*)
WRITE( , ) ' Pretty Time ->
> ',
, PrettyTime

57
What KIND Is It?
Fortran 90 has a KIND attribute for selectingg
the precision of a numerical constant/variable.
The KIND of a constant/variable is a positive
integer (more on this later) that can be attached
to a constant
constant.
Example:
126_3 : 126 isi an integer
i off KIND 3
3.1415926_8 : 3.1415926 is a real of
KIND 8

58
What KIND Is It (INTEGER)? 1/2
Function SELECTED_INT_KIND(k)
_ _ selects the
KIND of an integer, where the value of k, a
positive integer, means the selected integer
KIND has a value between -10k and 10k.
Thus, the value of k is approximately the
number of digits of that KIND. For example,
SELECTED_INT_KIND(10) means an integer
KIND of no more than 10 digits.
digits
If SELECTED_INT_KIND() returns -1, this
means the
th h hardware
d d
does nott supportt th
the
requested KIND.

59
What KIND Is It (INTEGER)? 2/2
SELECTED_INT_KIND()
_ _ is usuallyy used in the
specification part like the following:
INTEGER, PARAMETER :: SHORT = SELECTED_INT_KIND(2)
_ _
INTEGER(KIND=SHORT) :: x, y
The above declares an INTEGER PARAMETER
SHORT with SELECTED_INT_KIND(2), which is
the KIND of 2-digit integers.
Then, the KIND= attribute specifies that INTEGER
variables x and y can hold 2-digit integers.
In a program, one may use -12_SHORT and
9_SHORT to write constants of that KIND.
60
What KIND Is It (REAL)? 1/2
Use S
SELECTED_REAL_KIND(k,e) ( , ) to specify
p ya
KIND for REAL constants/variables, where k is
the number of significant digits and e is the
number of digits in the exponent. Both k and e
must be positive integers.
Note that e is optional.
SELECTED REAL KIND(7 3) selects a REAL
SELECTED_REAL_KIND(7,3)
KIND of 7 significant digits and 3 digits for the
exponent:
t 0.xxxxxxx
0 10 yyy

61
What KIND Is It (REAL)? 2/2
Here is an example:
INTEGER, PARAMETER :: &
SINGLE=SELECTED REAL KIND(7,2), &
SINGLE=SELECTED_REAL_KIND(7,2),
DOUBLE=SELECTED_REAL_KIND(15,3)
REAL(KIND=SINGLE) :: x
REAL(KIND=DOUBLE) :: Sum

x = 123.45E-5_SINGLE
123 4
Sum = Sum + 12345.67890_DOUBLE

62
Why KIND, etc? 1/2
Old Fortran used INTEGER*2,, REAL*8,,
DOUBLE PRECISION, etc to specify the
precision of a variable. For example,
REAL*8 means the use of 8 bytes to store a real
value.
This is not very portable because some
computers may not use bytes as their basic
storage
t unit,
it while
hil some others
th cannott use 2
bytes for a short integer (i.e., INTEGER*2).
M
Moreover, we also
l wantt tot have
h more andd finer
fi
precision control.

63
Why KIND, etc? 2/2
Due to the differences among computer
hardware architectures, we have to be careful:
The requested KIND may not be satisfied.
satisfied
For example, SELECTED_INT_KIND(100)
may not be realistic on most computers.
computers
Compilers will find the best way good enough
(i e larger) for the requested KIND.
(i.e., KIND
If a larger KIND value is stored to a
ll KIND variable,
smaller i bl unpredictable
di bl
result may occur.
Use KIND carefully for maximum portability. 64
Fortran 90 Control Structures

Computer programming is an art form,


like the creation of poetry or music.

Donald Ervin Knuth


1
Fall 2010
LOGICAL Variables
A LOGIAL variable can onlyy hold either .TRUE.
or .FALSE. , and cannot hold values of any
other type.
Use T or F for LOGICAL variable READ(*,*)
WRITE(* *) prints T or F for .TRUE.
WRITE(*,*) TRUE
and .FALSE., respectively.
LOGICAL, PARAMETER :: Test = .TRUE.
LOGICAL :: C1, C2

C1 = .true. ! correct
C2 = 123 ! Wrong
READ(*,*) C1, C2
C2 = .false.
WRITE(*,*) C1, C2 2
Relational Operators: 1/4
Fortran 90 has six relational operators:
p <,, <=,,
>, >=, ==, /=.
p
Each of these six relational operators takes two
expressions, compares their values, and
yields .TRUE. or .FALSE.
Thus, a < b < c is wrong, because a < b is
LOGICAL and c is REAL or INTEGER.
COMPLEX values can only use == and /=
LOGICAL values should use .EQV. or .NEQV.
for equal and not-equal comparison.

3
Relational Operators: 2/4
Relational operators have lower priority than
arithmetic operators, and //.
Thus 3 + 5 > 10 is .FALSE.
Thus, FALSE and a a //
b == ab is .TRUE.
Character
Ch t values
l are encoded.
d d Different
Diff t
standards (e.g., BCD, EBCDIC, ANSI) have
diff
differentt encoding
di sequences.
These encoding sequences may not be
compatible with each other.

4
Relational Operators: 3/4
For maximum p portability, y, only
y assume the
following orders for letters and digits.
Thus,, A < X,, f <= u,, and 2 <
7 yield .TRUE. But, we dont know the
results of S < s and t >= %.
However, equal and not-equal such as S /=
s and t == 5 are fine.
A < B < C < D < E < F < G < H < I < J < K < L < M < N
< O < P < Q < R < S < T < U < V < W < X < Y < Z

a < b < c < d < e < f < g < h < i < j < k < l < m < n
< o < p < q < r < s < t < u < v < w < x < y < z

0 < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9


5
Relational Operators: 4/4
Stringg comparison
p rules:
Start scanning from the first character.
If the current two are equal,
equal go for the next
If there is no more characters to compare, the
strings are equal (e.g., abc == abc)
If one string has no more character, the shorter
string is smaller (e.g., ab < abc
is .TRUE.)
TRUE )
If the current two are not equal, the string
has the smaller character is smaller (e
(e.g.,
g
abcd is smaller than abct).

6
LOGICAL Operators: 1/2
There are 5 LOGICAL operators
p in Fortran
90: .NOT., .OR., .AND., .EQV. and .NEQV.
.NOT.
NOT is the highest
highest, followed by .OR.
OR
and .AND., .EQV. and .NEQV. are the lowest.
Recall that .NOT.
NOT is evaluated from right to left
left.
If both operands of .EQV. (equivalence) are the
same, .EQV. yields
i .TRUE..
.NEQV. is the opposite of .EQV. (not equivalence).
If the operands of .NEQV. have different
values, .NEQV. yields .TRUE.
7
LOGICAL Operators: 2/2
If INTEGER variables m,, n,, x and y have
values 3, 5, 4 and 2, respectively.

.NOT. (m > n .AND. x < y) .NEQV. (m <= n .AND. x >= y)


.NOT. (3 > 5 .AND. 4 < 2) .NEQV. (3 <= 5 .AND. 4 >= 2)
.NOT. (.FALSE. .AND. 4 < 2) .NEQV. (3 <= 5 .AND. 4 >= 2)
.NOT. (.FALSE. .AND. .FALSE.) .NEQV. (3 <= 5 .AND. 4 >= 2)
.NOT. .FALSE. .NEQV. (3 <= 5 .AND. 4 >= 2)
.TRUE.
TRUE .NEQV.
NEQV (3 <= 5 .AND.
AND 4 >= 2)
.TRUE. .NEQV. (.TRUE. .AND. 4 >= 2)
.TRUE. .NEQV. (.TRUE. .AND. .TRUE.)
.TRUE.
TRUE .NEQV.
NEQV .TRUE.
TRUE
.FALSE.

.NOT. is higher than .NEQV.


8
THEN ELSE Statement: 1/4
IF-THEN-ELSE
IF
Fortran 90 has three if-then-else forms.
The most complete one is the IF-THEN-ELSE-
IF-END IF
An old logical IF statement may be very handy
when it is needed.
There is an old and obsolete arithmetic IF that
yyou are not encouraged
g to use. We wont talk
about it at all.
Details are in the next few slides.

9
THEN ELSE Statement: 2/4
IF-THEN-ELSE
IF
IF-THEN-ELSE-IF-END IF is the following.
g
Logical expressions are evaluated sequentially (i.e., top-
down). The statement sequence that corresponds to the
expression evaluated to .TRUE. will be executed.
Otherwise, the ELSE sequence is executed.
IF (logical-expression-1) THEN
statement sequence 1
ELSE IF (logical-expression-2)
(logical expression 2) THEN
statement seqence 2
ELSE IF (logical-expression-3) THEN
statement sequence 3
ELSE IF (.....) THEN
...........
ELSE
statement sequence ELSE
10
END IF
THEN ELSE Statement: 3/4
IF-THEN-ELSE
IF
Two Examples:
Find the minimum of a, b and c
and saves the result to Result Letter ggrade ffor x
IF (a < b .AND. a < c) THEN INTEGER :: x
Result = a CHARACTER(LEN=1) :: Grade
ELSE IF (
(b < a .AND. b < c)
) THEN
Result = b IF (x < 50) THEN
ELSE Grade = 'F'
Result = c ELSE IF (x < 60) THEN
END IF G d = 'D'
Grade
ELSE IF (x < 70) THEN
Grade = 'C'
ELSE IF (
(x < 80)
) THEN
Grade = 'B'
ELSE
Grade = 'A'
END IF
11
THEN ELSE Statement: 4/4
IF-THEN-ELSE
IF
The ELSE-IF p part and ELSE ppart are optional.
p
If the ELSE part is missing and none of the
logical
g expressions
p is .TRUE.,, the IF-THEN-
ELSE has no effect.
no ELSE-IF no ELSE
IF (logical-expression-1) THEN IF (logical-expression-1) THEN
statement sequence 1 statement sequence 1
ELSE ELSE IF (logical-expression-2) THEN
statement sequence ELSE statement sequence 2
END IF ELSE IF (logical-expression-3) THEN
statement sequence 3
ELSE IF ( (.....)
) THEN
...........
END IF

12
Example: 1/2
Given a quadratic equation ax2 +bx
bx + c = 0,
where a 0, its roots are computed as follows:
2
b b 4 a c
x
2 a
However, this is a very poor and unreliable way
of computing roots. Will return to this soon.
PROGRAM QuadraticEquation
IMPLICIT NONE
REAL :: a, b, c
REAL :: d
REAL :: root1, root2
other executable statement
END PROGRAM QuadraticEquation 13
Example: 2/2
The following shows the executable part
READ(*,*) a, b, c
WRITE(*,*) 'a = ', a
WRITE(*,*) 'b = ', b
WRITE(*,*) 'c = ', c
WRITE(*,*)

d = b*b - 4.0*a*c
IF (d >= 0.0) THEN ! is it solvable?
d = SQRT(d)
root1 = (-b + d)/(2.0*a) ! first root
root2 = (-b - d)/(2.0*a) ! second root
WRITE(* *) 'R
WRITE(*,*) 'Roots
t are '', root1,
t1 ' andd '
', root2
t2
ELSE ! complex roots
WRITE(*,*) 'There is no real roots!'
WRITE(* *) 'Discriminant = '
WRITE(*,*) ', d
END IF 14
THEN ELSE Can be Nested: 1/2
IF-THEN-ELSE
IF
Another look at the quadratic equation solver.
IF (a == 0.0) THEN ! could be a linear equation
IF (b == 0
0.0)
0) THEN ! the input becomes c = 0
IF (c == 0.0) THEN ! all numbers are roots
WRITE(*,*) 'All numbers are roots'
ELSE ! unsolvable
WRITE(*,*) 'Unsolvable equation'
END IF
ELSE ! linear equation bx + c = 0
WRITE(*,*) 'This is linear equation, root = ', -c/b
END IF
ELSE ! ok,
, we have a q
quadratic equation
q
...... solve the equation here
END IF

15
THEN ELSE Can be Nested: 2/2
IF-THEN-ELSE
IF
Here is the bigg ELSE
S ppart:

d = b*b - 4.0*a*c
4 0*a*c
IF (d > 0.0) THEN ! distinct roots?
d = SQRT(d)
root1 = (-b + d)/(2
d)/(2.0*a)
0*a) ! first root
root2 = (-b - d)/(2.0*a) ! second root
WRITE(*,*) 'Roots are ', root1, ' and ', root2
ELSE IF (d == 0.0) THEN ! repeated roots?
WRITE(*,*) 'The repeated root is ', -b/(2.0*a)
ELSE ! complex roots
WRITE(*,*)
( , ) 'There is no real roots!'
WRITE(*,*) 'Discriminant = ', d
END IF

16
Logical IF
The logical
g IF is from Fortran 66,, which is an
improvement over the Fortran I arithmetic IF.
g p
If logical-expression is .TRUE. , statement is
executed. Otherwise, execution goes though.
g
The statement can be assignment and
input/output.
IF (logical
(logical-expression)
expression) statement

Smallest = b Cnt = Cnt + 1


IF (a < b) Smallest = a IF (MOD(Cnt,10) == 0) WRITE(*,*) Cnt

17
The SELECT CASE Statement: 1/7
Fortran 90 has the SSELECT CASE S statement for
selective execution if the selection criteria are
p values in INTEGER,, LOGICAL
based on simple
and CHARACTER. No, REAL is not applicable.
SELECT CASE (selector)
CASE (label-list-1) selector is an expression evaluated
statements-1 to an INTEGER, LOGICAL or
CASE (label-list-2) CHARACTER value
statements-22
CASE (label-list-3)
label-list is a set of constants or
statements-3
PARAMETERS of the same type yp
other cases
as the selector
CASE (label-list-n)
statements-n
CASE DEFAULT statements iss oonee or
o more
o e
statements-DEFAULT executable statements
18
END SELECT
The SELECT CASE Statement: 2/7
The label
label-list
list is a list of the following forms:
value a specific value
value1
al e1 : value2 al e2 values between
value1 and value2, including value1 and
value2,
al e2 and value1 al e1 <= < value2
al e2
value1 : values larger than or equal to
value1
: value2 values less than or equal to
value2
Reminder: value,, value1 and value2 must
be constants or PARAMETERs. 19
The SELECT CASE Statement: 3/7
The SELECT CASE statement is SELECT CASE (selector)
executed as follows: CASE (label-list-1)
statements-1
Compare the value of CASE ((label-list-2)
)
selector with the labels in statements-2
each case. If a match is CASE (label-list-3)
statements-3
f
found,
d execute
t th
the other cases
corresponding statements. CASE (label-list-n)
statements-n
If no match is found and if CASE DEFAULT
CASE DEFAULT is there, statements-DEFAULT
execute the statements- END SELECT
DEFAULT.
Execute the next statement optional
following the SELECT CASE.
20
The SELECT CASE Statement: 4/7
Some important notes:
The values in label-lists should be unique.
Otherwise it is not known which CASE
Otherwise,
would be selected.
CASE DEFAULT should be used whenever it
is possible, because it guarantees that there is
a place
l to
t ddo something
thi ((e.g., error message))
if no match is found.
CASE DEFAULT can be b anywhere
h in
i a
SELECT CASE statement; but, a preferred
place
l is
i the
h last
l in h CASE list.
i the li
21
The SELECT CASE Statement: 5/7
p of S
Two examples SELECT CASE:
S
CHARACTER(LEN=4) :: Title CHARACTER(LEN=1) :: c
INTEGER :: DrMD = 0, PhD = 0
INTEGER :: MS = 0, BS = 0 SELECT CASE (c)
INTEGER ::Others = 0 CASE ('a' : 'j')
WRITE(*,*) First ten letters'
SELECT CASE (Title)
i CASE ('l' : 'p', 'u' : 'y')
CASE ("DrMD") WRITE(*,*) &
DrMD = DrMD + 1 'One of l,m,n,o,p,u,v,w,x,y'
CASE (
("PhD")
PhD ) CASE ('z',
( z , 'q'
q : 't')
t )
PhD = PhD + 1 WRITE(*,*) 'One of z,q,r,s,t'
CASE ("MS") CASE DEFAULT
MS = MS + 1 WRITE(*,*) 'Other characters'
CASE ("BS")
( ) END SELECT
BS = BS + 1
CASE DEFAULT
Others
Ot e s = Ot
Others
e s + 1
END SELECT
22
The SELECT CASE Statement: 6/7
Here is a more complex example:
INTEGER :: Number, Range Number Range Why?
<= -10
10 1 CASE (:
(:-10,
10, 10:)
SELECT CASE (Number)
-9,-8,-7,-6 6 CASE DEFAULT
CASE ( : -10, 10 : )
Range = 1 -5,-4,-3 2 CASE (-5:-3, 6:9)
CASE (-5:-3, 6:9) -2,-1,0,1,2 3 CASE (-2:2)
Range = 2
3 4 CASE (3, 5)
CASE (-2:2)
Range = 3 4 5 CASE (4)
CASE (3, 5) 5 4 CASE (3, 5)
Range = 4
6,7,8,9 2 CASE (
(-5:-3,
5: 3, 6:9)
CASE (4)
Range = 5 >= 10 1 CASE (:-10, 10:)
CASE DEFAULT
R
Range = 6
END SELECT 23
The SELECT CASE Statement: 7/7
PROGRAM CharacterTesting This program reads in a character and
IMPLICIT NONE determines if it is a vowel, a consonant,
CHARACTER(LEN=1) :: Input a digit, one of the four arithmetic operators,
READ(*,*) Input
a space, or something else (i.e., %, $, @, etc).
SELECT CASE (Input)
CASE ('A' : 'Z', 'a' : 'z') ! rule out letters
WRITE(*,*) 'A letter is found : "', Input, '"'
SELECT CASE (Input) ! a vowel ?
CASE ('A', 'E', 'I', 'O', 'U', 'a', 'e', 'i', 'o','u')
WRITE(*,*)
WRITE( ) 'It
It is a vowel
vowel'
CASE DEFAULT ! it must be a consonant
WRITE(*,*) 'It is a consonant'
END SELECT
CASE ('0' : '9') ! a digit
WRITE(*,*) 'A digit is found : "', Input, '"'
CASE ('+', '-', '*', '/') ! an operator
WRITE(*,*)
WRITE( , ) 'An
An operator is found : "', , Input, '"'
CASE (' ') ! space
WRITE(*,*) 'A space is found : "', Input, '"'
CASE DEFAULT ! something else
WRITE(*,*) 'Something else found : "', Input, '"'
END SELECT 24
END PROGRAM CharacterTesting
The Counting DO Loop: 1/6
Fortran 90 has two forms of DO loop:
p the
counting DO and the general DO.
The counting DO has the following form:
DO control-var = initial, final [, step]
statements
END DO

control var is an INTEGER variable,


control-var
initial, final and step are INTEGER
expressions; however, step cannot be zero.
If step is omitted, its default value is 1.
statements are executable
t bl statements
t t the DO.
t off th O
25
The Counting DO Loop: 2/6
Before a DO-loopp starts,, expressions
p initial,,
final and step are evaluated exactly once.
When executingg the DO-loop, p, these values will
not be re-evaluated.
again the value of step cannot be zero
Note again, zero.
If step is positive, this DO counts up; if step is
negative this DO counts down
negative,

DO control-var = initial,
initial final [
[, step]
statements
END DO

26
The Counting DO Loop: 3/6
If step
p is p
positive:
The control-var receives the value of initial.
If the value of control
control-var
var is less than or equal to
the value of final, the statements part is executed.
Then, the value of step is added to control-var,
and goes back and compares the values of
control-var and final.
If the value of control-var is greater than the
value of final, the DO-loop completes and the
statement following END DO is executed.
executed

27
The Counting DO Loop: 4/6
If step
p is negative:
g
The control-var receives the value of initial.
If the value of control
control-var
var is greater than or
equal to the value of final, the statements part is
executed. Then, the value of step is added to
control-var, goes back and compares the values
of control-var and final.
If the value of control-var is less than the value
of final, the DO-loop completes and the statement
following END DO is executed.
executed

28
The Counting DO Loop: 5/6
Two simple examples:
INTEGER :: N, k odd integers
between 1 & N
READ(*,*) N
WRITE(*,*) Odd number between 1 and , N
DO k = 1, N, 2
WRITE(*,*) k
END DO

INTEGER, PARAMETER :: LONG = SELECTED_INT_KIND(15) factorial of N


INTEGER(KIND=LONG) :: Factorial, i, N

READ(*,*)
READ(* *) N
Factorial = 1_LONG
DO i = 1, N
Factorial = Factorial * i
END DO
WRITE(*,*) N, ! = , Factorial 29
The Counting DO Loop: 6/6
Important Notes:
The step size step cannot be zero
Never change
N h th
the value
l off any variable
i bl iin
control-var and initial, final, and
step.
step
For a count-down DO-loop, step must be
negative.
i Thus, do
i = 10, -10 is i not
a count-down DO-loop, and the statements
portion is not executed.
Fortran 77 allows REAL variables in DO; but,
dont use it as it is not safe. 30
General DO Loop with EXIT: 1/2
DO-Loop
The general DO
DO-loop
loop has the following form:
DO
statements
END DO
statements
t t t will
ill be
b executed
t d repeatedly.
t dl
To exit the DO-loop, use the EXIT or CYCLE
statement.
The EXIT statement brings the flow of control to
the statement following (i.e., exiting) the END DO.
Thee CCYCLE
C state
statement
e t sta
starts
ts tthee next
e t iteration
te at o
(i.e., executing statements again). 31
General DO Loop with EXIT: 2/2
DO-Loop
REAL, PARAMETER :: Lower = -1.0,
REAL 1 0 Upper = 1
1.0,
0 Step = 0
0.25
25
REAL :: x

x = Lower ! initialize the control variable


DO
IF (x > Upper) EXIT ! is it > final-value?
WRITE(*,*) x ! no, do the loop body
x = x + Step ! increase by step-size
END DO

INTEGER :: Input

DO
WRITE(*,*) 'Type in an integer in [0, 10] please --> '
READ(*,*) Input
IF (0 <= Input .AND. Input <= 10) EXIT
WRITE(*,*) 'Your input is out of range. Try again'
END DO

32
Example, exp(x): 1/2
The exp(x) function has an infinite series:
x2 x3 xi
exp( x ) 1 x .... ......
2! 3! i!
Sum each term until a terms absolute value is
less than a tolerance, say 0.00001.
PROGRAM Exponential
IMPLICIT NONE
INTEGER :: Count ! # of terms used
REAL :: Term ! a term
REAL :: Sum ! the sum
REAL :: X ! the input x
REAL, PARAMETER :: Tolerance = 0.00001 ! tolerance
executable statements
END PROGRAM Exponential 33
Example, exp(x): 2/2
i 1
Note: x xi x
(i 1)! i! i 1

This is not a good solution, though.


READ(*,*) X ! read in x
Count = 1 ! the first term is 1
Sum = 1.0 ! thus, the sum starts with
i 1
Term = X ! the second term is x
DO ! for each term
IF (ABS(Term)
(ABS(T ) < TTolerance)
l ) EXIT ! if t
too small,
ll exit
it
Sum = Sum + Term ! otherwise, add to sum
Count = Count + 1 ! count indicates the next term
Term = Term * (X / Count) ! compute the value of next term
END DO
WRITE(*,*) 'After ', Count, ' iterations:'
WRITE(*,*)
WRITE( ) ' Exp(
Exp(', X,
X ')) = ', Sum
WRITE(*,*) ' From EXP() = ', EXP(X)
34
WRITE(*,*) ' Abs(Error) = ', ABS(Sum - EXP(X))
Example, Prime Checking: 1/2
A positive integer n >= 2 is a prime number if the
only divisors of this integer are 1 and itself.
If n = 2,
2 it is a prime
prime.
If n > 2 is even (i.e., MOD(n,2) == 0), not a prime.
If n is odd, then:
If the odd numbers between 3 and n-1 cannot
divide n, n is a prime!
Do we have to ggo upp to n-1? No,, SQRT(n)
Q ( ) is
good enough. Why?

35
Example, Prime Checking: 2/2
INTEGER :: Number ! the input number
INTEGER :: Divisor ! the running divisor

READ(*,*) Number ! read in the input


IF (Number < 2) THEN ! not a prime if < 2
WRITE(* *) 'Illegal input'
WRITE(*,*)
ELSE IF (Number == 2) THEN ! is a prime if = 2
WRITE(*,*) Number, ' is a prime'
ELSE IF (MOD(Number,2) == 0) THEN ! not a prime if even
WRITE(*,*) Number, ' is NOT a prime'
ELSE ! an odd number here
Divisor = 3 ! divisor starts with 3
DO ! divide the input number
IF (Divisor*Divisor > Number .OR. MOD(Number, Divisor) == 0) EXIT
Divisor = Divisor + 2 ! increase to next odd
END DO
IF (Divisor*Divisor > Number) THEN ! which condition fails?
WRITE(*,*) Number, ' is a prime'
ELSE
WRITE(* *) Number,
WRITE(*,*) Number ' is NOT a prime prime'
END IF
this is better than SQRT(REAL(Divisor)) > Number 36
END IF
Finding All Primes in [2, n ]: 1/2
The previous program can be modified to find
all prime numbers between 2 and n.
PROGRAM Primes
IMPLICIT NONE
INTEGER :: Range, Number, Divisor, Count

WRITE(*,*) 'What is the range ? '


DO ! keep trying to read a good input
READ(*,*) Range ! ask for an input integer
IF (Range >= 2) EXIT ! if it is GOOD, exit
WRITE(*,*) 'The range value must be >= 2. Your input = ', Range
WRITE(*,*) 'Please try again:' ! otherwise, bug the user
END DO
we have a valid input to work on here
END PROGRAM Primes

37
Finding All Primes in [2, n ]: 2/2
Count = 1 ! input is correct. start counting
WRITE(*,*) ! 2 is a prime
WRITE(*,*) 'Prime number #', Count, ': ', 2

DO Number = 3, Range, 2 ! try all odd numbers 3, 5, 7, ...


Divisor = 3 ! divisor starts with 3
DO
IF (Divisor*Divisor
i i i i > Number .OR. MOD(Number,Divisor)
i i == 0) EXIT
Divisor = Divisor + 2 ! not a divisor, try next
END DO
IF (Divisor
(Divisor*Divisor
Divisor > Number) THEN ! divisors exhausted?
Count = Count + 1 ! yes, this Number is a prime
WRITE(*,*) 'Prime number #', Count, ': ', Number
END IF
END DO

WRITE(*,*)
WRITE(*,*)
( , ) 'There
e e a
are
e ',
, Count,
Cou t, ' p
primes
es in the
t e range
a ge o
of 2 a
and
d ',
, Range
a ge

38
Factoring a Number: 1/3
Given a p positive integer, g , one can always
y factorize
it into prime factors. The following is an
example:
586390350 = 2 3 52 72 13 17 192
Here,, 2,, 3,, 5,, 7,, 13,, 17 and 19 are p
prime factors.
It is not difficult to find all prime factors.
We can repeatedly divide the input by 2.
Do the same for odd numbers 3, 5, 7, 9, .
But we said prime factors.
But, factors No problem
problem,
multiples of 9 are eliminated by 3 in an earlier
stage!
39
Factoring a Number: 2/3
PROGRAM Factorize
IMPLICIT NONE
INTEGER :: Input
INTEGER :: Divisor
INTEGER :: Count

WRITE(*,*) 'This program factorizes any integer >= 2 --> '


READ(*,*) Input
Count = 0
DO ! remove all factors of 2
IF (MOD(I
(MOD(Input,2)
t 2) //= 0 .OR.
OR IInput
t == 1) EXIT
Count = Count + 1 ! increase count
WRITE(*,*) 'Factor # ', Count, ': ', 2
Input = Input / 2 ! remove this factor
END DO
use odd numbers here
END PROGRAM Factorize
40
Factoring a Number: 3/3
Divisor = 3 ! now we only worry about odd factors
DO ! Try 3, 5, 7, 9, 11 ....
IF (Divisor > Input) EXIT ! factor is too large, exit and done
DO ! try this factor repeatedly
IF (MOD(Input,Divisor) /= 0 .OR. Input == 1) EXIT
Count = Count + 1
WRITE(*,*) 'Factor # ', Count, ': ', Divisor
Input = Input / Divisor ! remove this factor from Input
END DO
Divisor = Divisor + 2 ! move to next odd number
END DO

Note that even 99, 15


15, 49
49, will be used,
used they would only be used
once because Divisor = 3 removes all multiples of 3 (e.g., 9, 15, ),
Divisor = 5 removes all multiples of 5 (e.g., 15, 25, ), and
Divisor = 7 removes all multiples of 7 (e.g., 21, 35, 49, ), etc.
41
Handling End-of-File:
End of File: 1/3
Very frequently we don
dontt know the number of
data items in the input.
Fortran uses IOSTAT= for I/O error handling:
READ(*,*,IOSTAT=v) v1, v2, , vn
In the above, v is an INTEGER variable.
After the execution of READ(*,*):
If v = 0, READ(*,*) was executed successfully
If v > 0, an error occurred in READ(*,*) and not
all variables received values.
If v < 0, encountered end-of-file, and not all
variables received values.
42
Handling End-of-File:
End of File: 2/3
Every file is ended with a special character.
Unix and Windows use Ctrl-D and Ctrl-Z.
When using keyboard to enter data to
READ(*,*), Ctrl-D means end-of-file in Unix.
If IOSTAT=
IOSTAT returns a positive value,
value we only
know something was wrong in READ(*,*) such
as type
t mismatch,
i t h no such
h fil
file, d
device
i error, etc.
t
We really dont know exactly what happened
because the returned value is system dependent.

43
Handling End-of-File:
End of File: 3/3
i
input
t output
t t
INTEGER :: io, x, sum 1 The total is 8
3
sum = 0 4
DO
READ(*,*,IOSTAT=io) x
IF (io > 0) THEN input
WRITE(*,*) 'Check input. Something was wrong' 1
EXIT & no output
ELSE IF (io < 0) THEN 4
WRITE(*,*)
(* *) 'The
h total
l i
is ', sum
EXIT
ELSE
sum = sum + x
END IF
END DO

44
Computing Means, etc: 1/4
Let us compute the arithmetic, geometric and
harmonic means of unknown number of values:
x x ...... x
arithmetic mean = 1

n
2 n

geometric mean = x x ...... x


n
1 2 n

n
harmonic mean = 1 1
......
1
x1 x2 xn

Note that only positive values will be considered


considered.
This nave way is not a good method.

45
Computing Means, etc: 2/4
PROGRAM ComputingMeans
IMPLICIT NONE
REAL :: X
REAL :: Sum,
, Product,
, InverseSum
REAL :: Arithmetic, Geometric, Harmonic
INTEGER :: Count, TotalValid
INTEGER :: IO ! for IOSTAT=

Sum = 0.0
Product = 1.0
InverseSum = 0.0
TotalValid = 0
Count = 0
other computation part
END PROGRAM ComputingMeans

46
Computing Means, etc: 3/4
DO
READ(*,*,IOSTAT=IO) X ! read in data
IF (IO < 0) EXIT ! IO < 0 means end-of-file reached
Count = Count + 1 ! otherwise, got some value
IF (IO > 0) THEN ! IO > 0 means something wrong
WRITE(*,*) 'ERROR: something wrong in your input'
WRITE(*,*) 'Try again please'
ELSE ! IO = 0 means everything is normal
WRITE(*,*) 'Input item ', Count, ' --> ', X
IF (X <= 0.0) THEN
WRITE(*,*) 'Input <= 0. Ignored'
ELSE
TotalValid = TotalValid + 1
Sum = Sum + X
Product = Product * X
InverseSum = InverseSum + 1.0/X
END IF
END IF
END DO

47
Computing Means, etc: 4/4

WRITE(*,*)
IF (TotalValid > 0) THEN
Arithmetic = Sum / TotalValid
Geometric = Product**(1.0/TotalValid)
Harmonic = TotalValid / InverseSum
WRITE(*,*) '# of items read --> ', Count
WRITE(*,*)
WRITE( , ) '#
# of valid items ->
> ',
, TotalValid
WRITE(*,*) 'Arithmetic mean --> ', Arithmetic
WRITE(*,*) 'Geometric mean --> ', Geometric
WRITE(*,*) 'Harmonic mean --> ', Harmonic
ELSE
WRITE(*,*) 'ERROR: none of the input is positive'
END IF

48
Fortran 90 Arrays

Program testing can be used to show the presence of bugs,


bugs
but never to show their absence

Edsger W. Dijkstra

1
Fall 2009
The DIMENSION Attribute: 1/6
A Fortran 90 p program
g uses the DIMENSION
attribute to declare arrays.
The DIMENSION attribute requires
q three
components in order to complete an array
specification, rank, shape, and extent.
The rank of an array is the number of indices
or subscripts. The maximum rank is 7 (i.e.,
seven-dimensional).
The shape of an array indicates the number of
elements in each dimension.

2
The DIMENSION Attribute: 2/6
The rank and shape of an array is represented
as (s1,s2,,sn), where n is the rank of the array
and si (1 i n) is the number of elements in the
i-th dimension.
(7) means a rank 1 array with 7 elements
(5,9) means a rank 2 array (i.e., a table)
whose
h fi
firstt and
d second
d di
dimensions
i h
have 5
and 9 elements, respectively.
(10,10,10,10) means a rank 4 array that has
10 elements in each dimension.
3
The DIMENSION Attribute: 3/6
The extent is written as m:n, where m and n (m
n) are INTEGERs. We saw this in the SELECT
CASE,, substring,
g, etc.
Each dimension has its own extent.
A extent
An t t off a di
dimension
i is
i the
th range off itits
index. If m: is omitted, the default is 1.
-3:2 means possible i indices
i i are -3,
3 -22 , -1,
1 00,
1, 2
5:8 means possible indices are 5,6,7,8
7 means p possible indices are 1,2,3,4,5,6,7
, , , , , ,
4
The DIMENSION Attribute: 4/6
The DIMENSION attribute has the followingg
form:
DIMENSION(extent-1,
( , extent-2,, ,, extent-n))
Here, extent-i is the extent of dimension i.
This means an array of dimension n (i.e., n
indices) whose i-th dimension index has a range
ggiven byy extent-i.
Just a reminder: Fortran 90 only allows
maximum 7 dimensions.
Exercise: given a DIMENSION attribute,
determine its shape.p
5
The DIMENSION Attribute: 5/6
Here are some examples:
DIMENSION(-1:1) is a 1-dimensional
array with possible indices -1,0,1
-1 0 1
DIMENSION(0:2,3) is a 2-dimensional
array (i.e.,
(i a table).
t bl ) PPossible
ibl values
l off th
the
first index are 0,1,2 and the second 1,2,3
DIMENSION(3,4,5) is i a 3-dimensional
3 i i
array. Possible values of the first index are
1,2,3, the second 1,2,3,4, and the third
1,2,3,4,5.
6
The DIMENSION Attribute: 6/6
Arrayy declaration is simple.
p Add the
DIMENSION attribute to a type declaration.
Values in the DIMENSION attribute are usuallyy
PARAMETERs to make program modifications
easier.

INTEGER, PARAMETER :: SIZE=5, LOWER=3, UPPER = 5


INTEGER, PARAMETER :: SMALL = 10, LARGE = 15
REAL, DIMENSION(1:SIZE) :: x
INTEGER,
, DIMENSION(LOWER:UPPER,SMALL:LARGE)
( , ) :: a,b
,
LOGICAL, DIMENSION(2,2) :: Truth_Table

7
Use of Arrays: 1/3
Fortran 90 has,, in ggeneral,, three different ways
y
to use arrays: referring to individual array
element, referring to the whole array, and
referring to a section of an array.
The first one is very easy. One just starts with
the array name, followed by () between which
are the indices separated by ,.
Note that each index must be an INTEGER or an
expression evaluated to an INTEGER, and the
value
l off an iindex
d mustt beb ini the
th range off the
th
corresponding extent. But, Fortran 90 wont
check it for you.
you
8
Use of Arrays: 2/3
Suppose we have the following declarations
INTEGER, PARAMETER :: L_BOUND = 3, U_BOUND = 10
INTEGER, DIMENSION(L_BOUND:U_BOUND)
DIMENSION(L BOUND:U BOUND) :: x

DO i = L_BOUND, U_BOUND DO i = L_BOUND, U_BOUND


x(i) = i IF (MOD(i,2) == 0) THEN
END DO x(i)
i = 0
ELSE
array x() has 3,4,5,, 10
x(i) = 1
END IF
END DO
array x() has 11,0,1,0,1,0,1,0
0101010
9
Use of Arrays: 3/3
Suppose we have the following declarations:

INTEGER, PARAMETER :: L_BOUND = 3, U_BOUND = 10


INTEGER, DIMENSION(L_BOUND:U_BOUND, &
L_BOUND:U_BOUND) :: a

DO i = L_BOUND, U_BOUND DO i = L_BOUND, U_BOUND


DO j = L_BOUND, U_BOUND DO j = i+1, U_BOUND
a(i j) = 0
a(i,j) t = a(i,j)
END DO a(i,j) = a(j,i)
a(j,i) = t
a(i,i) = 1
END DO
END DO END DO
generate an identity matrix Swapping the lower and
upper diagonal parts (i
(i.e.,
e
the transpose of a matrix)
10
The Implied DO: 1/7
Fortran has the implied
p DO that can ggenerate
efficiently a set of values and/or elements.
p
The implied DO is a variation of the DO-loop.
p
The implied DO has the following syntax:
(item-1
(item 1, item
item-2
2, ,item
item-n
n, v=initial,final,step)
v=initial final step)
Here, item-1, item-2, , item-n are
variables or expressions, v is an INTEGER
variable, and initial, final, and step are
INTEGER expressions.
p
v=initial,final,step is exactly what we
saw in a DO-loop.
p
11
The Implied DO: 2/7
The execution of an implied
p DO below lets variable
v to start with initial, and step though to
final with a step size step.
(item 1 item-2,
(item-1, item 2 ,item-n,
item n v=initial,final,step)
v=initial final step)
The result is a sequence of items.
(i+1, i=1,3) generates 2, 2 3,
3 4.4
(i*k, i+k*i, i=1,8,2) generates k, 1+k (i
), 3*k,, 3+k*3 ((i = 3),
= 1), ), 5*k,, 5+k*5 ((i = 5),
),
7*k, 7+k*7 (i = 7).
(a(i),a(i+2),a(i*3-1),i*4,i=3,5)
t a(3),
generates (3) a(5),
( ) a(8)(8) , 12 (i=3),
(i 3) a(4),
(4)
a(6), a(11), 16 (i=4), a(5), a(7), a(14), 20.

12
The Implied DO: 3/7
Implied
p DO mayy be nested.
(i*k,(j*j,i*j,j=1,3), i=2,4)
above, (j*j,i*j,j=1,3)
In the above (j*j i*j j 1 3) is nested in
the implied i loop.
Here are the results:
When i = 2, the implied DO generates
2*k, (j*j,2*j,j=1,3)
Then j goes from 1 to 3 and generates
Then,
2*k, 1*1, 2*1, 2*2, 2*2, 3*3, 2*3
j = 1 j = 2 j = 3
13
The Implied DO: 4/7
Continue with the pprevious examplep
(i*k,(j*j,i*j,j=1,3), i=2,4)
When i = 3, it ggenerates the following:
g
3*k, (j*j,3*j,j=1,3)
Expanding
p g the j loopp yyields:
3*k, 1*1, 3*1, 2*2, 3*2, 3*3, 3*3
When i = 4,, the i loop
p ggenerates
4*k, (j*j, 4*j, j=1,3)
Expanding
p g the j loopp yyields
4*k, 1*1, 4*1, 2*2, 4*2, 3*3, 4*3

j = 1 j = 2 j = 3 14
The Implied DO: 5/7
The following generates a multiplication table:
((i*j,j=1,9),i=1,9)
When i = 1,
1 the inner j implied DO-loop
DO loop
produces 1*1, 1*2, , 1*9
When i = 2, the inner j implied DO-loop
produces 2*1, 2*2, , 2*9
When i = 9, the inner j implied DO-loop
produces 9*1, 9*2, , 9*9

15
The Implied DO: 6/7
The following produces all upper triangular
entries, row-by-row, of a 2-dimensional array:
((a(p q) q = p
((a(p,q),q p,n),p
n) p = 1 1,n)
n)
When p = 1, the inner q loop produces a(1,1),
a(1 2) , a(1,n)
a(1,2), a(1 n)
When p=2, the inner q loop produces a(2,2),
a(2,3), ., a(2,n)
When p=3, the inner q loop produces a(3,3),
a(3,4), , a(3,n)
When p p=n,, the inner q loop
ppproduces a(n,n)
( , )
16
The Implied DO: 7/7
The following produces all upper triangular
entries, column-by-column:
((a(p q) p = 1
((a(p,q),p 1,q),q
q) q = 1 1,n)
n)
When q=1, the inner p loop produces a(1,1)
When q=2, the inner p loop produces a(1,2),
a(2,2)
When q=3, the inner p loop produces a(1,3),
a(2,3), , a(3,3)
When q=n, the inner p loop produces a(1,n),
a(2,n),
( , ), a(3,n),
( , ), ,, a(n,n)
( , )
17
Array Input/Output: 1/8
Implied
p DO can be used in READ(*,*)
( , ) and
WRITE(*,*) statements.
When an implied DO is used
used, it is equivalent to
execute the I/O statement with the generated
elements.
elements
The following prints out a multiplication table
WRITE(*,*)((i,*,j,=,i*j,j=1,9),i=1,9)
(* *)((i * j i*j j 1 9) i 1 9)
The following has a better format (i.e., 9 rows):
DO i = 1, 9
WRITE(*,*) (i, *, j, =, i*j, j=1,9)
END DO
18
Array Input/Output: 2/8
The followingg shows three ways
y of readinggn
data items into an one dimensional array a().
Are they the same?
((1)) READ(*,*) n,(a(i),i=1,n)

(2) READ(*,*) n
READ(*,*) (a(i),i=1,n)
i i

(3) READ(*
READ(*,*)
*) n
DO i = 1, n
READ(*,*) a(i)
END DO
19
Array Input/Output: 3/8
Suppose
pp we wish to fill a(1),
( ), a(2)
( ) and a(3)
( )
with 10, 20 and 30. The input may be:
3 10 20 30
Each READ starts from a new line!
(1) READ(*,*) n,(a(i),i=1,n) OK

Wrong! n gets 3 and


(2) READ(*
READ(*,*)
*) n
the second READ fails
READ(*,*) (a(i),i=1,n)

(3) READ(*,*) n Wrong! n gets 3 and


DO i = 1, n the three READs fail
READ(*,*) a(i)
20
END DO
Array Input/Output: 4/8
What if the input is changed to the following?
3
10 20 30

(1) READ(*,*) n,(a(i),i=1,n) OK

OK. Why????
(2) READ(*
READ(*,*)
*) n
READ(*,*) (a(i),i=1,n)

(3) READ(*,*) n Wrong! n gets 3, a(1) has


DO i = 1, n 10; but, the next two
READ(*,*) a(i) READs fail
21
END DO
Array Input/Output: 5/8
What if the input is changed to the following?
3
10
20
30

(1) READ(*,*) n,(a(i),i=1,n) OK

OK
(2) READ(*
READ(*,*)
*) n
READ(*,*) (a(i),i=1,n)

(3) READ(*,*) n OK
DO i = 1, n
READ(*,*) a(i)
22
END DO
Array Input/Output: 6/8
Suppose
pp we have a two-dimensional arrayy a():
()
INTEGER, DIMENSION(2:4,0:1) :: a
Suppose further the READ is the following:
READ(*,*) ((a(i,j),j=0,1),i=2,4)
What are the results for the following input?
1 2 3
1 2 3 4 5 6 4 5 6
7 8 9
0 1 0 1
2 1 2 2 1 2
3 3 4 3 3 4
4 5 6 4 5 6
23
Array Input/Output: 7/8
Suppose
pp we have a two-dimensional arrayy a():
()
INTEGER, DIMENSION(2:4,0:1) :: a
DO i = 2,
2 4
READ(*,*) (a(i,j),j=0,1)
END DO
What are the results for the following input?
1 2 3
1 2 3 4 5 6 4 5 6
7 8 9
0 1 0 1
A(2,0)=1 1 2 2 1 2 row-by-row
y
A(2,1)=2 ? ? 3 4 5
then error! ? ? 4 7 8 24
Array Input/Output: 8/8
Suppose
pp we have a two-dimensional arrayy a():
()
INTEGER, DIMENSION(2:4,0:1) :: a
DO j = 0,
0 1
READ(*,*) (a(i,j),i=2,4)
END DO
What are the results for the following input?
1 2 3
1 2 3 4 5 6 4 5 6
7 8 9
A(2,0)=1 0 1 0 1
A(3,0)=2 1 ? 2 1 4 column-by-column
y
A(4,0)=3 2 ? 3 2 5
3 ? 25
then error! 4 3 6
Matrix Multiplication: 1/2
Read a l m matrix Al m and a m n matrix Bm n,
and compute their product Cl n = Al m Bm n.
PROGRAM Matrix_Multiplication
Matrix Multiplication
IMPLICIT NONE
INTEGER, PARAMETER :: SIZE = 100
INTEGER DIMENSION(1:SIZE
INTEGER, DIMENSION(1:SIZE,1:SIZE)
1:SIZE) :: A
A, B
B, C
INTEGER :: L, M, N, i, j, k
READ(*,*) L, M, N ! read sizes <= 100
DO i = 1, L
READ(*,*) (A(i,j), j=1,M) ! A() is L-by-M
END DO
DO i = 1, M
READ(*,*) (B(i,j), j=1,N) ! B() is M-by-N
END DO
other statements
26
END PROGRAM Matrix_Multiplication
Matrix Multiplication: 2/2
The following does multiplication and output

DO i = 1, L
DO j = 1, N
C(i,j) = 0 ! for each C(i,j)
DO k = 1, M ! (row i of A)*(col j of B)
C(i,j) = C(i,j) + A(i,k)*B(k,j)
END DO
END DO
END DO

DO i = 1,
1 L ! print row-by-row
WRITE(*,*) (C(i,j), j=1, N)
END DO

27
Arrays as Arguments: 1/4
Arrays
y may y also be used as arguments
g passing
p g
to functions and subroutines.
g
Formal argument arrays
y may y be declared as
usual; however, Fortran 90 recommends the use
of assumed-shape arrays.
An assumed-shape array has its lower bound in
each extent specified; but, the upper bound is
not used.
formal arguments
REAL, DIMENSION(-3:,1:), INTENT(IN) :: x, y
INTEGER, DIMENSION(:), INTENT(OUT) :: a, b
assumed-shape 28
Arrays as Arguments: 2/4
The extent in each dimension is an expression
that uses constants or other non-array formal
arguments
g with INTENT(IN)
( ):
assumed-shape
SUBROUTINE Test(x,y,z,w,l,m,n)
I PLICIT NONE
IMPLICIT
INTEGER, INTENT(IN) :: l, m, n
REAL, DIMENSION(10:),INTENT(IN) :: x
INTEGER, DIMENSION(-1:,m:), INTENT(OUT) :: y
LOGICAL, DIMENSION(m,n:), INTENT(OUT) :: z
REAL, DIMENSION(-5:5), INTENT(IN) :: w
other statements
END SUBROUTINE Test DIMENSION(1:m,n:)

not assumed-shape 29
Arrays as Arguments: 3/4
Fortran 90 automatically passes an array and its
shape to a formal argument.
A subprogram receives the shape and uses the
lower bound of each extent to recover the upper
bound.
bound
INTEGER,DIMENSION(2:10)::Score

CALL Funny(Score) shape is (9)

SUBROUTINE Funny(x)
IMPLICIT NONE
INTEGER,DIMENSION(-1:),INTENT(IN) :: x
other statements
30
END SUBROUTINE Funny (-1:7)
Arrays as Arguments: 4/4
One more example

REAL,
, DIMENSION(1:3,1:4)
( , ) :: x
INTEGER :: p = 3, q = 2

CALL Fast(x,p,q) shape is (3,4)

SUBROUTINE Fast(a,m,n)
( , , )
IMPLICIT NONE
INTEGER,INTENT(IN) :: m,n
REAL DIMENSION(-m:
REAL,DIMENSION( m:,n:),INTENT(IN)::a
n:) INTENT(IN)::a
other statements
END SUBROUTINE Fast

(-m:,n:) becomes (-3:-1,2:5) 31


The SIZE() Intrinsic Function: 1/2
How do I know the shape p of an array?
y
Use the SIZE() intrinsic function.
SIZE() requires two arguments, an array
name and an INTEGER, and returns the size of
the arrayy in the ggiven dimension.
shape is (9,101)
INTEGER,DIMENSION(-3:5,0:100):: a
WRITE(*,*) SIZE(a,1), SIZE(a,2)
CALL ArraySize(a)
(1:9,5:105)

Both WRITE prints SUBROUTINE ArraySize(x)


9 and 101 INTEGER,DIMENSION(1:,5:), :: x
WRITE(*,*) SIZE(x,1), SIZE(x,2)
32
The SIZE() Intrinsic Function : 2/2
INTEGER,DIMENSION(-1:1,3:6):: Empty
CALL Fill(Empty)
DO i = -1,1
WRITE(*,*) (Empty(i,j),j=3,6)
END DO shape is (3,4)
SUBROUTINE Fill(y)
I PLICIT NONE
IMPLICIT
INTEGER,DIMENSION(1:,1:),INTENT(OUT)::y
INTEGER :: U1, U2, i, j
output U1 = SIZE(y,1)
2 3 4 5
U2 = SIZE(y,2)
3 4 5 6
DO i = 1, U1 (1:3 1:4)
(1:3,1:4)
4 5 6 7
DO j = 1, U2
y(i,j) = i + j
END DO
END DO
33
END SUBROUTINE Fill
Local Arrays: 1/2
Fortran 90 permits to declare local arrays using
INTEGER formal arguments with the
INTENT(IN)
( ) attribute.

INTEGER, & SUBROUTINE Compute(X,


Compute(X mm, n)
DIMENSION(100,100) &
W(1:3) Y(1:3,1:15) IMPLICIT NONE
::a, z INTEGER,INTENT(IN) :: m, n
INTEGER,DIMENSION(1:,1:),
INTEGER DIMENSION(1 1 ) &
CALL Compute(a,3,5)
INTENT(IN) :: X local arrays
CALL Compute(z,6,8) INTEGER,DIMENSION(1:m) :: W
REAL,DIMENSION(1:m,1:m*n)::Y
other statements
W(1:6) Y(1:6,1:48)
END SUBROUTINE Compute

34
Local Arrays: 2/2
Just like you learned in C/C++ and Java,
memory of local variables and local arrays in
Fortran 90 is allocated before entering a
subprogram and deallocated on return.
g
Fortran 90 uses the formal arguments to
compute the extents of local arrays.
Therefore, different calls with different values
of actual arguments produce different shape
and extent for the same local array. However,
the rank of a local array will not change.

35
The ALLOCATBLE Attribute
In many situations, one does not know exactly
the shape or extents of an array. As a result,
one can only declare a large
large enough
enough array.
The ALLOCATABLE attribute comes to rescue.
The ALLOCATABLE attribute indicates that at
the declaration time one only knows the rank of
an array but
b t nott it
its extent.
t t
Therefore, each extent has only a colon :.
INTEGER,ALLOCATABLE,DIMENSION(:) :: a
REAL,ALLOCATABLE,DIMENSION(:,:) :: b
LOGICAL,ALLOCATABLE,DIMENSION(:,:,:) :: c
36
The ALLOCATE Statement: 1/3
The ALLOCATE statement has the followingg
syntax:
ALLOCATE(array-1
ALLOCATE(array-1,,array-n,STAT=v)
array-n STAT=v)
Here, array-1, , array-n are array names
with complete extents as in the DIMENSION
attribute, and v is an INTEGER variable.
Af the execution
After i off ALLOCATE, if v 0,0 then
at least one arrays did not get memory.
REAL,ALLOCATABLE,DIMENSION(:) :: a
LOGICAL,ALLOCATABLE,DIMENSION(:,:) :: x
INTEGER :: status
ALLOCATE(a(3:5), x(-10:10,1:8), STAT=status) 37
The ALLOCATE Statement: 2/3
ALLOCATE onlyy allocates arraysy with the
ALLOCATABLE attribute.
The extents in ALLOCATE can use INTEGER
expressions. Make sure all involved variables
have been initialized properly
properly.
INTEGER,ALLOCATABLE,DIMENSION(:,:) :: x
INTEGER,ALLOCATABLE,DIMENSION(:) :: a
INTEGER :: m, n, p
READ(*,*) m, n
ALLOCATE(x(1:m m+n:m*n) a(-(m*n):m*n) STAT=p)
ALLOCATE(x(1:m,m+n:m*n),a(-(m*n):m*n),STAT=p)
IF (p /= 0) THEN
report error here
If m = 3 and n = 5, then we have
x(1:3,8:15) and a(-15:15) 38
The ALLOCATE Statement: 3/3
ALLOCATE can be used in subprograms.
p g
Formal arrays are not ALLOCATABLE.
IIn general,
l an array allocated
ll t d iin a subprogram
b
is a local entity, and is automatically
d ll t d when
deallocated h ththe subprogram
b returns.
t
Watch for the following odd use:
PROGRAM Try_not_to_do_this
IMPLICIT NONE
REAL,ALLOCATABLE,DIMENSION(:) :: x
CONTAINS
SUBROUTINE Hey()
ALLOCATE(x(1:10))
END SUBROUTINE Hey
39
END PROGRAM Try_not_to_do_this
The DEALLOCATE Statement
Allocated arrays may be deallocated by the
DEALLOCATE() statement as shown below:
DEALLOCATE(array-1
DEALLOCATE(array-1,,array-n,STAT=v)
array-n STAT=v)
Here, array-1, , array-n are the names of
arrays and v is an INTEGER variable.
allocated arrays, variable
If deallocation fails (e.g., some arrays were not
allocated), i v is
) the value in i non-zero.
After deallocation of an array, it is not available
and any access will cause a program error.
DEALLOCATE(a b,
DEALLOCATE(a, b c
c, STAT=status)
40
The ALLOCATED Intrinsic Function
The ALLOCATED(a) ( ) function returns .TRUE.
if ALLOCATABLE array a has been allocated.
Otherwise,, it returns .FALSE.

INTEGER,ALLOCATABLE,DIMENSION(:) :: Mat
INTEGER :: status

ALLOCATE(Mat(1:100),STAT=status)
ALLOCATED(Mat) returns .TRUE. ..
other statements
DEALLOCATE(Mat,STAT status)
DEALLOCATE(Mat,STAT=status)
ALLOCATED(Mat) returns .FALSE.

41
Fortran 90 Subprograms

If Fortran is the lingua franca, then certainly it must


be true that BASIC is the lingua playpen

Thomas E. Kurtz
Co-Designer of the BASIC language
1
Fall 2010
Functions and Subroutines
Fortran 90 has two types of subprograms,
functions and subroutines.
A Fortran 90 function is a function like those in
C/C++. Thus, a function returns a computed
result via the function name.
name
If a function does not have to return a function
value,
l use subroutine.
b ti

2
Function Syntax: 1/3
A Fortran function,, or function subprogram,
p g ,
has the following syntax:
type FUNCTION function-name (arg1, arg2, ..., argn)
IMPLICIT NONE
[specification part]
[execution part]
p
[subprogram part]
END FUNCTION function-name
type is a Fortran 90 type (e.g.,
(e g INTEGER,
INTEGER
REAL, LOGICAL, etc) with or without KIND.
function name is a Fortran 90 identifier
function-name
arg1, , argn are formal arguments.
3
Function Syntax: 2/3
A function is a self-contained unit that receives
some input from the outside world via its
formal arguments, does some computations, and
returns the result with the name of the function.
Somewhere in a function there has to be one or
more assignment statements like this:
function-name = expression
where the result of expression is saved to the
name of the function.
Note that function-name cannot appear in
the right-hand side of any expression.
4
Function Syntax: 3/3
In a type
yp specification,
p , formal arguments
g
should have a new attribute INTENT(IN).
The meaningg of INTENT(IN) is that the
function only takes the value from a formal
argument and does not change its content.
Any statements that can be used in PROGRAM
can also be used in a FUNCTION.

5
Function Example
Note that functions can have no formal argument.
But, () is still required.
Factorial computation Read and return a positive real number
INTEGER FUNCTION Factorial(n) REAL FUNCTION GetNumber()
IMPLICIT NONE IMPLICIT NONE
INTEGER, INTENT(IN) :: n REAL :: Input_Value
INTEGER :: i, Ans DO
WRITE(*,*)
( , ) 'A positive
p number: '
Ans = 1 READ(*,*) Input_Value
DO i = 1, n IF (Input_Value > 0.0) EXIT
Ans = Ans * i WRITE(*,*) 'ERROR. try again.'
END DO END DO
Factorial = Ans GetNumber = Input_Value
END FUNCTION Factorial END FUNCTION GetNumber

6
Common Problems: 1/2
forget
g function type
yp g INTENT(IN)
forget not an error
FUNCTION DoSomething(a, b) REAL FUNCTION DoSomething(a, b)
IMPLICIT NONE IMPLICIT NONE
INTEGER, INTENT(IN) :: a, b INTEGER :: a, b
DoSomthing = SQRT(a*a + b*b) DoSomthing = SQRT(a*a + b*b)
END FUNCTION DoSomething END FUNCTION DoSomething

change INTENT(IN) argument forget to return a value


REAL FUNCTION DoSomething(a, b) REAL FUNCTION DoSomething(a, b)
IMPLICIT NONE IMPLICIT NONE
INTEGER, INTENT(IN) :: a, b INTEGER, INTENT(IN) :: a, b
IF (a > b) THEN INTEGER :: c
a = a - b c = SQRT(a*a + b*b)
ELSE END FUNCTION DoSomething
a = a + b
END IF
DoSomthing = SQRT(a*a+b*b)
END FUNCTION DoSomething
7
Common Problems: 2/2

incorrect use of function name only the most recent value is returned
REAL FUNCTION DoSomething(a, b) REAL FUNCTION DoSomething(a, b)
IMPLICIT NONE IMPLICIT NONE
INTEGER, INTENT(IN) :: a, b INTEGER, INTENT(IN) :: a, b
DoSomething = a*a + b*b DoSomething = a*a + b*b
DoSomething = SQRT(DoSomething) DoSomething = SQRT(a*a - b*b)
END FUNCTION DoSomething END FUNCTION DoSomething

8
Using Functions
The use of a user-defined
user defined function is similar to
the use of a Fortran 90 intrinsic function.
The following uses function Factorial(n) to
compute the combinatorial coefficient C(m,n) ,
where m and n are actual arguments:
Cmn = Factorial(m)/(Factorial(n)*Factorial(m-n))

Note that the combinatorial coefficient is


defined as follows, although it is not the most
efficient way:
m!
C(m, n)
n! (m n)! 9
Argument Association : 1/5
Argument association is a way of passing values
from actual arguments to formal arguments.
If an actual argument is an expression,
expression it is
evaluated and stored in a temporary location
from which the value is passed to the
corresponding formal argument.
If an actual
t l argumentt iis a variable,
i bl its
it value
l isi
passed to the corresponding formal argument.
C
Constant andd (A), where
h A is
i variable,
i bl are
considered expressions.
10
Argument Association : 2/5
Actual arguments are variables:

WRITE(*,*) Sum(a,b,c)
a b c

INTEGER FUNCTION Sum(x,y,z)


IMPLICIT NONE
INTEGER INTENT(IN)::x y z
INTEGER,INTENT(IN)::x,y,z x y z
..
END FUNCTION Sum

11
Argument Association : 3/5
Expressions as actual arguments. Dashed line
boxes are temporary locations.

WRITE(*,*) Sum(a+b,b+c,c)
a+b b+c c

INTEGER FUNCTION Sum(x,y,z)


IMPLICIT NONE
INTEGER INTENT(IN)::x y z
INTEGER,INTENT(IN)::x,y,z x y z
..
END FUNCTION Sum

12
Argument Association : 4/5
Constants as actual arguments. Dashed line
boxes are temporary locations.

WRITE(*,*) Sum(1, 2, 3)
1 2 3

INTEGER FUNCTION Sum(x,y,z)


IMPLICIT NONE
INTEGER INTENT(IN)::x y z
INTEGER,INTENT(IN)::x,y,z x y z
..
END FUNCTION Sum

13
Argument Association : 5/5
A variable in () is considered as an expression.
p
Dashed line boxes are temporary locations.

WRITE(*,*) Sum((a), (b), (c))


(a) (b) (c)

INTEGER FUNCTION Sum(x,y,z)


IMPLICIT NONE
INTEGER INTENT(IN)::x y z
INTEGER,INTENT(IN)::x,y,z x y z
..
END FUNCTION Sum

14
Where Do Functions Go: 1/2
Fortran 90 functions can be internal or external.
Internal functions are inside of a PROGRAM, the
main program:
PROGRAM program-name
IMPLICIT
C NONE
NON
[specification part]
[execution part]
CONTAINS
[functions]
END PROGRAM program-name

Although a function can contain other functions,


i t
internal
l functions
f ti cannott have
h iinternal
t l ffunctions.
ti
15
Where Do Functions Go: 2/2
The right
g shows PROGRAM TwoFunctions
two internal IMPLICIT NONE
REAL :: a, b, A_Mean, G_Mean
functions, READ(*,*) a, b
ArithMean() A_Mean = ArithMean(a, b)
G_Mean = GeoMean(a,b)
and GeoMean(). WRITE(*,*) a, b, A_Mean, G_Mean
CONTAINS
They take two REAL FUNCTION ArithMean(a, b)
REAL actual IMPLICIT NONE
REAL, INTENT(IN) :: a, b
argumentst and
d ArithMean = (a+b)/2.0
END FUNCTION ArithMean
compute and REAL FUNCTION GeoMean(a, b)
return a REAL IMPLICIT NONE
REAL, INTENT(IN) :: a, b
function value. GeoMean = SQRT(a*b)
END FUNCTION GeoMean
END PROGRAM TwoFunctions
16
Scope Rules: 1/5
Scope rules tell us if an entity (i.e., variable,
parameter and function) is visible or accessible
at certain places.
Places where an entity can be accessed or visible
is referred as the scope of that entity
entity.

17
Scope Rules: 2/5
Scope Rule #1: The scope of an entity is the
program or function in which it is declared.
PROGRAM Scope_1 Scope of PI, m and n
IMPLICIT NONE
REAL, PARAMETER :: PI = 3.1415926
INTEGER :: m, n
...................
CONTAINS
INTEGER FUNCTION Funct1(k) Scope of k, f and g
IMPLICIT NONE local to Funct1()
INTEGER, INTENT(IN) :: k
REAL :: f, g
..........
END FUNCTION Funct1
REAL FUNCTION Funct2(u, v)
IMPLICIT NONE Scope of u and v
REAL, INTENT(IN) :: u, v local to Funct2()
..........
END FUNCTION Funct2 18
END PROGRAM Scope_1
Scope Rules: 3/5
Scope
p Rule #2 :A global entity is visible to all
contained functions.
PROGRAM Scope_2
IMPLICIT NONE
a, b and c are global
INTEGER :: a = 1, b = 2, c = 3 The first Add(a) returns 4
WRITE(*,*) Add(a)
c = 4 Th second
The d Add(a)
dd returns
t 5
WRITE(*,*) Add(a)
WRITE(*,*) Mul(b,c) Mul(b,c) returns 8
CONTAINS
INTEGER FUNCTION Add(q)
IMPLICIT NONE Thus, the two Add(a)s produce different
INTEGER, INTENT(IN) :: q results, even though the formal arguments
Add = q + c
END FUNCTION Add
are the same! This is usually referred to
INTEGER FUNCTION Mul(x, y) as side effect.
IMPLICIT NONE
INTEGER, INTENT(IN) :: x, y
Mul = x * y Avoid using global entities!
END FUNCTION Mul 19
END PROGRAM Scope_2
Scope Rules: 4/5
Scope
p Rule #2 :A global entity is visible to all
contained functions.

PROGRAM Global The first Add(a,b) returns 30


IMPLICIT NONE It also changes b to 30
INTEGER :: a = 10, b = 20
Th 22nd
The d WRITE(*,*)
WRITE(* *) showsh 30
WRITE(*,*) Add(a,b)
WRITE(*,*) b The 2nd Add(a,b) returns 40
WRITE(*,*) Add(a,b) This is a bad side effect
CONTAINS Avoid using global entities!
INTEGER FUNCTION Add(x,y)
IMPLICIT NONE
INTEGER, INTENT(IN)::x, y
b = x+y
Add = b
END FUNCTION Add
END PROGRAM Global 20
Scope Rules: 5/5
Scope Rule #3 :An entity declared in the scope of
another
th entity
tit iis always
l a different
diff t one even if
their names are identical.
PROGRAM Scope_3 Although PROGRAM and FUNCTION
IMPLICIT NONE Sum() both have INTEGER variable i,
INTEGER :: i, Max = 5
Theyy are TWO different entities.
DO i = 11, Max
Write(*,*) Sum(i)
END DO Hence, any changes to i in Sum() will
CONTAINS not affect the i in PROGRAM.
INTEGER FUNCTION Sum(n)
IMPLICIT NONE
INTEGER, INTENT(IN) :: n
INTEGER :: ii, s
s = 0
other computation
Sum = s
END FUNCTION Sum
END PROGRAM Scope_3 21
Example: 1/4
If a triangle has side lengths a, b and c, the Heron
formula computes the triangle area as follows,
where s = (a
(a+b+c)/2:
b c)/2:

Area s ( s a ) ( s b ) ( s c)

To form a triangle, a, b and c must fulfill the


following two conditions:
a > 0, b > 0 and c > 0
a+b > c, a+c > b and b+c > a

22
Example: 2/4
LOGICAL Function TriangleTest()
g () makes
sure all sides are positive, and the sum of any
two is larger than the third.

LOGICAL FUNCTION TriangleTest(a, b, c)


IMPLICIT NONE
REAL, INTENT(IN) :: a, b, c
LOGICAL
OG C :: test
test1,
, test
test2
test1 = (a > 0.0) .AND. (b > 0.0) .AND. (c > 0.0)
test2 = (a + b > c) .AND. (a + c > b) .AND. (b + c > a)
TriangleTest = test1 .AND. test2 ! both must be .TRUE.
END FUNCTION TriangleTest

23
Example: 3/4
This function implements the Heron formula.
Note that a, b and c must form a triangle.

REAL FUNCTION Area(a, b, c)


IMPLICIT NONE
REAL, INTENT(IN) :: a, b, c
REAL :: s
s = (a + b + c) / 2.0
A
Area = SQRT(
SQRT(s*(s-a)*(s-b)*(s-c))
*( )*( b)*( ))
END FUNCTION Area

24
Example: 4/4
Here is the main program!
PROGRAM HeronFormula
IMPLICIT NONE
REAL :: a, b, c, TriangleArea
DO
WRITE(*,*) 'Three sides of a triangle please --> '
READ(*,*) a, b, c
WRITE(*,*) 'Input sides are ', a, b, c
IF (TriangleTest(a, b, c)) EXIT ! exit if they form a triangle
WRITE(*,*) 'Your input CANNOT form a triangle. Try again'
END DO
TriangleArea = Area(a,
Area(a b,
b c)
WRITE(*,*) 'Triangle area is ', TriangleArea
CONTAINS
LOGICAL FUNCTION TriangleTest(a, b, c)

END FUNCTION TriangleTest
REAL FUNCTION Area(a, b, c)

END FUNCTION Area
25
END PROGRAM HeronFormula
Subroutines: 1/2
A Fortran 90 function takes values from its
formal arguments, and returns a single value
with the function name.
A Fortran 90 subroutine takes values from its
formal arguments,
arguments and returns some computed
results with its formal arguments.
AFFortran
t 90 subroutine
b ti does
d nott return
t any
value with its name.

26
Subroutines: 2/2
The following is Fortran 90 subroutine syntax:

SUBROUTINE subroutine-name(arg1,arg2,...,argn)
IMPLICIT NONE
[specification part]
[
[execution
ti part]
t]
[subprogram part]
END SUBROUTINE subroutine
subroutine-name
name

If a subroutine does not require any formal


arguments arg1,arg2,...,argn
arguments, arg1 arg2 argn can be removed;
however, () must be there.
S b
Subroutines
ti are similar
i il tto ffunctions.
ti
27
The INTENT() Attribute: 1/2
Since subroutines use formal arguments to
receive values and to pass results back, in
addition to INTENT(IN),
( ), there are
INTENT(OUT) and INTENT(INOUT).
INTENT(OUT) means a formal argument does
not receive a value; but, it will return a value to
its corresponding actual argument
argument.
INTENT(INOUT) means a formal argument
receives
i a value
l from
f and d returns
t a value
l tot its
it
corresponding actual argument.

28
The INTENT() Attribute: 2/2
Two simple examples:
Am, Gm and Hm are used to return the results
SUBROUTINE Means(a, b, c, Am, Gm, Hm)
IMPLICIT NONE
REAL, INTENT(IN) :: a, b, c
REAL, INTENT(OUT) :: Am, Gm, Hm
Am = (a+b+c)/3.0
Gm = (a*b*c)**(1.0/3.0)
(a*b*c)**(1 0/3 0)
Hm = 3.0/(1.0/a + 1.0/b + 1.0/c)
END SUBROUTINE Means
values of a and b are swapped
SUBROUTINE Swap(a, b)
IMPLICIT NONE
INTEGER, INTENT(INOUT) :: a, b
INTEGER :: c
c = a
a = b
b = c
END SUBROUTINE Swap
29
The CALL Statement: 1/2
Unlike C/C
C/C++ and Java, to use a Fortran 90
subroutine, the CALL statement is needed.
The CALL statement may have one of the three
forms:
CALL sub-name(arg1,arg2,,argn)
sub name(arg1 arg2 argn)
CALL sub-name( )
CALL sub-name
The last two forms are equivalent and are for
calling a subroutine without formal arguments.

30
The CALL Statement: 2/2
PROGRAM Test PROGRAM SecondDegree
IMPLICIT NONE IMPLICIT NONE
REAL :: a, b REAL :: a, b, c, r1, r2
READ(*,*) a, b LOGICAL :: OK
CALL Swap(a,b) READ(*,*) a, b, c
WRITE(*,*) a, b CALL Solver(a,b,c,r1,r2,OK)
CONTAINS IF (.NOT. OK) THEN
SUBROUTINE Swap(x,y)
Swap(x y) WRITE(* *) No root
WRITE(*,*)
IMPLICIT NONE ELSE
REAL, INTENT(INOUT) :: x,y WRITE(*,*) a, b, c, r1, r2
REAL :: z END IF
z = x CONTAINS
x = y SUBROUTINE Solver(a,b,c,x,y,L)
y = z IMPLICIT NONE
END SUBROUTINE Swap REAL INTENT(IN) :: a,b,c
REAL, a b c
END PROGRAM Test REAL, INTENT(OUT) :: x, y
LOGICAL, INTENT(OUT) :: L

END SUBROUTINE Solver
END PROGRAM SecondDegree 31
More Argument Association: 1/2
Since a formal argument
g with the INTENT(OUT)
( )
or INTENT(INOUT) attribute will pass a value
back to the corresponding actual argument, the
actual argument must be a variable.

PROGRAM Errors SUBROUTINE Sub(u,v,w,p,q)


IMPLICIT NONE IMPLICIT NONE
INTEGER :: a, b, c INTEGER, INTENT(OUT) :: u
.......... INTEGER, INTENT(INOUT) :: v
CALL Sub(1,a,b+c,(c),1+a) INTEGER, INTENT(IN) :: w
.......... INTEGER,
, INTENT(OUT) :: p
END PROGRAM Errors INTEGER, INTENT(IN) :: q
..........
END SUBROUTINE Sub

these two are incorrect! 32


More Argument Association: 2/2
The number of arguments and their types must
match properly.
There is no type-conversion between arguments!

PROGRAM Error SUBROUTINE ABC(p, q)


IMPLICIT NONE IMPLICIT NONE
INTEGER :: a, b INTEGER, INTENT(IN) :: p
CALL ABC(a, b) REAL, INTENT(OUT) :: q
CALL ABC(a) type mismatch
CONTAINSwrongg # of arguments
g END SUBROUTINE ABC

END PROGRAM Error

33
Fortran 90 Modules: 1/4
One may collect all relevant functions and
subroutines together into a module.
A module
module, in OOs
OO s language
language, is perhaps close to
a static class that has public/private information
and methods
methods.
So, in some sense, Fortran 90s module provides
a sortt off object-based
bj t b d rather
th ththan object-
bj t
oriented programming paradigm.

34
Fortran 90 Modules: 2/4
A Fortran 90 module has the following syntax:
MODULE module-name
IMPLICIT NONE
[specification part]
CONTAINS
[internal functions/subroutines]
[ / ]
END MODULE module-name

The specification
p p
part and internal functions and
subroutines are optional.
A module looks like a PROGRAM, except that it
does not have the executable part. Hence, a
main program must be there to use modules.
35
Fortran 90 Modules: 3/4
Examples:
Module SomeConstants does not Module SumAverage does not
p g
have the subprogram p
part have the specification
p p
part
MODULE SomeConstants MODULE SumAverage
IMPLICIT NONE
REAL, PARAMETER :: PI=3.1415926 CONTAINS
REAL PARAMETER :: g = 980
REAL, REAL FUNCTION Sum(a,
S ( b
b, c)
INTEGER :: Counter IMPLICIT NONE
END MODULE SomeConstants REAL, INTENT(IN) :: a, b, c
Sum = a + b + c
END FUNCTION Sum
REAL FUNCTION Average(a, b, c)
IMPLICIT NONE
REAL INTENT(IN) :: a,
REAL, a bb, c
Average = Sum(a,b,c)/2.0
END FUNCTION Average
END MODULE SumAverage

36
Fortran 90 Modules: 4/4
The right
g module MODULE DegreeRadianConversion
IMPLICIT NONE
has both the REAL, PARAMETER :: PI = 3.1415926
specification REAL, PARAMETER :: Degree180 = 180.0
part andd CONTAINS
internal REAL FUNCTION DegreeToRadian(Degree)
IMPLICIT NONE
functions
functions. REAL, INTENT(IN) :: Degree
DegreeToRadian = Degree*PI/Degree180
Normally, this is END FUNCTION DegreeToRadian
the case. REAL FUNCTION RadianToDegree(radian)
IMPLICIT NONE
REAL, INTENT(IN) :: Radian
RadianToDegree = Radian*Degree180/PI
END FUNCTION RadianToDegree
END MODULE DegreeRadianConversion

37
Some Privacy: 1/2
Fortran 90 allows a module to have pprivate and
public items. However, all global entities of a
module, by default, are public (i.e., visible in all
other programs and modules)
modules).
To specify public and private, do the following:
PUBLIC :: name-1,
name 1 name
name-2,
2 , name
name-n
n
PRIVATE :: name-1, name-2, , name-n
The PRIVATE statement without a name makes
all entities in a module private. To make some
entities visible, use PUBLIC.
PUBLIC and d PRIVATE may also l be
b used
d in
i
type specification:
INTEGER, PRIVATE :: Sum, Phone_Number 38
Some Privacy: 2/2
Anyy gglobal entityy MODULE TheForce
(e.g., PARAMETER, IMPLICIT NONE
INTEGER :: SkyWalker, Princess Is this public?
variable, function, REAL, PRIVATE :: BlackKnight
subroutine,
i etc) LOGICAL :: DeathStar
REAL, PARAMETER :: SecretConstant = 0.123456
can be in PUBLIC PUBLIC :: SkyWalker, Princess
or PRIVATE PRIVATE :: VolumeOfDeathStar
PRIVATE :: SecretConstant
statements. CONTAINS
INTEGER FUNCTION VolumeOfDeathStar()
..........
END FUNCTION WolumeOfDeathStar
REAL FUNCTION WeaponPower(SomeWeapon)
..........
END FUNCTION ..........
END MODULE TheForce

By default, this PUBLIC statement


does not make much sense 39
Using a Module: 1/5
A PROGRAM or MODULE can use PUBLIC entities
in any other modules. However, one must
declare this intention (of use).
There are two forms of the USE statement for
this task:
USE module-name
USE module-name, ONLY: name-1, name-2, ..., name-n

The first USE indicates all PUBLIC entities of


MODULE module-name will be used.
The second makes use only the names listed after
the ONLY keyword.
40
Using a Module: 2/5
Two simple
p examples:
p
PROGRAM Main
USE SomeConstants
MODULE SomeConstants IMPLICIT NONE
IMPLICIT NONE ..........
REAL, PARAMETER :: PI = 3.1415926 END PROGRAM Main
REAL,
, PARAMETER :: g = 980
INTEGER :: Counter
END MODULE SomeConstants

MODULE DoSomething
USE SomeConstants, ONLY : g, Counter
IMPLICIT NONE PI is not available
CONTAINS
SUBROUTINE Something()

END SUBROUTINE Something
S thi
END MODULE DoSomething 41
Using a Module: 3/5
Sometimes, the imported
imported entities from a
MODULE may have identical names with names
g PROGRAM or MODULE.
in the importing
p
If this happens, one may use the renaming
feature of USE.
USE
For each identifier in USE to be renamed, use the
f ll i syntax:
following t
name-in-this-PROGRAM => name-in-module

In this program, the use of name-in-this-


PROGRAM is equivalent to the use of name-in-
module in the imported MODULE. 42
Using a Module: 4/5
The followingg uses module MyModule.
y
Identifiers Counter and Test in module
MyModule are renamed as MyCounter and
MyTest in this module, respectively:
USE MyModule, MyCounter => Counter &
MyTest => Test
The following only uses identifiers Ans,
Condition and X from module Package with
Condition renamed as Status:
USE Package, ONLY : Ans, Status => Condition, X

43
Using a Module: 5/5
Two USE
S and => examples
p GravityG is the g in the module;
however, g is the g in Test
PROGRAM Test
MODULE SomeConstants USE SomeConstants, &
IMPLICIT NONE GravityG => g
REAL, PARAMETER :: PI = 3.1415926 IMPLICIT NONE
REAL,
, PARAMETER :: g = 980 INTEGER :: g
INTEGER :: Counter
END MODULE SomeConstants END PROGRAM Test

MODULE Compute
USE SomeConstants, ONLY : PI, g
IMPLICIT NONE
without ONLY, Counter would
REAL :: Counter
appear in MODULE Compute
CONTAINS
causing a name conflict!

END MODULE Compute 44
Compile Your Program: 1/4
Suppose a program consists of the main
program main.f90 and 2 modules Test.f90
and Compute.f90.
p In ggeneral,, they
y can be
compiled in the following way:
f90 main.f90 Test.f90 Compute.f90 o
o main

However, some compilers may be a little more


restrictive List those modules that do not use any
restrictive.
other modules first, followed by those modules that
only use those listed modules
modules, followed by your
main program.

45
Compile Your Program: 2/4
Suppose
pp we have modules A,, B,, C,, D and E,, and C
uses A, D uses B, and E uses A, C and D, then a
safest way to compile your program is the
following command:
f90 A.f90 B.f90 C.f90 D.f90 E.f90 main.f90 o main

Since modules are supposed to be designed and


developed separately, they can also be compiled
separately to object codes:
f90 c
c test.f90
test f90

The above compiles a module/program in file


t t f90 to
test.f90 t it
its object d test.o
bj t code t t
46
This means compile only
Compile Your Program: 3/4
Suppose
pp we have modules A, B, C, D and E, and C
uses A, D uses B, and E uses A, C and D.
Since modules are developed separately with
some specific
ifi functionality
f ti lit in
i mind,
i d one may
compile each module to object code as follows:
f90 c
c A.f90
f90 c B.f90
If your compiler is picky, some modules
f90 c C.f90
may have to compiled together!
f90 c D.f90
f90 c E.f90
Note
N t th
thatt th
the order
d iis still
till iimportant.
t t ThThe above
b
generates object files A.o, B.o, C.o, D.o
and E.o
47
Compile Your Program: 4/4
If a main p
program
g in file p
prog2.f90
g uses
modules in A.f90 and B.f90, one may compile
and ggenerate executable code for p
prog2
g as
follows:
f90 A.o B.o prog2.f90 o
o prog2
If prog2.f90 uses module E.f90 only, the
following must be used since E.f90
E f90 uses A.f90,
A f90
C.f90 and D.f90:
f90 A
A.o
o C
C.o
o D
D.o
o E
E.o
o prog2
prog2.f90
f90 o
o prog2
Note the order of the object files.
48
Example 1
The combinatorial coefficient of m and n (m n) is
Cm,n = m!/(n! (m-n)!).
MODULE FactorialModule PROGRAM ComputeFactorial
IMPLICIT NONE USE FactorialModule
CONTAINS IMPLICIT NONE
INTEGER FUNCTION Factorial(n)
i l( ) INTEGER :: N,
N R
IMPLICIT NONE READ(*,*) N, R
INTEGER, INTENT(IN) :: n WRITE(*,*) Factorial(N)
other
ot e statements
state e ts WRITE(*,*) Combinatorial(N,R)
END FUNCTION Factorial END PROGRAM ComputeFactorial
INTEGER FUNCTION Combinatorial(n, r)
IMPLICIT NONE
INTEGER,
G INTENT(IN)
( ) :: n, r
other statements Combinatorial(n,r) uses
END FUNCTION Combinatorial Factorial(n)
END MODULE FactorialModule

49
Example 2
Trigonometric functions use degree.
MODULE MyTrigonometricFunctions PROGRAM TrigonFunctTest
IMPLICIT NONE USE MyTrigonometricFunctions
REAL, PARAMETER :: PI = 3.1415926 IMPLICIT NONE
REAL, PARAMETER :: Degree180 = 180.0 REAL :: Begin = -180.0
REAL, PARAMETER :: R_to_D=Degree180/PI REAL :: Final = 180.0
REAL, PARAMETER :: D_to_R
D to R=PI/Degree180
PI/Degree180 REAL :: Step = 10.0
CONTAINS REAL :: x
REAL FUNCTION DegreeToRadian(Degree) x = Begin
IMPLICIT NONE DO
REAL, INTENT(IN)
( ) :: Degree IF (x
( > Final)
i l) EXIT
DegreeToRadian = Degree * D_to_R WRITE(*,*) MySIN(x)
END FUNCTION DegreeToRadian x = x + Step
REAL FUNCTION MySIN(x)
yS ( ) END DO
IMPLICIT NONE END PROGRAM TrigonFunctTest
REAL, INTENT(IN) :: x
MySIN = SIN(DegreeToRadian(x))
END FUNCTION MySIN
SIN
other functions
50
END MODULE MyTrigonometricFunctions
INTERFACE Blocks: 1/5
Legacy Fortran programs do not have internal
subprograms in PROGRAMs or MODULEs.
These subprograms are in separate files
files. These
are external subprograms that may cause some
compilation problems in Fortran 90
90.
Therefore, Fortran 90 has the INTERFACE block
f a program or a module
for d l tto know
k the
th ttype off
the subprograms, the intent and type of each
argument,t etc.
t

51
INTERFACE Blocks: 2/5
Consider the following triangle area program.
How does the main program know the type and
number of arguments of the two functions?
LOGICAL FUNCTION Test(a, b, c) PROGRAM HeronFormula
IMPLICIT NONE IMPLICIT NONE
REAL, INTENT(IN) :: a, b, c some important here
LOGICAL :: test1, test2 REAL :: a, b, c
test1 = (a>0.0) .AND. (b>0.0) .AND. (c>0.0) REAL :: TriangleArea
test2 = (a+b>c) .AND. (a+c>b) .AND. (b+c>a) DO
Test = test1 .AND. test2 READ(*,*) a, b, c
END FUNCTION Test IF (Test(a,b,c)) EXIT
END DO
REAL FUNCTION Area(a, b, c) TriangleArea
g = Area(a, b, c)
IMPLICIT NONE WRITE(*,*) TriangleArea
REAL, INTENT(IN) :: a, b, c END PROGRAM HeronFormula
REAL :: s = (a + b + c) / 2.0
Area = SQRT(s*(s-a)*(s-b)*(s-c))
END FUNCTION Area
52
file area.f90 file main.f90
INTERFACE Blocks: 3/5
An INTERFACE block has the followingg syntax:
y
INTERFACE
type FUNCTION name(arg-1, arg-2, ..., arg-n)
type, INTENT(IN) :: arg-1
type, INTENT(IN) :: arg-2
..........
type INTENT(IN) :: arg-n
type, arg n
END FUNCTION name
SUBROUTINE name(arg-1, arg-2, , arg-n)
type, INTENT(IN or OUT or INOUT) :: arg-1
type, INTENT(IN or OUT or INOUT) :: arg-2
..........
type, INTENT(IN or OUT or INOUT) :: arg-n
END SUBROUTINE name
....... other functions/subroutines .......
END INTERFACE

53
INTERFACE Blocks: 4/5
All external subprograms should be listed
between INTERFACE and END INTERFACE.
However only the FUNCTION and SUBROUTINE
However,
headings, argument types and INTENTs are
needed No executable statements should be
needed.
included.
Th argumentt names do
The d nott have
h to
t be
b id
identical
ti l
to those of the formal arguments, because they
place holders in an INTERFACE block.
are place-holders block
Thus, a main program or subprogram will be
able to know exactly how to use a subprogram.
54
INTERFACE Blocks: 5/5
Return to Herons formula for triangle
g area.
The following shows the INTERFACE block in a
main program.
p g
LOGICAL FUNCTION Test(a, b, c) PROGRAM HeronFormula
IMPLICIT NONE IMPLICIT NONE
REAL INTENT(IN) :: a,
REAL, a b,
b c INTERFACE
LOGICAL :: test1, test2 LOGICAL FUNCTION Test(x,y,z)
test1 = (a>0.0) .AND. (b>0.0) .AND. (c>0.0) REAL, INTENT(IN)::x,y,z
test2 = (a+b>c) .AND. (a+c>b) .AND. (b+c>a)
Test = test1 .AND.
AND test2
END FUNCTION Test
END FUNCTION Test REAL FUNCTION Area(l,m,n)
REAL, INTENT(IN)::l,m,n
REAL FUNCTION Area(a, b, c) END FUNCTION Area
IMPLICIT NONE END INTERFACE
REAL, INTENT(IN) :: a, b, c other statements
REAL :: s END PROGRAM HeronFormula
s = (a + b + c) / 2.0
Area = SQRT(s*(s-a)*(s-b)*(s-c))
END FUNCTION Area
55
file area.f90 file main.f90
The End

56

You might also like