Book: Fortran 95-2003 for Scientists
and Engineers, by S. J Chapman
Transparencies prepared by Anthony
T. Chronopoulos
CS1073
CHAPTER 1
Chapter 1 Intro. to Computers and the Fortran Language
The Computer
In summary, the major components of the
computer are:
CPU
Main Memory
Secondary Memory
Input Devices (e.g. keyboard, tapes etc)
Output Devices (e.g. display, monitor, tapes etc).
Chapter 1 Intro. to Computers and the Fortran Language
The CPU
The Central Processing Unit is "heart“ (or better
“brain”) of a computer.
The CPU consists of three main parts:
The Control Unit - coordinates activities of the
computer
The Arithmetic Logic Unit (ALU) - performs the
calculations
Registers - store a small amount of data and
instructions
Chapter 1 Intro. to Computers and the Fortran Language
• Main Memory (RAM)
It is larger than the Registers and smaller than
the hard drive.
It temporarily stores the program currently being
run by the computer and also the data required
by the programs.
RAM is volatile, i.e. when power is interrupted,
then what was stored in RAM is lost.
Chapter 1 Intro. to Computers and the Fortran Language
Secondary Memory
It is a permanent (non-volatile) storage.
The hard drive is the best example, but also
USB, CDs, tapes, etc. The size of hard drives
is larger than that of RAM. However,
accessing data stored on a hard drive (or other
secondary memory) takes much longer (5-10
times) than from RAM.
Chapter 1 Intro. to Computers and the Fortran Language
Computer Languages
Each computer has its own machine language
(Assembly) used to execute very basic
operations. Operations are: load and store
(data, to and from memory), and add, subtract,
multiply, or divide.
The problem with a machine language is that it
is very difficult to program and use, and also it
can be unique for a computer.
Chapter 1 Intro. to Computers and the Fortran Language
Thus, computer scientists design high-level language
that are easy to program and use. The programs must
be converted to a machine-language (by compilers and
linkers) for the computer to run them. Examples are
Fortran, C, C++, Java etc.
The benefit of a high-level language (e.g. Fortran) is
that a program and can be compiled on any machine
that has a Fortran compiler.
Chapter 1 Intro. to Computers and the Fortran Language
Data Representation in a Computer
Data is represented by millions of switches, each of
which can be either ON (1) or OFF (0). 0 and 1 are
the two binary digits (bits).
We use a combination of 0's and 1's to represent the
other numbers (and characters as well).The smallest
common combination of bits (0's and 1's) is called a
byte. A byte is a group of 8 bits. A word is a group
of 2, 4, or 8 bytes. Our PCs have 4-byte words.
Chapter 1 Intro. to Computers and the Fortran Language
• The Binary Number System
The number system used by humans is the
decimal system. The decimal system is a
base=10 system.
There are 10 digits (0-9). Each digit in a number
represents a power of 10.
The number 221 is:
2 * 10^2+ 2 * 10^1 + 1 * 10^0
(where 10^i is 10 raised to exponent i =0,1,2,..).
Chapter 1 Intro. to Computers and the Fortran Language
Similarly, converting a number from binary
(base 2) to decimal (base 10).
The number 101:
1 * 2^2+ 0 * 2^1 + 1 * 2^0 = 4 +0+ 1 = 5
If n bits are available, then those bits can
represent 2^n possible values.
e.g. One byte (n=8 bits) can represent 256
possible values. Two bytes (n=16 bits) can
represent 65,536 possible values.
Chapter 1 Intro. to Computers and the Fortran Language
Which of the following ranges would best
describe the possible values of a byte?
(1) 0 ,.., 255 (2) 1 ,.., 256 (3) -127 ,.., 128
(4) -128 ,.., 127 . The answer is (4).
The reason is that the computer must store both
positive and negative integers. The following
example illustrates how this can be achieved.
Chapter 1 Intro. to Computers and the Fortran Language
Example from the car odometer/milometer. (Note: content not in Book
will not be used in Exams)
Milometer readings during travel.
(a)
0
0
0
0
0
0
0
0 initial milometer reading
(b)
0
0
0
0
0
0
0
2 after two miles
(c)
0
0
0
0
0
0
0
1 after reversing one mile
0
after reversing one more
0 mile
9
after reversing one more
9 mile
(d)
(e)
0
9
0
9
0
9
0
9
0
9
0
9
Chapter 1 Intro. to Computers and the Fortran Language
e.g. Storage of 8-digit integers, in base=10 system:
(a)
5
0
0
0
0
0
0
0 represents -50 000 000
(b)
5
0
0
0
0
0
0
1 represents -49 999 999
(c)
9
9
9
9
9
9
9
9 represents -1
(d)
0
0
0
0
0
0
0
0 represents 0
(e)
0
0
0
0
0
0
0
1 represents +1
(f)
4
9
9
9
9
9
9
9 represents +49 999 999
Chapter 1 Intro. to Computers and the Fortran Language
e.g. Storage of (4-bit) integers:
1000
-8
1001
-7
1110
-2
1111
-1
0000
0
0001
+1
0010
+2
0111
+7
When using the binary system, the effect is that
if the first binary digit (or bit) is a one then the number is negative,
while if it is zero the number is positive.
Chapter 1 Intro. to Computers and the Fortran Language
 Two other number systems that are also useful
are octal (base 8) and hexadecimal (base 16).
 Table 1-1 shows the conversion between these
systems for the decimals: 0,1, …,15
Chapter 1 Intro. to Computers and the Fortran Language
Types of Data
Three common types of data are stored in a
computer's memory: character, integer, real
Each type has unique characteristics and takes up
a different amount of memory.
Chapter 1 Intro. to Computers and the Fortran Language
Character Data
A typical system for representing character data
may include the following:
Letters: A through Z and a through z
Digits (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Miscellaneous symbols, e.g. (", ', ?, ., <, >, =, %,
&)
Chapter 1 Intro. to Computers and the Fortran Language
• In the past, it has been common to use just one
byte of memory to represent a maximum of
256 characters (ASCII).
• To represent characters found in many
languages, one can use use 2 bytes of memory
which allows 65,536 possible characters
(Unicode).
Chapter 1 Intro. to Computers and the Fortran Language
Integer Data
Integer data ( e.g. -1, -355, 0, 1993) are represented
exactly on computers. However, only a finite number
can be stored. Most machines will use 4 bytes
of memory to represent integers.
Smallest n-bit integer: -2^(n-1)
Largest n-bit integer: 2^(n-1) - 1
e.g. n=32 for 4-byte numbers.
Chapter 1 Intro. to Computers and the Fortran Language
With 4 bytes of memory we can represent
numbers in the approx. range [-2.15*billion,
2.15*billion].
Outside this range we get arithmetic overflow.
Integer data limitations: (1) No fractional parts.
(2) It is not possible to represent very large
positive integers or very small negative
integers.
Chapter 1 Intro. to Computers and the Fortran Language
Real Data
The real data type stores numbers in a format
similar to scientific notation.
For example, the speed of light in a vacuum is
about 299,800,000 meters per second. The
number in scientific notation would be 2.998
* 10^8 (m/s) meters per second.
Chapter 1 Intro. to Computers and the Fortran Language
A format similar to scientific notation will be
used to represent real numbers in FORTRAN.
Real numbers occupy 4 bytes of memory. These
4 bytes will be divided as follows:
3 byte for the fraction (or mantissa)
1 byte exponent
The mantissa will be a number between -1 and 1.
The exponent will contain the power of 2
required to scale the number to its actual value.
Summary: Numbers represented on the computers
Integer numbers are stored in the computer as they are (e.g. 1321 ).
The real numbers are converted. Consider any non-zero real number as
a fraction lying between 0.1 and 1.0, called the mantissa, which is multiplied
or divided by 10 a certain number of times, where this number is called the
exponent. e.g. 17877.0 (in fraction, base=10 form): 0.17877x10^5
a  10
b
exponent
mantissa
The same technique as was used for integers to distinguish positive and
negative numbers will be used for both the mantissa and the exponent.
Chapter 1 Intro. to Computers and the Fortran Language
Precision and Range
Precision refers to the number of significant digits that
can be preserved in a number (on a computer).
Based on the number of bits (or bytes) in the mantissa,
3 byte mantissa gives about 7 significant digits
(between 1.0 and -1.0) e.g. 12345678.4 is stored as
12345678.0. The difference (i.e. 0.4) is called the
round-off error.
Chapter 1 Intro. to Computers and the Fortran Language
Range is the difference between the largest and
smallest numbers that can be represented.
The number of bits in the exponent e.g.
1-byte exponent (with the 3-byte mantissa)
allows a range of approximately 10^-38 to
10^38 (i.e. [10^-38 , 10^38] )
Chapter 1 Intro. to Computers and the Fortran Language
Evolution of Fortran:
Fortran I: Fig. 1-5
Fortran 77: Fig. 1-6
Fortran 90/2003: Fig 1-7
Chapter 1 Intro. to Computers and the Fortran Language
• Recommended Problems (not to be handed
in)
• Page 12 , Quiz 1 (answers are on the back):
1(a),2(a),6,7
CS1073
CHAPTER 2
Chapter 2: Basic Elements of Fortran
2.2 The Fortran Character Set (Table 2-1)
The following are valid in a Fortran 90/95 program:
alpha-numeric: a-z, A-Z, 0-9, and _ (the
underscore);
arithmetic symbols: +, -, *, /, **
miscellaneous symbols: e.g.
,
comma
.
decimal point
<
less than
etc
Chapter 2: Basic Elements of Fortran
2.3 Structure of a FORTRAN Statement
A program consists of a series of statements designed to
accomplish the goal to be accomplished.
There are two basic types of statements:
Executable statements describe the actions taken by
the program (additions, subtractions,
multiplications, divisions).
Non-executable statements provide information
necessary for proper operation of the program.
Chapter 2: Basic Elements of Fortran
Rules on Fortran statements:
Each line may be up to 132 characters long.
A statement too long to fit in a single line may
be continued on the next line by ending the
current line with an & (ampersand). e. g.
output = input1 + input2 ! sum the inputs
output = input1 &
! Also, sum the inputs
+ input2
Chapter 2: Basic Elements of Fortran
The above two statements are equivalent.
Commenting your code is very important. To
comment in FORTRAN, one uses the
exclamation point (!).
All comments after the ! are ignored by the
compiler
Chapter 2: Basic Elements of Fortran
One can use labels in some statements. A label
can be any number between 1 and 99999.
Statement labels are less common in modern
FORTRAN.
Chapter 2: Basic Elements of Fortran
2.4 Structure of a FORTRAN Program
A FORTRAN program can be divided into three
sections:
Declarations - This section consists of a group of nonexecutable statements at the start of the program.
Execution - This section consists of one or more
statements describing the actions to be performed
by the program.
Termination - This section consists of a statement (or
statements) telling the computer to stop/end running
the program.
Chapter 2: Basic Elements of Fortran
The program (in Fig. 2-1) reads two numbers as input, multiplies
them, and prints out the result
PROGRAM my_first_program
! Purpose:
! To illustrate some of the basic features of a Fortran program.
!
! Declare the variables used in this program.
INTEGER :: i, j, k
! All variables are integers
! Get two values to store in variables i and j
WRITE (*,*) 'Enter the numbers to multiply: '
READ (*,*) i, j
Chapter 2: Basic Elements of Fortran
! Multiply the numbers together
k=i*j
! Write out the result.
WRITE (*,*) 'Result = ', k
! Finish up.
STOP
END PROGRAM my_first_program
Chapter 2: Basic Elements of Fortran
Discussion of Program Above
The first statement of this program begins with the word
PROGRAM. This is a non-executable statement
that specifies the name of the program to the
FORTRAN compiler.
The name may be up to 31 characters long and be any
combination of alphabetic characters, digits, and the
underscore.
The first character must be a letter.
The PROGRAM statement must be the first line of the
program.
Chapter 2: Basic Elements of Fortran
The Declaration Section
This section begins with a comment stating that variable
declarations are to follow.
The declaration begins with the data type (INTEGER)
followed by two colons and then the variable name.
A comment follows the variable name. Every variable
must be commented as to its purpose in the
program.
These statements are non-executable.
Chapter 2: Basic Elements of Fortran
The Execution Section
The first statement in this section is the WRITE
statement that tells the user to enter the input.
The second statement will read the input and assign the
values to the corresponding variables.
The third statement multiplies the two variables and the
product is assigned to a third variable.
The last executable statement prints the product to the
screen.
Chapter 2: Basic Elements of Fortran
The Termination Section
The STOP statement tells the computer to stop
running the program.
The use of the STOP command is optional here.
The END PROGRAM statement informs the
compiler that no more statements exist.
Chapter 2: Basic Elements of Fortran
Compiling and Executing the FORTRAN
Program
Before a program can be run (executed) it must
be compiled into an executable program.
In this process the code may also be linked to
various system libraries.
Chapter 2: Basic Elements of Fortran
2.5 Constants and Variables
A constant is a data object that is defined before
a program is executed and it does/can not
change during the execution of the program.
Constants are used in developing a good/correct
programs in solving math problems (e.g.
the circle constant PI ).
Chapter 2: Basic Elements of Fortran
A variable is a data object that can change value
during the execution of a program.
Referring to the sample program above:
The data objects i,j,k are variables.
Each variable (or constant) must have a unique
name inside the program.
Chapter 2: Basic Elements of Fortran
The names may contain up to 31 characters and
any combination of alphabetic characters,
digits, and the underscore.
The first character must always be alphabetic.
 The name we assign a variable (or constant)
should be meaningful in terms of the purpose
that it is used to solve the problem (e.g.
 time, distance, grade etc).
Chapter 2: Basic Elements of Fortran
2.5.1 - 2.5.3 Types of Data
There are five intrinsic (or "built-in") types of
data:
Integer
Real
Character
There are two other intrinsic types that will be
introduced later (Logical, Complex).
Chapter 2: Basic Elements of Fortran
Integers
Integers are numbers without a decimal point.
e.g. -999 , +17, 1234 (not allowed: 1,234 , +17. )
No commas may be embedded within an integer
constant.
If the number is positive, the sign + is optional, but the is required to for negative.
Integer variables contain the value of an integer data
type.
There is a maximum and a minimum value that an
integer can take. The range is determined by how
much memory is (in terms of no. of bytes) given to
a variable of the integer type.
Chapter 2: Basic Elements of Fortran
Real Numbers
Real (or floating-point) numbers represent values
with a fraction.
Real constants can be written with or without an
exponent. e.g. 10. , -999.9, 1.0E-3 (i.e. 0.001
or .001 )
Not allowed: 1,000. , 111E3, -12.0E1.5, 1.0x
10^-3
Chapter 2: Basic Elements of Fortran
The mantissa should contain a decimal point. A
real variable is a variable that contains the
value of a real data type.
There is a maximum and a minimum value that a
real var/constant can take. The range is
determined by how much memory is (in
terms of no. of bytes) given to a variable of
the real type.
Chapter 2: Basic Elements of Fortran
Characters
A character constant is a string of characters
enclosed in a single or double quotes.
Any characters representable on a computer (not
just the Fortran characters) are legal in a
character context (i.e. if enclosed in quotes).
e.g. ‘this is’, ‘ ‘, ‘[^]’, “3.1345”
Chapter 2: Basic Elements of Fortran
Mismatching or using an odd number of quotes
are common mistakes in programming.
e.g. not correct character: ‘this is , ‘this is”
A character variable is a variable containing a
value of character data type. e.g. c = ‘this is’
Character variables/constants with more than one
character are often referred to as strings.
The character constant '8' is different from the
integer constant 8.
Chapter 2: Basic Elements of Fortran
2.5.4, 2.10 Variables and the IMPLICIT
NONE
Checking a constant (e.g.7, 3.14156, 'John'), it is
easy to determine which type it may
be. However, for a variable, we must assign
a type to that variable. Assigning a type
reserves the memory needed to store the data
expected (e.g.4 bytes for: 7 , 3.14156 and
2 bytes/letter for: 'John').
Chapter 2: Basic Elements of Fortran
There is a default type given to all variables for which
a type is not explicitly given. This is used in Fortran
versions before Fortran 90. In this case, the first
letter of the names of variables or constants
determines the type.
Prior to Fortran 90: Var/const names with letters
i,j,k,l,m,n as first letter imply INTEGER , where as
the rest of the letters imply REAL.
Note: Fortran upper/lower case is the same. We use
lower case for var’s names e.g. i, x, c
and upper case for key-words (e.g. READ(*,*), STOP).
Chapter 2: Basic Elements of Fortran
In Fortran 90/95, 2003 we declare the type of
The REAL, INTEGER for all var/constants e.g.
INTEGER :: height
REAL :: second
The IMPLICIT NONE used after the keyword
PROGRAM means that we must specify a
type for each variable you declare.
Chapter 2: Basic Elements of Fortran
e.g.
PROGRAM test_1
i=123
time =10.0 ! Here time i is time is REAL type
OR
PROGRAM test_1
IMPLICIT NONE
INTEGER :: i
REAL :: time
i=123
time=10.0
Chapter 2: Basic Elements of Fortran
Character types are declared similarly, e.g.
CHARACTER(len=5) :: name
The above will declare a variable called name
that can be up to 5 characters long. If the
(len = ) is omitted, the length is assumed to be 1.
An alternative is e.g.
CHARACTER(20) :: last_name
Chapter 2: Basic Elements of Fortran
2.5.5 Keeping Constants, Consistent
If we need a named constant in our program e.g. circle:
PI = 3.141593
We declare a constant in FORTRAN using the
PARAMETER after the type. e.g
INTEGER, PARAMETER :: num= 80
REAL, PARAMETER :: PI = 3.141593
CHARACTER(len = 7) , PARAMETER :: ERROR=
‘error 1’
Chapter 2: Basic Elements of Fortran
2.6 Assignment Statements and Arithmetic
Calculations
An assignment statement calculates a Mathexpression on the right of the equal sign and
assigns it to the variable on the left of the
equal sign.
variable_name = expression/value
e.g. i = i+1
Chapter 2: Basic Elements of Fortran
Binary Operators (+, -, *, /, **)
We can use the arithmetic operators above to
program calculations.
x=3+4
y = a*b
z = radius ** 2
The values (expressions) are resolved and
assigned to the variables on the left.
Chapter 2: Basic Elements of Fortran
Unary Operators
Unary operators (just a single operand) , but the
negate operator is one that is most common.
x = +2
x = -a
Here, take the value on the right, apply the
operator and assign it to the variable on the
left.
Chapter 2: Basic Elements of Fortran
Arithmetic rules in FORTRAN:
No two operators can occur side by side. e. g.
x = a * -b is illegal. x = a * (-b) is allowed.
Implied multiplication is illegal e. g. x = yz
instead: x = y * z, is legal.
Parentheses can be used to enforce precedence in
an expression. e. g. 2**((8+2)/5) =
2**(10/5)= 2**2 =4
Chapter 2: Basic Elements of Fortran
2.6.1 Integer Arithmetic
Integer arithmetic involves only integer data.
Integer arithmetic always produces an integer
result.
With division, the fractional part is truncated by
the computer. e.g. 7/4 =1 , 4/4 =1 , 3/4 = 0
Chapter 2: Basic Elements of Fortran
Integers should never be used to calculate realworld quantities, such as distance, speed, or
time. Integers should only be used for things
that are intrinsically integer in nature, such as
counters.
Chapter 2: Basic Elements of Fortran
2.6.2 Real Arithmetic
Real (or floating-point) arithmetic involves real
data.
e.g. 7./4. =1.75 , 4./4. =1. , 3./4. = 0.75
1./3. = 0.3333333
Note: 3.*(1./3.) is not equal to 1. (on some
computers)
But: 2.*(1./2.) = 1.
Chapter 2: Basic Elements of Fortran
2.6.3 Hierarchy of operations
1. Contents of “( )” are evaluated first, starting from the
innermost and going outward.
2. Exponentials are evaluated, from right to left.
3. Multiplies/divides are evaluated, from left to right.
4. Adds/subtracts are evaluated, from left to right.
e.g. a=3.,b=2.,c=5.,d=4.,e=10.,f=2.,g=3.
output =a*b+c*d+e/(f**g**1)
output = … = 27.25
Chapter 2: Basic Elements of Fortran
2.6.4 Mixed-Mode Arithmetic
Integer arithmetic result is an integer.
Real numbers arithmetic result is a real number.
What if we mix real/integers ?
In memory, the integer and real number are stored
differently. So, the machine must first convert the
integer into its real number equivalent before
performing an operation. This conversion will
allow real number arithmetic to be performed.
Chapter 2: Basic Elements of Fortran
Examples:
1 + 1/4 = 1
1 + 3.0/4 = 1.75
1. + 3/4= 1.
The computer converts an integer to a real, there are cases when
we want control when a conversion should be made. Fortran
simple functions (see Table 2-3, x is real and i is integer)
: e.g. x=2.9 (truncate, round, select nearest integer
below/above x): INT(x)=2, NINT(x)=3, FLOOR(x)=2,
CEILING(x)=3, INT(-x)=-2, NINT(-x)=-3, FLOOR(-x)=-3,
CEILING(-x)=-2
Chapter 2: Basic Elements of Fortran
2.6.5 Mixed-Mode Arithmetic and Exponentiation
Cases: (I) result = y**n, y REAL, n INTEGER
Converts to result = y*y*…*y (n times)
e.g (-2.)**2 result is 4. (II) result = y**x, y REAL, x
REAL . We need the Math formula: y^x =
exp(xlny) and functions for natural exponential/log
functions. This is done for us by Fortran for y >=0;
e.g. 4.**(-0.5) is legal. (III) (-2.)**2.0 is illegal
and gives run-time error.
Chapter 2: Basic Elements of Fortran
2.7 Intrinsic Functions
In Math, a function is an expression that accepts one or
more input values and calculates a single result
from them. e.g.
f(x) = 3 +2*x+ x * *2
For an x value, can one evaluate this function?
There are a number of standard (library) functions that
are available in Fortran, such functions are called
intrinsic functions. Later this semester we will be
writing our own functions, which are called userdefined functions.
Chapter 2: Basic Elements of Fortran
The function f(x) accepts a value x and it
computes the result. The value x is called the
argument of the function.
e.g. f(x, y) = x + y * 2 , has arguments, x and y.
A set of intrinsic math functions are listed in
Table 2-4 (trigonometric, sqrt, log, exp, max,
min). Please make use in the Fortran
programs. e.g. y = SIN(theta)
Chapter 2: Basic Elements of Fortran
This statement will take the sine of theta (in
radians) and assign the result to y.
Variable “y” should be real and “theta” can be
real or integer.
Can “theta” be in degrees?
If so, it must be converted to radians, multiplying
the value in degrees by 3.14159/180.
Chapter 2: Basic Elements of Fortran
y = SIN(theta * (3.141593/180.))
The factor DEG2RAD = 3.141593/180. will be
evaluated first and multiplied by theta. This value
(theta in radians) will then be used in the SIN
function.
Table 2-3 and Table 2-4 list some common intrinsic
functions.
Argument type (Real, Integer, or Character)
Result type (Real, Integer, or Character)
Notice that some (generic) functions (e.g. ABS(x) ) can
accept either type and return either type depending
on the type of the input argument.
Chapter 2: Basic Elements of Fortran
2.8 List-Directed Input and Output
To make assignments and do computations, we
need input for the calculations and to output
the results.
The term list-directed input means that the
types of the variables in the variable list
determine the required format of the input
data.
Chapter 2: Basic Elements of Fortran
The READ statement is in the form:
READ (*, *) input_list
where the input_list is the list of variables into
which the values being read are stored.
The (*, *) contain control information for the
read ( more details, in chapter 5).
Chapter 2: Basic Elements of Fortran
Examples of input of data:
PROGRAM input_example
INTEGER :: i, j
REAL :: a
CHARACTER (len=12) :: chars
READ (*,*) i, j,a,chars ! e.g. 1,2,3., ‘this course’
END PROGRAM input_example
Chapter 2: Basic Elements of Fortran
PROGRAM input_example_2
INTEGER :: i, j,k,l
READ (*,*) i, j
READ (*,*) k,l
END PROGRAM input_example_2
e.g.
1,2,3,4
5,6,7
Then the values stored are: i=1, j=2, k=5,l=6
Chapter 2: Basic Elements of Fortran
The list-directed output statement is in the
form:
WRITE (*, *) output_list
Again, the term list-directed implies that the
types of the values in the output list of the
write statement determine the format of the
output data.
Chapter 2: Basic Elements of Fortran
Example of output:
PROGRAM output_example
INTEGER :: ix
REAL:: theta
ix=1
theta=3.141593
WRITE(*,*) ‘ix =‘, ix
WRITE(*,*) ‘theta = ‘, theta, ‘COS(theta) =‘, COS(theta)
END PROGRAM output_example
Result printed is: ix=1
theta=3.141593 COS(theta) = -1.0
Chapter 2: Basic Elements of Fortran
2.9 Initialization of Variables
Initialization statements by three methods: (1)
assignment, (2) READ, (3) part of type declaration
e.g.
PROGRAM init123 ! Three methods to initialize
INTEGER :: i, j,k=3 ! initialize
i=1 ! initialize
READ (*,*) j ! initialize
WRITE(*,*) i, j,k
END PROGRAM input_example
Chapter 2: Basic Elements of Fortran
2.9 The IMPLICIT NONE statement
e.g.
PROGRAM test_1
! IMPLICIT NONE
REAL :: time=10.0
WRITE(*,*) “Time =“, tmie
END PROGRAM test_1
Wrong result is: Time =0.0 . But with IMPLICIT
NONE, we get a compile error.
Chapter 2: Basic Elements of Fortran
2.11 Program Examples (Fig 2-6, Fig2-8)
Example 2-3 (Fig 2-6) Design a FORTRAN
program to read an input temperature in
degrees Fahrenheit (F), to convert in Kelvin
(K), and to write out the result.
What does this program output?
The temperature in kelvins.
What is the input?
The temperature in Fahrenheit.
Chapter 2: Basic Elements of Fortran
How is the conversion done?
Temperature in Kelvins = (5./9.) *(T (in F) – 32.)
+ 273.15
So, what variables are we looking at?
Temperature in K (REAL)
Temperature in F (REAL)
A Kelvins conversion constant (273.15)
Chapter 2: Basic Elements of Fortran
How will we know if the program works correctly?
We know 212 Fahrenheit is equal to 373.15 K,
and -110F is equal to 194.26 K.
The algorithm steps:
1. Prompt user for input.
2. Read in data from user.
3. Calculate to Temperature in Kelvins
4. Print output and Terminate the program.
Chapter 2: Basic Elements of Fortran
Sample Runs of the Program:
Enter the temperature in Fahrenheit:
-110
The temperature -110.0 F is 194.26111
kelvins.
Enter the temperature in Fahrenheit:
212
The temperature 212.0 F is 373.15 kelvins.
Run Fortran Programs
Fortran commands to :
(1) Compile (gives .o files)
(2) Link (the possibly several .o files into .exe
file)
(3) Execute ( run the .exe file)
Note: In gfortran on MS windows, (1) and (2)
are combined into a single step.
Chapter 2: Basic Elements of Fortran
Example 2-4 (Electr. Engineer., Fig 2-8)
Design a FORTRAN program to calculate
Real, Reactive and Apparent power.
Equations of circuit:
I=V/Z
(2-3) (Z is ‘load impedance’)
P=V I cos(theta) (2-4) ! power
Q=V I sin(theta) (2-5) ! reactive power
S=V I
(2-6) ! apparent power
PF= cos(theta) (2-7) ! power factor
Chapter 2: Basic Elements of Fortran
The algorithm steps:
1. Prompt user for input.
2. Read-in data from user.
3. Calculate p q, s, pf ( (React., Real, Apparent) powers,
power factor)
4. Print output and Terminate the program.
Test with inputs of known results: V=120, Z=5,
Theta=30 degrees then: I=24, P=2494, Q=1440,
S=2880, PF=0.86603
Chapter 1 Intro. to Computers and the Fortran Language
Recommended Problems (not to be handed in)
• Page 35 , Quiz 2-1 (answers are on the back):
2,4,12,15,18,21,23,24
• Page 45 , Quiz 2-2 (answers are on the back):
2(b,e,h), 3(c,d), 4(b,d,e), 5,6,7
• Page 53 , Quiz 2-3 (answers are on the back):,
2,3, 4, 5,6,7,8
• Exercises pp.73-76: (do as many of) 2-1,..,2-9
CS1073
CHAPTER 3
Program Design and Branching
Chapter 3
Program Design and Branching Structures
Many problems are just too large to program directly
their solutions. Top-Down design means to start with
a large task and break it down into smaller ones
(subtasks), which we can program independently.
Key Ideas in Top-Down Design: (1) Divide the larger
task into smaller sub-tasks. (2) Code and test each
sub-task. (3) Put together the solution.
Chapter 3
Steps of Program Design in the Top-Down Approach:
1. State the problem.
2. Define inputs and outputs.
3. Design the algorithm.
4. Turn the solution into Fortran statements.
5. Test (and debug) the Fortran program.
Which step would require the most time? Step 5!
How can we reduce the time for this step? By spending
more time on steps 1-4.
Chapter 3
The constructs to build an algorithm use either
flowcharts or pseudocode. We will use the
pseudocode, which describes the steps in English and
mathematical formulas ready to be programmed.
Example (pseudocode to convert the temperatures):
• Prompt the user for the input temperature in
Fahrenheit
• Read temperature in degrees Fahrenheit (temp_f)
• temp_k  (5. / 9.) * (temp_f - 32.) + 273.15
• Write temperature in Kelvin degrees
Chapter 3
3.3 Logical Constants, Variables, and Operators
The logical data type can store one of two values:
.TRUE. or .FALSE. A logical variable is a variable
containing a value of the logical data type and can be
declared as follows:
PROGRAM example
LOGICAL :: log1, log2 ! logical var’s
LOGICAL, PARAMETER :: logconst=.TRUE.
Executable statements
…
Chapter 3
Logical var’s/const’s are used in branch statements (using IF).
e.g. For computing cubic roots, for x >0 :
PROGRAM example_IF
IMPLICIT NONE
LOGICAL :: log1
REAL :: x=8. , cube_root
log1 = ( x > 1.E-10) ! logical var = logical expression
IF(log1) THEN
cube_root = EXP(LOG(x)/3.0 )
ELSE
cube_root =0.0
ENDIF
WRITE (*,*) 'log1=', log1, 'cube_root=', cube_root
END PROGRAM example_IF
Note: In Math: x^ 1/3 = e^(log(x)/3), and we must have x>0
Chapter 3
3.3.3 Relational Operators
Relational logic operators are operators with two
numeric (or character) operands that produces
a logical result. The new style operators were
introduced with FORTRAN 90.
e.g. > : (ABS(x) > 1.E-10)
Table 3-1 (next page) contains all the relational
logic operators in Fortran 90 and the old
versions (Fortran 77).
Chapter 3, Table 3-1Relational logic operators
New Old
Meaning
Style Style
== .EQ.
Equal to
/= .NE. Not equal to
> .GT. Greater than
Greater than or
>= .GE.
equal to
< .LT.
Less than
Less than or
<= .LE.
equal to
Chapter 3
Examples: Operation
Result
3<4
.TRUE.
3 /=4
.TRUE.
3>4
.FALSE.
‘A’ < ‘B’
.TRUE. (because characters are
evaluated in alphab. order)
Also, (7+2) < (10+1) .TRUE.
7+2 < 10+1
.TRUE.
4== 4.
.TRUE.
4 <=‘A’
illegal (compile error)
Chapter 3
3.3.4 Combinational Logic Operators
Combinational logic operators are operators with
one or two logical operands that yield a logical
result.
The operators are:
.AND., .OR., .NOT., .EQV., .NEQV.
Examples: Let a,b,c,d be real/integer variables.
Chapter 3
(a<b) .OR. (c<d)
‘(‘ , ‘)’ can be omitted
e.g. a<b .OR. c<d !But may confuse us; so use ‘(‘ , ‘)’
(a<b) .OR. (c<d)
e.g. For a = 2 , b = 3 , c = 5 , d = 3 the value of the
logical expressions above is .TRUE.
Let the logical expressions l1 = (a < b) and l2 = (c <
d) , the results of the operators are in
Tables 3-3(A,B) (which are called truth tables).
Chapter 3
Table 3-3, Combinational operators
log1 log2 log1.OR.log2 log1.AND.log2
true
true
true
true
true false true
false
false true true
false
false false false
false
log1
true
true
false
false
log2
true
false
true
false
log1.EQV.log2 log1.NEQV.log2
true
false
false
true
false
true
true
false
.NOT.log1
false
false
true
true
Chapter 3
. NOT. is a unary operator gives .TRUE. for value
.FALSE. and vice-versa
e.g. The following expressions are equivalent (e.g. for
values of variables: a = 2 , b = 3, c=5)
log1=
.NOT. (a<b .AND. b<c)
log2=
a>=b .OR. b>=c
i.e. log1.EQV.log2 = .TRUE.
Chapter 3
e.g. Mixed operations: (a+b) < (c+d) .OR. 3>=4
Precedence order :
1. arithmetic operators (*, +, etc, evaluated left-toright) ;
2. relational operators ( < , = =, etc, evaluated from
left to right)
3. .NOT.
4. .AND. (evaluated from left to right)
5. .OR. (evaluated from left to right)
6. .EQV. and .NEQV. (evaluated from left to right)
Chapter 3
Note: combinational operators are illegal to use with
real/integer/character e.g.
4 .AND. 3 (compile-error)
3.3.5 Logical values for Input/Output statements
When entering data, using READ(*,*), if the first
entered character is ‘T’ then .TRUE. is read in;
similarly for .FALSE.
3.3.6 Significance of Logical variables/expressions
They are mostly used with IF statements.
Chapter 3
3.4 Control constructs: Branches
Branches in Fortran allow us to execute (depending on the value
true/false of logical values/expressions) specific parts of the
program and skip other parts.
The block IF construct is:
IF (logical_expression) THEN
ELSE IF (logical_expression) THEN
IF(.NOT. (a < b. AND. b < c)) ! Example of block IF
x=a+b
! e.g. a=3,b=4, c=5
ELSE IF (a < b. AND. b < c)
x=c+b
ENDIF
Chapter 3 , 3.4.2 The ELSE and ELSE IF
3.4.2 The ELSE and ELSE IF :
IF (criterion_1) THEN
action_1
ELSE IF (criterion_2) THEN
action_2
ELSE IF (criterion_3) THEN
action_3
ELSE
action_4
END IF
A minimal block IF:
IF (criterion) THEN
action
END IF
Chapter 3
Example of Fortran program: The quadratic
equation (PROGRAM roots, Fig-3-10).
Examples of inputs to test the program:
x^2+5x+6 =0, roots: -2, -3
x^2+4x+4 =0, roots: -2 (double)
x^2+2x+5 =0, roots: -1+2i, -1-2i (complex)
Chapter 3
Example of Fortran program: Evaluating a
function of two variables (PROGRAM funxy,
Fig-3-12).
Test the program:
f(2,3) = 5
f(-2,3) = 7
f(2,-3) = 11
f(-2,-3) = 13
Chapter 3
3.4.4 The named block IF constructs:
[name:] IF (logical expression) THEN
statement1
ELSE IF (logical expression) THEN
statement1
ELSE
statement1
END IF
Chapter 3
3.4.5 Notes concerning use of block IF constructs:
Block IF may be nested:
outer: IF (x>0.) THEN
statement1
inner: IF (y<0.) THEN
statement1
END IF inner
statement1
END IF outer
Chapter 3
3.4.6 The logical IF statement:
e.g. IF(x<0.) y=-1
Note: Better to avoid it and use Block IF, instead.
3.4.7 The SELECT CASE construct
deals with many alternatives are mutually exclusive.
The case selector must be : integer, character, or logical
expression. But ‘real’ expressions are not allowed.
Chapter 3
[name:]SELECT CASE (case expression)
CASE (case selector) !mutually exclusive case
block of Fortran statements
CASE (case selector) !mutually exclusive case
block of Fortran statements
.
.
END SELECT name
Chapter 3
Example of Fortran program: Use SELECT
CASE to select the day of the week
(PROGRAM day_of_week, Fig-3-14).
Test: e.g.
1
Day= Sunday
Chapter 3
Example of Fortran program: Use characters
in a SELECT CASE construct
(PROGRAM weekday_weekend, Fig. 3-15).
Test: e.g.
Tuesday
Day Type= weekday
Chapter 3
Example: Assigning letter grades
90< grade
A
80< grade <=89 B
70< grade <=79 C
61< grade <=69 D
0< grade <=60 F
Chapter 3
(a) Solution without nested (start from highest grade and create
mutual exclusive logical exressions)
IF (grade > 90) THEN
WRITE(*,*) ‘The grade is A‘
ELSE IF (grade > 80) THEN
WRITE(*,*) ‘The grade is B‘
ELSE IF (grade > 70 ) THEN
WRITE(*,*) ‘The grade is C ‘
ELSE IF (grade > 61 ) THEN
WRITE(*,*) ‘The grade is D‘
ELSE
WRITE(*,*) ‘The grade is F‘
END IF
Chapter 3
(b) Solution using nested IF
(in textbook p. 111), to be avoided because it
may lead to errors.
(c) Solution using SELECT CASE
left as an exercise (not to be handed in).
Chapter 3
3.5 Debugging Fortran programs
We can insert WRITE(*,*) statements into the
program to print out important var’s at key points of the
program. e.g. Verify correctness of block IF:
WRITE(*,*) ‘At if1: var1 =‘, var1
if1: IF(sqrt(var1) >1.) THEN
WRITE(*,*) ‘At if1: sqrt(var1) >1. ‘
ELSE IF(sqrt(var1) <1.) THEN
WRITE(*,*) ‘At if1: sqrt(var1) <1. ‘
ELSE
WRITE(*,*) ‘At if1: sqrt(var1) == 1. ‘
END IF if1
Chapter 3
When we locate in which part of the program the error
occurs. We check the statements to discover it.
Examples of common errors with IF statements:
1. Check the relational operators e.g. maybe >=
is needed instead of > , etc.
2. When we test for equality of real var’s/const’s (unlike
integers), we can not use == .
We must use e.g. IF(ABS(x-10.) < 0.000001) THEN
IF(x==10.), for x real, may be false because in some
computer x=0.9999999 (which is 10.0).
Chapter 3
Recommended Problems (not to be handed in)
• Page 95 , Quiz 3-1 (answers are on the back):
1(a,b,d,f,h), 2
• Page 117 , Quiz 3-2 (answers are on the back):
1,2,4,6,7
Page 123-124, Exercises: 3-1, 3-2, 3-4, 3-6, 3-7
Chapter 4 LOOPS AND CHARACTER MANIPULATION
Objectives
• Know how to create and use while loops.
• Know how to create and use counting loops.
• Know when to use while loops, and when to use
counting loops.
• Know the purpose of the CONTINUE and EXIT
statements, and how to use them.
• Understand loop names, and why they are used.
• Learn about character assignments and character
operators.
• Learn about substrings and string manipulations.
While Loop
The While Loop
DO
...
IF (logical_expr) EXIT
...
END DO
!
! Code block
!
The block of statements between the DO and END DO
are repeated indefinitely until the logical_expr
becomes true and the EXIT statement is executed.
After the EXIT statement is executed, control
transfers to the first statement after the END DO.
Statistical Analysis
Example: The average and standard deviation of set of numbers ( xi is sample i
out of N samples):
Problem
1. State the problem Calculate the average and the
standard deviation of a set of , if measurements are
either positive or zero, and if we do not know in
advance how many measurements there are. A
negative input value will mark the end of the set of
measurements.
2. Define the inputs and outputs The inputs are a
number of positive or zero real (floating-point)
numbers.
Algorithm
3.
•
•
•
Design the algorithm (steps)
Accumulate the input data
Calculate the mean and standard deviation
Write out the mean, standard deviation, and number of points
PseudoCode
•
•
•
•
•
•
•
•
•
•
The pseudocode for these steps is:
Initialize n, sum_x, and sum_x2 to 0
WHILE
Prompt user for next number
Read in next x
IF x < 0. EXIT
nn+1
sum_x  sum_x + x
sum_x2  sum_x2 + x**2
End of WHILE
PseudoCode
• Pseudocode to Calculate the mean and standard
deviation.
• x_bar  sum_x / REAL(n)
• std_dev SQRT((REAL(n)*sum_x2 - sum_x**2) /
(REAL(n)*REAL(n-1)))
• Write out the results :
• Write out the mean value x_bar
• Write out the standard deviation std_dev
• Write out the number of input the n data points
Turn the algorithm into Fortran statements
PROGRAM stats_1
IMPLICIT NONE
INTEGER :: n = 0 ! The number of input samples.
REAL :: std_dev = 0. ! The standard deviation of the
input samples.
REAL :: sum_x = 0. ! The sum of the input values.
REAL :: sum_x2 = 0. ! The sum of the squares of the
input values.
REAL :: x = 0.
! An input data value.
REAL :: x_bar
! The average of the input samples.
Turn the algorithm into Fortran statements
DO ! While Loop to read input values.
! Read in next value
WRITE (*,*) 'Enter number: '
READ (*,*) x
WRITE (*,*) 'The number is ', x
! Test for loop exit
IF ( x < 0 ) EXIT
! Otherwise, accumulate sums.
n =n+1
sum_x = sum_x + x
sum_x2 = sum_x2 + x**2
END DO
Turn the algorithm into Fortran statements
! Calculate the mean and standard deviation
x_bar = sum_x / real(n)
std_dev = sqrt( (real(n) * sum_x2 - sum_x**2) / (real(n)
* real(n-1)) )
! Tell user.
WRITE (*,*) 'The mean of this data set is:', x_bar
WRITE (*,*) 'The standard deviation is: ', std_dev
WRITE (*,*) 'The number of data points is:', n
END PROGRAM stats_1
Test the program
For input values: 3, 4, and 5 :
3.
The number is
Enter number:
4.
The number is
Enter number:
5.
The number is
Enter number:
-1.
The number is
3.000000
4.000000
5.000000
-1.000000
The mean of this data set is:
Enter number:
The standard deviation is:
The number of data points is:
4.000000
1.000000
3
The DO WHILE Loop
There is an alternate form of the while loop in Fortran 95/2003,
called the DO WHILE loop. The DO WHILE construct has
the form
DO WHILE (logical_expr)
...
! Statement 1
...
! Statement 2
...
! ...
...
! Statement n
END DO
Good Programming Practice: Do not use DO WHILE loops in new programs.
Use the more general while loop instead.
The Iterative or Counting Loop
DO index = istart, iend, incr
Statement 1
!
...
! Body
Statement n
!
END DO
Loop index variable : index
Loop parameters (constants or variables) : istart, iend, incr
Note: All these variables or constants must be declared before
the loop as INTEGER .
The Iterative or Counting Loop
How loop works:
1. Evaluate parameters: istart, iend, and incr
2. Index  istart; If index*incr <= iend*incr, the program
executes the statements within the body of the loop.
3. recalculate: index = index + incr
4. If index*incr <= iend*incr, goto to 2. above and repeat .
The Iterative or Counting Loop
The number of times the count loop (without an IF ()
EXIT) is executed is given by the integer arithmetic
expression:
(iend-istart+incr)/incr
Also, the count loop will not be executed if for all
index values for which:
index*incr > iend*incr
Examples
DO i = 1, 10
Statement 1
...
Statement n
END DO
DO i = 1, 10, 2
Statement 1
...
Statement n
END DO
Examples
DO i = 1, 10, -1
Statement 1
...
Statement n
END DO
DO i = 3, -3, -2
Statement 1
...
Statement n
END DO
Examples
The Factorial Function: To illustrate the operation of a
counting loop, we will use a DO loop to calculate the factorial
function. For integer numbers n (in mathematics) the factorial
function is defined as:
n! =1
if n = 0
n! = n * (n-1) * (n-2) * ... * 3 * 2 * 1 if n >= 1
e.g. for n=4 then n!=4*3*2*1=24.
The Fortran code to calculate n factorial for n>0 is:
n_factorial = 1 ! We use the variable name n_factorial for n!
DO i = 1, n
n_factorial = n_factorial * i
END DO
Examples
If n is 5, the DO loop parameters will be istart = 1, iend = 5, and
incr = 1. The factorial will be:
1*2*3*4*5= 120
Example 4-3—Calculating the Day of Year:
1. Years evenly divisible by 400 are leap years.
2. Years evenly divisible by 100 but not by 400 are not leap
years.
3. All years divisible by 4 but not by 100 are leap years.
4. All other years are not leap years.
See the program Figure 4-6 (PROGRAM doy).
Examples (Programming Pitfalls)
DO i = 3, 2
...
END DO
Since: (iend-istart+incr)/incr= (2-3+1)/1=0, the DO loop will
never be executed.
Count down loops:
DO i = 3, 1, -3
...
END DO
Since:(iend-istart+incr)/incr= (1-3+(-3) )/(-3) = -5/(-3) = 1, the
DO loop will be executed only once (for i=3).
Examples (Program Pitfalls)
Good Programming Practice:
Never modify the value of a DO loop index
variable while inside the loop.
Never depend on a loop index variable to retain a
specific value after a DO loop completes
normally. So, avoid using it in statements after
the loop (see the examples in the next page).
Examples (Program Pitfalls)
INTEGER :: i ! Branch out of the loop before completion
DO i = 1, 5
...
IF (i >= 3) EXIT
...
END DO
The value of the index variable i=3 when the loop is completed.
INTEGER :: i
DO i = 1, 5
...
END DO
WRITE (*,*) i
The value of the index variable i is undefined when the loop is completed.
The CYCLE and EXIT Statements
• There are two additional statements which can be
used to control the operation of while loops and
counting DO loops: CYCLE and EXIT.
•
If the CYCLE statement is executed in the body
of a DO loop, the execution of the current iteration of
the loop will stop, and control will be returned to the
top of the loop. The loop index will be incremented,
and execution will resume again if the index has not
reached its limit.
The CYCLE and EXIT Statements
Example with CYCLE:
PROGRAM test_cycle
INTEGER :: i
DO i = 1, 5
IF ( i == 3 ) CYCLE
! If true go next to start of the loop
WRITE (*,*) i
END DO
WRITE (*,*) ‘End of loop!’
END PROGRAM test_cycle
The CYCLE and EXIT Statements
If the EXIT statement is executed in the body of a loop, the
execution of the loop will stop and control will be transferred
to the first executable statement after the loop. An example of
the EXIT statement in a DO loop is shown below.
PROGRAM test_exit
INTEGER :: i
DO i = 1, 5
IF ( i == 3 ) EXIT ! If true go next to end of the loop
WRITE (*,*) i
END DO
WRITE (*,*) ‘End of loop!’
END PROGRAM test_exit
Named Loops
[name:] DO
Statement
Statement
...
IF ( logical_expr ) CYCLE [name]
...
IF ( logical_expr ) EXIT [name]
...
END DO [name]
Good Programming Practice: Assign a name to any large and
complicated loops in your program to help you keep the parts
of the construct associated together in your own mind.
Named Loops
[name:] DO index = istart, iend, incr
Statement
Statement
...
IF ( logical_expr ) CYCLE [name]
...
END DO [name]
Nesting Loops
It is possible for one loop to be completely inside
another loop. If one loop is completely inside
another one, the two loops are called nested
loops.
The following example shows two nested DO
loops used to calculate and write out the
product of two integers.
Nesting Loops
PROGRAM nested_loops
INTEGER :: i, j, product
DO i = 1, 3
DO j = 1, 3
product = i * j
WRITE (*,*) i, ' * ', j, ' = ', product
END DO
END DO
END PROGRAM nested_loops
Nesting Loops
The results are
1*1= 1
1*2= 2
1*3= 3
2*1= 2
2*2= 4
2*3= 6
3*1= 3
3*2= 6
3*3= 9
When a Fortran compiler encounters an END DO statement, it associates that
statement with the innermost currently open loop. Good Programming
Practice: Assign names to all nested loops so that they will be easier to
understand and debug.
Nesting Loops
Compiling a named loop helps us find errors
PROGRAM bad_nested_loops_2
INTEGER :: i, j, product
outer: DO i = 1, 3
inner: DO j = 1, 3
product = i * j
WRITE (*,*) i, ' * ', j, ' = ', product
END DO outer
END PROGRAM bad_nested_loops_2
bad_nested_loops_2.f90(7) :
Error: The block construct names must match, and they
do not. [OUTER]
END DO outer
-------^
bad_nested_loops_2.f90(3) : Error: An unterminated block exists.
outer: DO i = 1, 3
^
compilation aborted for bad_nested_loops_2.f90 (code 1)
Nesting Loops
If two loops are to be nested, one of them must lie completely
within the other one. e.g. of DO loops are incorrectly nested
outer: DO i = 1, 3
...
inner: DO j = 1, 3
...
END DO outer
...
END DO inner
Good Programming Practice: Assign names to all nested loops so
that they will be easier to understand and debug.
Nested Loops with CYCLE or EXIT
If a CYCLE or EXIT statement appears inside an unnamed set of
nested loops, then the CYCLE or EXIT statement refers to the
innermost of the loops containing it. e.g.
PROGRAM test_cycle_1
INTEGER :: i, j, product
DO i = 1, 3
DO j = 1, 3
IF ( j == 2) CYCLE
product = i * j
WRITE (*,*) i, ' * ', j, ' = ', product
END DO
END DO
END PROGRAM test_cycle_1
Nested Loops with CYCLE or EXIT
The resulting output values are
1*1= 1
1*3= 3
2*1= 2
2*3= 6
3*1= 3
3 *3 = 9
Nested Loops with CYCLE or EXIT
PROGRAM test_cycle_2 ! Skip remainder of the code block of the inner DO
INTEGER :: i, j, product
outer: DO i = 1, 3
inner: DO j = 1, 3
IF ( j == 2) CYCLE outer
product = i * j
WRITE (*,*) i, ' * ', j, ' = ', product
END DO inner
END DO outer
END PROGRAM test_cycle_2
The resulting output values are
1* 1= 1
2* 1= 2
3* 1= 3
Nesting Loops within IF Constructs
• Nesting Loops within IF Constructs and vice
versa
•
It is possible to nest loops within block IF
constructs or block IF constructs within loops.
If a loop is nested within a block IF construct,
the loop must lie entirely within a single code
block of the IF construct.
Nesting Loops within IF Constructs
e.g. illegal or incorrect nesting:
outer: IF ( a < b ) THEN
...
inner: DO i = 1, 3
...
ELSE
...
END DO inner
...
END IF outer
Nesting Loops within IF Constructs
e.g. Correct nesting:
outer: IF ( a < b ) THEN
...
inner: DO i = 1, 3
...
END DO inner
...
ELSE
...
END IF outer
Character assignments and substrings
e.g.
CHARACTER(len=3) :: file_ext
file_ext = 'f' ! Stores ‘f ‘ into variable file_ext
e.g.
CHARACTER(len=3) :: file_ext_2
file_extent_2 = 'FILE01' ! Stores ‘FIL‘ into var. file_ext
e.g. str1 = '123456' then substring str1(2:4) is '234'
Example 4-5 What will the contents of variables a, b,
and c be at the end of the following program?
Character assignments and substrings
PROGRAM test_char1
CHARACTER(len=8) :: a, b, c
a = 'ABCDEFGHIJ' ! a stores 'ABCDEFGH'
b = '12345678' ! '12345678'
c = a(5:7) ! c stores 'EFG ' (it has 5 blanks)
b(7:8) = a(2:6) ! b stores '123456BC'
WRITE(*,*) " a =", a
WRITE(*,*) " b =", b
WRITE(*,*) " c =", c
END PROGRAM test_char1
Concatenation operator (//)
PROGRAM test_char2
CHARACTER(len=10) :: a
CHARACTER(len=8) :: b, c
a= 'ABCDEFGHIJ'
b = '12345678'
c = a(1:3) // b(4:5) // a(6:8) ! c stores 'ABC45FGH'
END PROGRAM test_char2
Relational Operators with Character Data
Character strings can be compared in logical expressions using:
==, /=, <, <=, >, and >= :
e.g. '123' == '123' is true e.g. '123' == '1234' is false
Order is the collating sequence of the characters on the computer:
It is the order number in the ASCII set of symbols: e.g. 'A' is 65 and
'B' is 66; also 'a' is 97, and ‘b' is 98
Comparison is left to right and character per character: e.g. true:
'AAAAAB' > 'AAAAAA'
'AB' > 'AAAA' and 'AAAAA' > 'AAAA'
Character intrinsic functions
Book Table 4-1 character functions: ACHAR(ival)
IACHAR(char), LEN(str1), LEN_TRIM(str1) , TRIM(str1)
See also appendix (B.7 pp. 899-902).
Skip program Example 4-6—Shifting Strings to Upper Case .
One can compare character strings using the intrinsic functions:
LGE(str1,str2), LGT(str1,str2), LLE(str1,str2),LLT(str1,str2)
e.g. Fortran statements:
str1='AAAAAB' , str2= 'AAAAAA'
WRITE(*,*) LGT(str1,str2) ! It prints TRUE
Character intrinsic functions
e.g.Quiz 4-2 What is written out by each of the WRITE statements below?
PROGRAM test_char
CHARACTER(len=10) :: str1 = 'Hello'
CHARACTER(len=10) :: str2 = 'World'
CHARACTER(len=20) :: str3
str3 = str1 // str2
WRITE (*,*) LEN(str3) ! 20
WRITE (*,*) LEN_TRIM(str3) ! 15
str3 = TRIM(str1) // TRIM(str2)
WRITE (*,*) LEN(str3) ! 20
WRITE (*,*) LEN_TRIM(str3) ! 10
END PROGRAM test_char
Example 4-7—Physics--The Flight of a Ball
Range of ball thrown in the air will be:
range= -2.0*v0*v0 /g*cos(theta)*sin(theta)
Write a program with a loop to check angles
theta = from 1 to 90 degrees
PseudoCode:
DO for theta = 0 to 90 degrees
Convert theta to radians
Calculate the range of the ball for each angle theta
Determine if this theta yields the maximum range so far
Write out the range as a function of theta
END of DO
WRITE out the theta yielding maximum range
See (FIGURE 4-13) PROGRAM ball
Chapter 5
Basic I/O Concepts
Objectives
•
•
•
•
Formatted WRITE
Format descriptors : I, F, E, ES, L, A, X, T, /
Formatted READ
Files
5.3 Format descriptors
Table 5-2 : Symbols with format descriptors
Symbol meaning
c column number
d no. of digits to the right of the decimal place of the real input/output
m
n
r
w
minimum no. of digits to be displayed
no. of spaces to skip
Repeat count (i.e. no. of times to use a group of descriptors)
Field width (i.e. no. of characters to use in input or output)
Integer output : rIw
e.g.
INTEGER :: t,d,h
t= 23
d= 715
h= -12
WRITE(*,200) t,d,h
200 FORMAT(I5,I5,I5)
will produce
♦♦♦23♦♦715♦♦-12
Real output : rFw.d
e.g.
x = 3.14159
y = -275.3024
z = 12.9999
WRITE(*,200) x, y, z
200 FORMAT(F10.3, F10.3, F10.3)
!using r=3: 200 FORMAT(3F10.3)
will produce
♦♦♦♦♦3.142♦♦-275.302♦♦♦♦13.000
Real output : rEw.d
The E edit descriptor, produces a representation of
a real number consisting of a decimal mantissa, fr, in
the range
0.1 < fr< 1.0,
with d digits of fr, followed by a four character
exponent e.g. For d=4 :
+ 0.d1d2d3d4E+ee
the whole number will occupy a field width of w
characters. So, w >=d+7 (7 characters: mantissa
sign, 0, . , E, exp.sign, 2 for exp.)
Real output : Ew.d
e.g. The number -0.000036176 4, will be output as:
E10.4
-.3618E-04
E12.6
-.361764E-04
E14.8
-.36176400E-04
But with Fw.d format, we lose digits in the display:
F10.4
♦♦♦-0.0000
F12.6
♦♦♦-0.000036
F14.8
♦♦♦-0.00003618
Real output : ESw.d
The ES edit descriptor, produces a representation of
a real number consisting of a decimal mantissa, fr, in
the range
1.0< fr< 10.0,
with d digits of fr, followed by a four character
exponent e.g. For d=3:
+ d1.d2d3d4E+ee
the whole number will occupy a field width of w
characters. Again, w >=1+d+6 (6 characters:mantissa
sign, . , E, exp.sign, 2 for exp.)
Real output : ESw.d
e.g. The number -0.0000361764, will be output as:
ES10.3
-3.618E-05
ES12.5
-3.61764E-05
ES14.7
-3.6176400E-05
Logical output: rLw
Output w - 1 blanks, followed by T or F to represent a
logical value
e.g.
LOGICAL :: output =.TRUE. ,debug=.FALSE.
WRITE(*,’2L5’) output, debug
will produce: ♦♦♦♦ T ♦♦♦♦ F
Character output: rA or rAw
Aw
A
e.g:
Output a character string in
the next w character positions.
Output a character string,
starting at the next character position,
with no leading or trailing blanks.
CHARACTER(LEN=26) :: long_name = "Llanfair...gogogoch"
WRITE(*,”(A19)”) long_name
produces:
Llanfair...gogogoch
Horizontal positioning: X or T
nX
Ignore the next n character positions.
Tc
Output the next item starting at character
position c
e.g.
REAL :: x=1.,y=2.,z=3.
WRITE(*,200) "X = ", x, " Y = ", y, " Z = ", z
200 FORMAT (A4,F4.1,2(2X,A5,F4.1))
will produce:
X= 1.0 Y= 2.0 Z = 3.0
Example of making a table using a do loop
An example of tabular printing:
PROGRAM tabular_output
IMPLICIT NONE
REAL, PARAMETER :: third=1.0/3.0
REAL :: x
INTEGER :: i
WRITE(* ‘The output….’
DO i=1,10 ! WRITE(* ‘The output….’
x=i
WRITE(*, '(F15.4,3X,F15.4,3X,F15.4)‘) x, SQRT(x), x**third
END DO
END PROGRAM tabular-output
EXAMPLE: Fig 5-5 (PROGRAM table)
Example of making a table using a do loop
The output from this program will be
1.0000
1.0000
1.0000
2.0000
1.4142
1.2599
3.0000
1.7321
1.4422
4.0000
2.0000
1.5874
5.0000
2.2361
1.7100
6.0000
2.4495
1.8171
7.0000
2.6458
1.9129
8.0000
2.8284
2.0000
9.0000
3.0000
2.0801
10.0000
3.1623
2.1544
Example of ES format
EXAMPLES: Fig 5-8 (PROGRAM capacitor)
Equations type: Either (1) or (2) :
(1) Given capacitance in farads and voltage in volts compute (total) charge in
coulombs:
Q = C*V
(2)
C= Q/V
Also, compute energy in joules:
E = (1/2)*C*V*V
And no. of electrons (6.241461*10^(18) ) per coulomb of charge.
e.g. Test with input data: Volt.=100.00 V, Total charge=0.01 C (i.e. type =2
case),
Output is: Capacitance = 1.000E-04 F, No. of electrons=6.241E+16
Total energy =.5000 joules.
READ Format
Edit descriptors for input:
Descriptor
Meaning
Iw
Read the next w characters as an integer (e.g. w=8)
Fw.d
[
Read the next w characters as a real number with
d digits after the decimal place (e.g. w=14 , d=5)
Ew.d
if no decimal point is present]
Aw
Read the next w characters as characters
A
Read sufficient characters to fill the input list item,
stored as characters
Lw
Read the next w characters as the representation of
a logical value
nX
Ignore the next n characters (e.g. n=2)
Tc
Next character to be read is at position c (e.g. c=5)
Examples of READ Formats
Format Iw: Assume that we type on the keyboard
123456789 (as input):
READ (*, '(4X, I5)‘) num
! Leave 4 spaces then read num=56789 will ignore the
first four columns and then read;
READ (*,'(I2, 3X, I3)‘) i, j
! Read i, leave 3 spaces; read j,
will cause the value 12 to be stored in i and 678 in j.
Examples of READ Formats
Assume that we type on the keyboard 123456789 (as
input):
READ (*,'(T4, I2, T8, I2, T2, I4)‘) x, y, z ! Move to
pos. 4, read x,…
will read the number 45 into x, reading 89 into y,
and reading the number 2345 into z.
Examples of READ Formats
Format Fw.d: The effect of the F edit descriptor during
input with
decimal point present.
READ (*,'(3F10.4)') a,b,c
1.5
0.15E+01
15.0E-01
---------|---------|----------|---------|
10
20
Then a , b, c store the value 1.5
30
40
Examples of READ Formats
The effect of the Fw.d edit descriptor during input without
decimal point present. Then the d last digits are the fraction part.
READ (*,'(3F10.4)') a,b,c
15
150
15000
---------|---------|---------|---------|
10
20
30
40
Then : a is 0.0015, b is 0.0150, c is 1.5000
Explanation: Due to w=10, the first 10 places will be read for ‘a’
and due to d=4, there will be 4 fractional digits , similarly for b ,c
Examples of READ Formats
Good Programming Practice: Always include a decimal point
with REAL inputs, when using formated READ.
Format Lw: The edit descriptor used with logical data, takes the
form:
Lw (e.g. w=4)
This edit descriptor processes the next w characters to
derive either a true value, a false value, if the 1st character is
T or F. Else an error will occur.
Examples of READ Formats
Format A: An A edit descriptor without any field width w is
treated as
though the field width was identical to
the length of the corresponding input list item.
Thus, for
CHARACTER (len=10) :: ch1
CHARACTER (len=8) :: ch2
CHARACTER (len=15) :: ch3
the following two statements will have an identical effect:
READ(*, '(A10, A8, A15)‘) ch1, ch2, ch3
READ (*,'(A, A, A)',) ch1, ch2, ch3
eg. Inputline:Mississipi Amazon longest river
5.5 Files and File processing
The UNIT
The UNIT number indicates which "stream" of input or output
you desire to access.
By default the standard streams are keyboard (input) and monitor
(output).
You can change the output to stream to (or input to stream from)
a file of choice.
The number of the UNIT appears to be up to you to decide.
The FILE
This is the name of the file you wish to open.
You may also reference a character variable that holds the name
of the file to access.
We call ‘Record’ one line of data the file.
5.5 Files and File processing
The STATUS
The STATUS specifies the status of the file to be opened.
The status of the file may be:
– OLD - file exists
– NEW - file needs to be created
– REPLACE - file needs to be essentially deleted and recreated
– SCRATCH - a temporary file that will be deleted when execution
completes
The ACTION
Why you open the file? READ, WRITE, or READWRITE?
The IOSTAT tells if all was correct or an error occur
5.5 Files and File processing
The OPEN Statement
OPEN(UNIT = 8, FILE = "data", STATUS = "OLD",
ACTION = "READ", IOSTAT = ierror)
The statement above will open the file named data for
reading.
The variable ierror is an integer that will hold the status
of the open the request. If ierror equals zero then the
open was successful.
UNIT is set to 8. this number is arbitrary, but it is
unique among open I/O streams.
5.5 Files and File processing
Examples of WRITE and READ with files:
Figures 5-10 (PROGRAM read_file),
5-11 (PROGRAM scratch_file),
5-12 (PROGRAM least_squares_fit)
Figure 5.12 Least-squares fit
DATA FITING BY LEAST SQUARES :
Assume that we have a (set) table of data from experiments e.g
and we want to pass a line as near to the data as possible. If we
know that the data satisfy : y = ax + b; (Note in our book:
‘a’ is ‘m’ and ‘b’ is the same as ‘b’ here)
TABLE
x
x1
x2
.
xn
y
y1
y2
.
yn
We know that if we have n = 2 pairs of data i.e.
then there is one line connecting them (if x1 != x2)
TABLE
x
y
x1
y1
x2
y2
BUT if we have n > 2, then it is not possible (expect special
cases) for the line to connect the (x,y) points. Then we want a line
to pass ‘as near as possible’
y
y7
y1
0
x1 x2……..x7
x
The problem of finding a line that passes as near as possible is
solved by the ‘least squares’ method which finds the a,b which
make MINIMUM the sum [axi + b – yi]2
From LINEAR ALGEBRA and CALCULUS we know that the
Solution (assuming two xi’s at least are different) is
n
n
n
n
n
a  [((  x i )(  y i )  n (  x i y i )) / ((  x i )  n (  x i ))]
2
i1
n
i1
i1
i1
2
i1
n
b  ((  y i )  a (  x i )) / n
i1
i1
Note: solve for ‘a’ first and use it in ‘b’. Note in our book:
‘a’ is ‘m’ and ‘b’ is the same as ‘b’ here.
Program in Figure 5-12.
For each (xi , yi) we call ‘residual’ r(xi) = [axi + b – yi] ; this states
how ‘closely’ the line y = ax + b passes through the point (xi , yi)
e.g.
y
10*r(x1)
0
x1 x2
x7
x
10*r(x2)
n
The ‘residual sum’:

i1
n
r ( xi )
2


[axi  b  yi ]
2
i1
gives the ‘goodness of the fit’. For best fit the residual sum
n

i1
r ( xi )  0
2
Chapter 6 Arrays
Motivation:
We know REAL or INTEGER variables or constants
e.g. REAL :: x
REAL, PARAMETER :: pi=3.14
• These allow us to program computations with reals or
integers.
• How about working with vectors or matrices (needed
in linear algebra)?
Chapter 6 Arrays
e.g:
X3x1 = [X1 X2 X3]T = [1.0 2.0 3.0] T
or
A3x1 = [a11 a12 a13] T
A2x2 = [a11 a12
[1.0 0.0
a21 a22] = 2.0 4.0]
= a(1:2, 1:2)
A2x3 = [a11 a12 a13
[0.5 0 0.3
a21 a22 a23] = 0.1 1.0 1.2] = a(1:2, 1:3)
The array concept
So far we have used one name to refer to one location in
the computer's memory.
A group, or array, of locations in the memory, are identified by
the same name but with an index, or subscript,
to identify individual locations.
As the vector A, the individual elements are A1, A2, ... An
We call such an ordered set of related variables an array,
and we refer to the individual items within the array
as array elements.
The array concept
We follow the name of the array by an identifying integer value
enclosed in parentheses:
A(1), A(2), ..., A(n)
An array element is defined by writing
the name of the array followed by a subscript,
where the subscript consists of an integer.
Expression (known as the subscript expression)
is enclosed in parentheses.
Thus,
x(10)
y (2*i+4)
The array concept
Array (in programs) is a name of a variable or constant
with an index set . e.g. [a1, a2, a3] (of linear algebra) is
written as :
a(1),a(2), a(3)
(in FORTRAN 90).
More generally a(1), a(2),….a(n) where n is an integer
value (e.g. n=3 for previous example)
An array element is (a subscript expression) e.g:
x(3), y(2* i +4)
Note: subscript expression must be integer ; but it can be
an array itself or contain an array as part of it.
Chapter 6 Arrays
Declaring Arrays
Before an array can be used, its type and the number of
elements it contains must be declared to the compiler.This
must be done so that the compiler knows what type of data are
to be stored in the array and how much memory is required to
hold the indicated number of elements of that type.
Example from the book. Let's assume we need to store the
voltage (v) readings from 16 different experiments, we could
declare 16 individual REAL variables or one REAL array that
can hold 16 elements.
REAL :: v1, v2, v3, v4, v5, v6, v7, v8, v9, v10
REAL :: v11, v12, v13, v14, v15, v16
Probably not a good idea. Try the array instead!
REAL, DIMENSION(16) :: voltage
Chapter 6 Arrays
• Each individual REAL value is represented by
an index (or subscript).
Index:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Value:
3.2 2.4 1.0 1.1 3.2 2.2 1.2 4.3 2.3 4.5 3.2 1.0 0.3 3.4 3.4 8.3
6.1 Array declarations
The declaration of scalar (e.g. REAL) variables causes the
compiler to allocate an appropriate storage unit to contain its
value. When we declare an array variable, the compiler will need
to allocate several storage units.
There are two ways using either a dimension attribute or
an array specification applied to the variable name.
Consider e.g.
REAL, DIMENSION(50) :: a, b, c
REAL :: a(50), b(50), c(50)
REAL, DIMENSION(50) :: a,b,c, x(20),y(20),z
To store arrays in memory we need:
- name (e.g. a)
- type (e.g. REAL)
- Dimension i.e number of elements
e.g. ‘3’ for a(1), a(2), a(3).
FORTRAN declaration for arrays:
e.g. REAL,DIMENSION(50) :: a,b,c
50 means: (1:50)
-Mixed dimensions:
REAL,DIMENSION(50) :: a,b,c,x(20),y(20),z or
better
REAL, DIMENSION(50) :: a,b,c,z
REAL, DIMENSION(20) :: x,y
6.1
NOTE: This means e.g. we have stored
x(1),x(2),x(3),………x(20)
i.e. lb :lower bound=1
y(1),y(2),y(3),………y(20)
ub : upper bound=20
By default the subscripts will start at 1, but if we wish the
subscripts to have a different range of values then we may provide
the lower bound (lb) and the upper bound (ub) explicitly,
separated by a colon:
(lb:ub)
REAL, DIMENSION(11:60) :: a,b,c
![extent=no of elements
REAL, DIMENSION(-20:-1) :: x
!
= ub-lb+1]
REAL, DIMENSION(-9:10) :: y
REAL, DIMENSION(0:49) :: z
6.1
Five technical terms that are of great importance
when discussing arrays in Fortran.
 Fortran permits up to seven subscripts,
each of which relates to one dimension of the array.
For each dimension,
there are two bounds, the lower bound and the upper bound.
 The number of permissible subscripts for a particular array
is called its rank.
 The extent of a dimension is
the number of elements in that dimension.
 The size of the array is the total number of elements.
 The shape of an array is determined by
its rank and the extent of each dimension.
I
Chapter 6 Arrays
6.2.1 Array Elements Are Just Ordinary Variables
Each element of an array is a variable just like any other variable!
e.g. program segment
……
INTEGER, DIMENSION(10) :: arrayInt
REAL, DIMENSION(3) :: arrayReal
arrayInt(1) = 5
arrayReal (3) = arrayInt(1)/4.0
WRITE(*,*) "arrayInt(1) = ", arrayInt(1)
WRITE(*,*) "arrayReal(3) = ", arrayReal(3)
Initialization of Array elements
Four different approaches for initialization:
(1) Using a loop: (e.g. program segment)
INTEGER, DIMENSION(10) :: arrayInt
INTEGER :: lcv
DO lcv = 1, 10, 1
arrayInt(lcv) = lcv * 2
END DO
e.g. PROGRAM squares ! Fig 6-2 in book
Initialization of Array elements
(2) Provide values for each of these elements by means of an
array constructor.
An array constructor consists of a list of values enclosed
between special delimiters, (/ …. /):
(/ value_l, value_2, … /)
If arr is an integer array of size 10, its elements could be set to
arr = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
Chapter 6 Arrays
(3) Use implied DO loop: e.g.: Create an integer array
(dimension 1000) and initialize each element to be
equivalent to its index. e.g.
INTEGER, DIMENSION(1000) :: arrayInt = (/ (i, i=1, 1000) /)
e.g. PROGRAM square_roots ! Fig 6-3 in book
Another Example (text page 256):
INTEGER, DIMENSION(25)::array4=(/ ( (0,i=1,4), 5*j, j=1,5 ) /)
The inner loop (0,i=1,4) executes completely for each outer loop
Index j. So the resulting array4 is:
0,0,0,0,5, 0,0,0,0,10, 0,0,0,0,15, 0,0,0,0,20, 0,0,0,0,25
Chapter 6 Arrays
(4) Use whole array operation: Initialize an array
(dimension 5000) to zero for all elements.
INTEGER, DIMENSION(5000) :: arrayInt =1.0
! OR:
INTEGER, DIMENSION(5000) :: arrayInt
arrayInt = 1.0
Chapter 6 (Changing the Subscript Range of an Array)
We can change the range of values that an array's subscript can
take when we declare the array.
INTEGER, DIMENSION(-50:49) :: arrayInt !! Or
INTEGER:: lower_bound = -50, upper_bound=49
INTEGER, DIMENSION(lower_bound:upper_bound) ::
arrayInt
Shape of an array is the number of dimensions (here it is 1) and
the extent of each dimension. We have only seen one
dimensional arrays so far.
Extent of an array is the upper_bound - lower_bound + 1
e.g. PROGRAM squares_2 ! Fig 6-4 in book
Chapter 6 Arrays (out of bounds subscripts)
The Fortran compiler may not report ‘bounds checking’errors
at compile time. Then we may get ‘unwanted’ results.
Example :
PROGRAM bounds! Fig 6-6 in book
REAL, DIMENSION(5) :: a
This declaration means that the bounds are: 1:5 for array
Thus we can not read/write other elements e.g. a(6) does not
really exist.
Use of Named Constants with Array Declarations
Instead of using a hard-coded value as the size of an
array, it is more common to use a constant to
represent the array size.
INTEGER, PARAMETER :: nstud= 100
INTEGER, DIMENSION(nstud) :: stuID
INTEGER, DIMENSION(nstud) :: course
Example : PROGRAM extremes! Fig 6-7 in
book
Whole Array Operations
If the two arrays are the same shape, then they can be used in
ordinary arithmetic operations and the operation will be
applied on an element-by-element basis (whole arrays).
Example : PROGRAM add_arrays ! Fig 6-9 in book
INTEGER :: i
REAL :: a(4) = (/1, 2, 3, 4/)
REAL :: b(4) = (/5, 6, 7, 8/)
REAL :: c(4)
REAL :: d(4)
Whole Array Operations
!!ADDING ELEMENT BY ELEMENT
DO i = 1, 4, 1
c(i) = a(i) + b(i)
END DO
!!WHOLE ARRAY ADDITION
d=a+b
DO i = 1, 4, 1
WRITE(*,*) "c(",i,") = ", c(i), "d(",i,") = ", d(i)
END DO
Other examples:
Whole Array Operations
Other examples: One must first check that the arrays are of the
same shape (conformable)
REAL, DIMENSION(20) :: a, b, c
REAL :: d(10:29)
a = 1.55
b = c*d
! Whole array processing
!! or, the same computation using a loop
DO i=1, 20
! DO loop array operations
b(i) = c(i)*d(i+9) ! difficult!
ENDDO
Whole Array Operations
Other examples e.g. 1) whole array processing:
REAL :: a(1:20), b(0:19), c(10:29), d(-9:10)
a = c*d
! Fortran 90 style
!! Or, The same computation using a loop
DO i=1,20
! FORTRAN 77 style
b(i-1) = c(i+9)*d(i-10) ! b= c*d
END DO
2) REAL:: array_1(1:20), array_2(-9:10)
array_1 = 10*array_2
3) REAL:: a=0.0, b=0.0
REAL, DIMENSION(50) :: c = 0.0, d = 0.0
Whole Array Operations
Intrinsic functions (p.48): Syntax with variables (i.e. not arrays): e.g. b =
SQRT(a)
If an intrinsic function (p.48) has an array as an argument then the result of
the function reference will be an array with the same shape as the
argument. But, we need conformable arrays:
e.g. 1)
REAL:: array_1(1:20), array_2(-9:10)
array_1 = SIN(array_2)
Thus, the statement array_1 = SIN(array_2) assigns the sine of each element
of the array array_2 to each corresponding element of the array array_1.
Note: that the assignment starts from the lower index and goes to the upper
and it is the same as a loop. e.g.
DO i = 1, 20
array_1(i) = SIN(array_2(i - 10))
END DO
Whole Array Operations
Also, an intrinsic function has more than one argument
then they must all be conformable. e.g. 2)
REAL :: a(1:20), b(0:19), c(10:29), d(-9:10)
REAL::e(1:20), arr_max(1:20)
arr_max = MAX(100.0, a, b, c, d, e)
Thus the statement arr_max = MAX(100.0, a, b, c, d, e)
will assign to the elements of arr_max the maximum value of the
corresponding elements of the arrays a, b, c, d and e, or 100.0.
Whole Array Operations
Can we use comparisons with whole arrays?
IF (a < b) THEN
WRITE(*,*) "a < b"
ELSE
WRITE(*,*) "a >= b"
END IF
Not possible ! Syntax Error!
Arrays Subsets (or Sections)
These are specified by subscript-triplets for each dimension of the
array. The general form is:
[< subscritpt1 >]:[< subscritpt2 >][:< stride >]
The section starts at < subscritpt1 > and ends at or before <
subscritpt2 >
< stride > is the increment (or jump) by which the elements are
selected.
< subscritpt1 >, < subscritpt2 > and < stride > must all be scalar
integer expressions.
e.g. INTEGER :: i=3, j=7
INTEGER, DIMENSION(10) :: a =(/1,2,3,4,5,-6,7,8,9,10/)
a(:) is the entire array a
a(i:j) is the array subset: [3,4,5,-6,7]
Arrays Subsets (or Sections)
Other examples for:
INTEGER :: i=3, j=7
INTEGER, DIMENSION(10) :: a =(/1,2,3,4,5,
-6,7,8,9,10/)
a(i:j:k) , for k=3, is the array subset [3,-6]
a(8:3:-1) ,i.e. from a(8) to a(3) in steps of –1, is [3,4,5,-6,7,8]
a(8:3) ,i.e. from a(8) to a(3) in steps of 1, is an empty subset
a(i:) , from a(i) to upper_bound of a, i.e.: [3,4,5,-6,7,8,9,10]
a(:j) , from lower_bound of a to a(j), i.e.: [1,2,3,4,5,-6,7]
a(::3), from lower_bound of a to upper_bound of a with stride= 3
i.e.: [1,4,7,10]
a(i:i), i.e. :[3]
Good Programming Practices with Arrays
• Are arrays necessary? Yes, e.g. for Linear
Algebra vectors and matrices and Multidimensional Calculus
• Array dimensions must be declared using
named constants. This leads to fewer errors!
• Arrays should be initialized before use. The
results of using uninitialized arrays are
unpredictable.
• Stay within the array bounds.
Input and output of whole arrays and sections
• Before using an array in prog’s must be able to
input data in arrays and get output e.g.:
PROGRAM inputoutputData
INTEGER :: first= 1, last= 100
! Must declare all arrays
READ (*,*) first,last,(arr(i), i=first,last) !Input
!output
WRITE (*, *) (arr(i), i=1,99,2) ,arr(3),arr(4)
WRITE (*, *) arr
END PROGRAM inputoutputData
Input and output of whole arrays and sections
• Array elements are treated in just the same
way as scalar variables.
• An array name may appear in an input or
output list, in which case it refers to the whole
array.
• Input data to arrays and output results from
arrays (next):
Input and output of whole arrays and sections
Part of an array may be identified by use of an implied DO,
the item takes the form
(object_list, implied_do_control)
For example: WRITE (*, *) (arr(i), i=1, 99, 2), arr(3), arr(4)
Input and output of whole arrays and sections
It is permitted for one or more of the controlling values
for an implied DO in an input statement to be
themselves
input by the same statement:
READ (*,*) first, last, (arr(i), i=first, last)
This form of input statement must be used with care.
NOTE: (1)We must be careful w/ defining ‘first’ and
‘last’: It must: first < last, (2) If ‘arr’ dimensions are
arr(low:upper) then also must: low <= first and last
<= upper.
Input and output of whole arrays and sections
Example of input data into array:
(A safe way of reading data with an implied DO)
PROGRAM array_input
IMPLICIT NONE
INTEGER, PARAMETER :: lower=-50, upper=50
INTEGER :: first, last, i
REAL, DIMENSION(lower:upper) :: arr
...
READ (*,*) first, last
Input and output of whole arrays and sections
IF (first>=lower .AND. last<=upper) THEN
READ *, (arr(i), i=first, last)
ELSE
WRITE(*, *) 'Invalid array subscript specification! '
.
END IF
.
END PROGRAM array_input
Book Example: program array_io Fig. 6-11
EXAMPLES (sorting data e.g. numbers)
Sorting (i.e. ordering) by straight selection:
Index
1 2 3 4 5
Initial order
7 1 8 4 6
After first exchange
1 7 8 4 6
After second exchange
1 2 8 4 6
After third exchange
1 2 3 4 6
After fourth exchange
1 2 3 4 6
After fifth exchange
1 2 3 4 5
After sixth exchange
1 2 3 4 5
After seventh exchange
1 2 3 4 5
6
3
3
3
8
8
8
6
6
7
5
5
5
5
5
6
8
7
8
2
2
7
7
7
7
7
8
Sorting
Sorting Data: Algorithm “selection sort”.
The list is divided into two sublists, sorted and unsorted, which
we will separate. Initially, the entire array constitutes the
unsorted list.
We go through the unsorted list and find the smallest
element. Then we swap that element with the element at the
beginning of the unsorted (or end of sorted list) data.
Sorting
What does it mean to swap?
Answer
INTEGER :: x = 3, y= 2
INTEGER :: temp
temp = x
x=y
y = temp
Sorting
Once we find the smallest element in the
unsorted list and move it to the front
position. We then move one to the right.
This adds one datum to the sorted list and
takes one datum away from the unsorted
list.
Each time we complete such a swap we say
we have completed a sort pass.
With n elements in an array we need n-1
sort passes to properly sort the data
Sorting
PROGRAM selectionsort
IMPLICIT NONE
INTEGER:: SIZE,temp,i,j, smallest
INTEGER :: data(50)
INTEGER :: num_it = 0
READ(*,*) SIZE
DO i = 1, SIZE, 1
READ(*,*) data(i)
END DO
Sorting
DO i = 1, SIZE-1, 1
smallest = i
DO j = i+1, SIZE, 1
num_it = num_it + 1
IF (data(j) < data(smallest)) THEN
smallest = j
END IF
END DO
temp = data(i)
data(i) = data(smallest)
data(smallest) = temp
END DO
Sorting
DO i = 1, SIZE, 1
WRITE(*,*) "data(", i, ") = ", data(i)
END DO
WRITE(*,*) "Number of iterations: ",
num_it
END PROGRAM selectionsort
Also, Book program for Selection Sort:
Figure 6-15: program sort1
Chapter 7 Introduction to procedures
Motivation: Top-Down Design
• This is the idea that with any problem you should try
to break down the problem into smaller easier to
program tasks.
• The code for these smaller tasks is isolated in to what
is called a procedure (subroutine or function).
Chapter 7 Introduction to procedures
The book defines as follows:
– Subroutine - a procedure that can return multiple
results through calling arguments.
– Function - a procedure that returns only a single
value that is used in the evaluation of an
expression.
Arguments - The data that goes into (or comes out
from) a procedure
Chapter 7 Introduction to procedures
7.1 Subroutines: A subroutine is a procedure that receives its
input values and returns its results through an argument list .
SUBROUTINE some_name (some argument list)
! DECLARATION SECTION
! EXECUTION SECTION
RETURN
END SUBROUTINE some_name
Note: "variables" in the argument are called dummy arguments
( memory is not allocated for them, they act as placeholders
for the actual arguments when the subroutine is called ).
Chapter 7 Introduction to procedures
(1) The subroutine itself behaves as normal program
and it has both a declaration and execution section.
(2) When the subroutine is called control of the
program shifts from the calling program to the
subroutine.
(3) When the subroutine ends the control returns in the
calling program in the statement after the CALL
e.g.
 CALL some_name (actual argument list)
Chapter 7 Introduction to procedures
Example (book): Fig. 7-1 and 7-2: calc_hypotenuse
Need calling program (called test driver) to run the
subroutine.
SUBROUTINE calc_hypotenuse ( side_1, side_2, hypotenuse )
Note: 3 dummy variables (first 2 are input and 3rd
output)
Chapter 7 Introduction to procedures
• The variables being used as arguments must be declared
(REAL, INTEGER, CHARACTER, LOGICAL, arrays, )
• The intent of each argument must be declared as well.
– INTENT IN - The value is coming in to the procedure and
cannot be changed.
– INTENT OUT - The variable is coming in to the
procedure and the result assigned to the variable will be
"returned" from the procedure.
– The other (local) variables (i.e. not arguments) of the
subroutine must be declared too. (e.g. REAL :: temp )
– The keyword RETURN is optional
Chapter 7 Introduction to procedures
Example (for INTENT): Fig. 7-1 and 7-2:
calc_hypotenuse
7.1.2 The INTENT Attribute :
• INTENT (IN) - Dummy argument is used only to pass input
data to the subroutine.
• INTENT (OUT) - Dummy argument is used only to return
results to the calling program.
• INTENT (INOUT) - Dummy argument is used both to pass
input data to the subroutine and to return results to the calling
program
e.g. More Examples: bad_call (Fig7-5), array2 (Fig7-6),
intent_test (next slide, not in the book programs)
Chapter 7 Introduction to procedures
PROGRAM intent_test ! Example of INTENT(IN)
IMPLICIT NONE
INTEGER :: x = 1
INTEGER :: y = 2
CALL testing(x, y)
WRITE(*,*) "The value of x = ", x, " and the value of y = ", y
END PROGRAM intent_test
SUBROUTINE testing(a, b)
IMPLICIT NONE
INTEGER, INTENT(IN) :: a
INTEGER, INTENT(OUT) :: b
! Error because next we change variable a , which is input argument.
! it will work if we change IN to INOUT
a=3
b=4
END SUBROUTINE testing
Chapter 7 Introduction to procedures
7.2 Sharing Data Using Modules:
• We have seen how data can be exchanged with
subroutines as arguments.
• Another way of sharing data among programs,
subroutines, and functions is by use of a module (or
modules).
• A module is a unit that contains the definitions and
initial values of data we wish to share between
program units (functions, subroutines).
Example: shared_data, test_module (Fig 7-8, Fig 7-9)
Chapter 7 Introduction to procedures
A module exists in order to make some or all of the
entities declared
within it accessible to more
than one program unit.
One very important use of modules relates to global
accessibility of variables, constants and derived type
definitions.
A module allows a defined set of variables and/or
constants to be made available to any program units
which access them by means of an appropriate USE
statement.
Chapter 7 Introduction to procedures
MODULE global_data
IMPLICIT NONE
SAVE
! Constant declarations
REAL, PARAMETER :: pi=3.1415926, piby2=pi/2.0
! Variable declarations
REAL :: global_1, global_2, global_3, global_4, global_5
END MODULE global_data
Note: SAVE should always be included in any module which
declares any variables.
Chapter 7 Introduction to procedures
The USE statement comes after the initial statement
(PROGPAM, SUBROUTINE or FUNCTION) but before
any other statements:
SUBROUTINE component
USE global_data
IMPLICIT NONE
!Any additional specification statements
!Executable statements
END SUBROUTINE component
Note: All procedures which use a module that includes a SAVE
statement are sharing the same copy of any variables,
constants, type definitions or other entities
accessed
from by USE association.
Chapter 7 Introduction to procedures
7.3 Module Procedures
• A module can also be used to share procedures.
The called procedure is said to have an implicit interface if we
use CALL subroutine_name (because the calling program
does not know the types, intent, etc of the arguments at
compile-time).
We can change the implicit interface to explicit interface by
using modules.
Example: bad_call2 (Fig. 7-12), which allows the compiler
to discover the error of missing ‘IN’ keyword in the subroutine:
‘my_subs’ in program ‘bad_call’
Chapter 7 Introduction to procedures
7.4 FORTRAN Functions
A FORTRAN function is a procedure whose result is a single
number, logical value, character string or array.
This result can be used to form a FORTRAN expression.
The expression may be on the right side of an assignment
statement.
There are two types of functions, intrinsic and user-defined.
Intrinsic functions are those functions built into a FORTRAN
language, such as SIN(x) or LOG(x).
See Appendix B.
Chapter 7 Introduction to procedures
User-Defined functions are functions defined by programmers
(not really users) to meet a specific need not addressed by the
standard intrinsic functions.
General form of user-defined functions
REAL FUNCTION name(argument list)
!Declaration statements
!executable statements
name = arithmetic expression
RETURN
END FUNCTION name
Chapter 7 Introduction to procedures
Note:
(1) A function is (invoked) called by including it in an
expression ( e.g. name = expression) or WRITE (*,*)
name )
(2) The parentheses around the argument list are required even if
the list is blank.
(3) The type of the function must be declared both in the function
procedure and the calling programs.
Examples in book: (1) quadf (Fig 7-13), test_quadf (Fig 7-14),
(2) sinc (Fig7-16), test_sinc (Fig-7-17).
Chapter 7 Introduction to procedures
Example:
REAL FUNCTION cube_root (x)
IMPLICIT NONE
! Function to calculate the cubic root of a positive real
number
! Dummy argument declaration
REAL, INTENT (IN) :: x
! Local variable declaration
REAL :: log_x
log_x = LOG(x)
cube_root = EXP (log_x/3.0)
RETURN
END FUNCTION cube_root
Chapter 7 Introduction to procedures
PROGRAM function_demo
IMPLICIT NONE
! Variable declarations; actual arg’s
REAL :: a=1. ,b=2. ,c=27. ,d=1.
!REAL :: cube_root ! Not enough
REAL, EXTERNAL :: cube_root ! Need this
a = b*cube_root (c) +d
WRITE(*,*) a
END PROGRAM function_demo
Chapter 7 Introduction to procedures
NOT IN EXAMS: 7.5.1 Passing user-defined functions as
arguments:
We can have arguments (in procedures) which are functions. For
this (and always with user-defined functions), we must
declare (in the calling programs) the function as EXTERNAL
e.g. REAL, EXTERNAL :: func
Example: ave_value (Fig. 7-18) , test_ ave_value (Fig 7-19)
NOT COVERED: We can also have arguments (in procedures)
which are subroutines. For this we must also declare (in the
calling programs) the subroutine as EXTERNAL.
Example: sub_as_arguments (Fig. 7-20) ,
test_sub_as_arguments(Fig 7-21)
Chapter 8 Additional Features of Arrays( Skip: 8.4-8.5)
• Multidimensional Arrays
• The arrays we have seen so far are 1-dimension (
rank=1) arrays. We often visualize such arrays as
being in a single row.
• However, it might be more useful to think of the 1dimension as being in one column based on how
arrays are stored in memory.
• A 2-dimension array can be visualized as a table
made up of several rows and columns. If the columns
are a single dimension array then a table (2dimensional array) can be viewed as a series of 1dimensional arrays (columns).
Chapter 8 Additional Features of Arrays
Why think of a 1-dimension array as a
column? Because in physical memory, arrays
are stored by column, such that all of column
1's contents reside consecutively then column
2's, column 3's, and so on. Such arrangement
in memory is known as column major
order. Not all programming languages will be
column major order, many (e.g. C) are row
major order.
In Chapter 6, we discussed rank = 1 (1-dimension or 1-D) arrays.
e.g. REAL, DIMENSION (11:60) :: a
To solve problems in linear algebra, we need many dimensions
(i.e. rank >= 2).
13.1 Matrices and two-dimensional arrays:
A1,1 A1,2 A1,3 A1,4
A 3 x 4 matrix A3x4:
A=
A2,1 A2,2 A2,3 A2,4
A3,1 A3,2 A3,3 A3,4
e.g
A=
2
3
4
3
4
5
4
5
6
5
6
7
The matrix A can be defined in FORTRAN 90:
REAL, DIMENSION (3,4) :: a
Note: in DIMENSION (3,4) the no. of rows is 1st, then the no.
of columns.
Other types of arrays are possible: e.g.
LOGICAL, DIMENSION (10,4) :: b
e.g. b10x4 =
b(1,1) b(1,2) b(1,3) b(1,4)
………………………………….
.…………………………………
b(10,1) b(10,2) b(10,3) b(10,4)
and the values b(i,j) = .TRUE. Or .FALSE. for i = 1,…,10; j =
1,…,4.
The array elements (being ‘scalars’ i.e. single elements) can be
used in expressions exactly as the simple type (e.g. REAL,
INTEGER, LOGICAL) variables or constants.
e.g for REAL, DIMENSION (3,4) :: a
e.g
a(3,4) = 2.0*a(3,4) + 1.0
! Doubles a(3,4) and adds 1
to it
DO i = 1,4
! Replace row 1 of a by
a(1,i) = a(3,i)
row 3 of a. Row 3 is
END DO
unaltered
DO i = 1,3
! Replace column 2 of a by
a(i,2) = a(i,1)
column 1 of a. Column 1
END DO
is unaltered
Basic concepts for dim => 1 arrays :
Recall: rank = No. of dim’s and taken from ‘DIMENSION()’:
e.g.
REAL, DIMENSION(8) :: a
!rank = 1
INTEGER, DIMENSION(3,10) ::b
!rank = 2
array size =No. of array elements = product of extents =
3*10 = 30
Note : e.g. for b: DIMENSION(3 ,10 ) same as
DIMENSION(1:3, 1:10 ) and the ‘extents’ are 3,10
Instead of the actual dim’s we can use ‘named constants’
e.g. INTEGER, PARAMETER :: s1=3, s2=10
…
INTEGER, DIMENSION(s1,s2) ::b
‘shape’ of array : rank , extents of dim’s e.g.
shape of array ‘b’ above : rank=2 and extents = (3, 10)
-e.g. arrays with different index bounds and the same
shape e.g. Arrays a1, b1 below have the same shape as
arrays : a, b above :
REAL, DIMENSION(11:18) :: a1
INTEGER, DIMENSION(5:7, -10:-1) :: b1
-Array element order (in FORTRAN) is by columns :e.g.
REAL , DIMENSION(4,3) :: arr
WRITE( * ,*) arr
arr(1,1) , arr(2,1), arr(3,1), arr(4,1), arr(1,2), arr(2,2)
arr(3,2) , arr(4,2), arr(1,3), arr(2,3), arr(3,3), arr(4,3)
arr(1,1)
arr(1,2)
arr(1,3)
arr(4,1)
arr(4,2)
arr(4,3)
13.3 Array constructors :
e.g REAL , DIMENSION(0:49) :: arr = (/-1, (0 , i = 1,48),1 /)
means:
arr(0) = -1
arr(1) = 0
.
.
arr(48) = 0
arr(49) = 1
Since array constr. are 1-Dim we use ‘RESHAPE’ to apply to
Dim > 1 arrays
e.g. a = RESHAPE( (/1.0 ,2.0, 3.0, 4.0, 5.0,6.0/), (/2 , 3/) )
1.0 3.0 5.0
2 .0 4 .0 6.0
We could use nested implied ‘DO’
11
12
21
22
e.g. for
by the following declaration statement
INTEGER :: i, j
REAL , DIMENSION(2,2) :: a = &
RESHAPE( (/ ((10*i+j , i = 1,2), j =1,2) / ) , (/ 2,2 /) )
Which is the same as the following:
INTEGER :: i , j
REAL, DIMENSION(2,2) :: a
DO j = 1,2
DO i = 1,2
a( i,j) = 10*i+j
ENDDO
ENDDO
Input/output with arrays :
The ways for input/output with arrays: (1) List individual
elements (2) List of individual elements under an
implied/regular DOloop (3) Use an array name (e.g ‘x’)
with no subscripts in a whole array operation
e.g. REAL, DIMENSION(50 , 8) :: x
(x has 50 rows, 8 col’s)
WRITE(*, ‘ (8F8.2)’) x
will print out the data in the following way
x(1,1) x(2,1) x(3,1) x(4,1) x(5,1) x(6,1) x(7,1) x(8,1)
x(9,1) x(10,1) x(11,1) x(12,1) x(13,1) x(14,1) x(15,1) x(16,1)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
x(49,1) x(50,1) x(1,2) x(2,2) x(3,2) x(4,2) x(5,2) x(6,2)
x(7,2) x(8,2) x(9,2) x(10,2) x(11,2) x(12,2) x(13,2) x(14,2)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
which is not at all what was wanted! It does not print the
array as a matrix!
On the other hand, the implied Doloop statement
WRITE(*, ‘(8F8.2)’) ((x(i,j) , j = 1,8 ), i = 1,50)
will cause the results to be printed in the correct
arrangement (like a matrix)
x(1,1) x(1,2) x(1,3) x(1,4) x(1,5) x(1,6) x(1,7) x(1,8)
x(2,1) x(2,2) x(2,3) x(2,4) x(2,5) x(2,6) x(2,7) x(2,8)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
WHOLE ARRAY OPERATIONS
- Need Conformable arrays : i.e. arrays of same shape
- e.g. (i)
REAL , DIMENSION (10) :: p,q
REAL , DIMENSION (10 : 19) :: r
- Operations with conform. arrays do not need loops
e.g. (i)
DO i = 1, 10
p(i) = q(i) + r(i + 9)
END DO
same as whole array operation: p = q + r
e.g. (ii)
REAL, DIMENSION(10, 21) :: x
REAL, DIMENSION(0:9, -10:10) :: y
REAL, DIMENSION(11:20, -20:0) :: z
shape of x : rank = 2, extents (10 , 21)
Also, shape of y and z : rank = 2, and extents =
(10 , 21)
Then the Fortran 90 whole array statement:
x = y + z +10.0
has exactly the same effect as the following
nested
DO loop:
DO i = 1, 10
DO k = 1, 21
x(i,k) = y(i-1, k-11) + z(i+10, k-21) + 10.0
END DO
END DO
Rules (from chapter 6) for working with whole array operations:
(1) Two arrays are conformable, if they have the same shape
(2) A scalar, including a constant, is conformable with any
array
(3) All intrinsic operations are defined between conformable
arrays
e.g. (i) REAL :: x(4) = (/ 0.0, 1.1, 2.2, 3.3 /)
REAL :: y(4)
y = SIN(x)
(ii) x= y+z +10.0 +EXP(y)+COS(z)
The result is the same as if the function were applied to each element
of the array. The shape of the resulting array must be the same as
the input argument.
All intrinsic functions e.g. ABS, SIN, COS, TAN, EXP, LOG, LOG10,
MOD, and SQRT may also accept arrays as input.
Chapter 8 Additional Features of Arrays
• Array subsets
e.g. REAL, DIMENSION (1:5,1:5) :: a, b, c
(i) a(:,1) is the 1st column
(ii) a(1,:) is the 1st row
(iii) a(1:3,1:5:2) takes an array subset of
stride=2
8.3 USING SPECIAL FORTRAN ARRAYS
INTRINSIC FUNCTIONS
This type of function will return a value that is
dependent on the properties of the object being
evaluated.
Chapter 8 Additional Features of Arrays
LBOUND(array) - Returns ALL of the lower bounds of array.
INTEGER :: array ( 1:5, 3:6)
WRITE(*,*) "LBOUND is ", LBOUND(array)
LBOUND is 1 3
LBOUND(array, dim) - Returns the lower bound of dim of array.
There is a similar function called UBOUND .
SHAPE(array) - Returns the shape of array.
WRITE(*,*) "SHAPE is ", SHAPE(array)
SHAPE is 2 5 4
SIZE(array) - Returns the number of elements in the array.
WRITE(*,*) "SIZE is ", SIZE(array)
SIZE is 20
Example : PROGRAM check_array (Fig.8-7),
FORTRAN provides intrinsic functions for vectors (rank=1
arrays) and matrices (rank=2 arrays)
Table 8.2 (contains the full list; Optional: mask is a
LOGICAL array, with element values: TRUE/FALSE)

matmul(matrix_A, matrix_B)
dot_product(vector1, vector2)
transpose(matrix)
maxval(array, mask)
maxloc(array, mask )
minval(array, mask)
minloc(array, mask)
product(array, mask)
sum(array, mask)
From LINEAR ALGEBRA:
MATMUL:
e.g. A3x4 x B4x4 = C3x4 =
3x
C (1,1)
.
.
C ( 2 ,1)
.
.
C ( 3,1)
.
.
4
where
C (i , j ) 

a (i , k ) * b ( k , j )
k 1
DOT_PRODUCT:
e.g. Vectors
X3x1 =
X (2)
X ( 3)
dot_product computes
y ( 1)
X (1)
3

i1
X (i ) * y (i )
, y3x1 =
y (2)
y ( 3)
TRANSPOSE:
e.g.
D4X3 = AT3X4 =
MAXVAL:
e.g. For array X =
a (1,1)
a ( 2 ,1)
a ( 3 ,1)
a (1,2 )
a ( 2 ,2 )
a ( 3,2 )
a (1,3 )
a ( 2 ,3)
a ( 3 ,3 )
a (1,4 )
a ( 2 ,4 )
a ( 3,4 )
x ( 1)
x (2)
x ( 3)
Computes the maximum of x(1) , x(2) , x(3)
MINVAL: computes the minimum of x(1), x(2) , x(3)
x ( 1)
PRODUCT: e.g. for X =
computes x(1)*x(2)*x(3)
x (2)
x ( 3)
SUM: computes the sum of array elements: x(1) + x(2) +x(3)
An example of matrix and vector multiplication
PROGRAM vectors_and_matrices
IMPLICIT NONE
INTEGER, DIMENSION(2,3) :: matrix_a
INTEGER, DIMENSION(3,2) :: matrix_b
INTEGER, DIMENSION(2,2) :: matrix_ab
INTEGER, DIMENSION(2) :: vector_c = (/ 1 , 2 /)
INTEGER, DIMENSION(3) :: vector_bc
! If all a(i,j) = 1.0, write a = 1.0
! Initialize matrix_a
matrix_a(1,1) = 1
matrix_a(1,2) = 2
! Matrix_a is the matrix:
matrix_a(1,3) = 3
! [1 2 3]
matrix_a(2,1) = 2
! [2 3 4]
matrix_a(2,2) = 3
matrix_a(2,3) = 4
! Set matrix_b as the transpose of matrix_a
matrix_b = TRANSPOSE(matrix_a)
!matrix_b is now the matrix [ 1 2 ]
!
[2 3]
!
[3 4]
! Calculate matrix products
matrix_ab = MATMUL(matrix_a, matrix_b)
! matrix ab is now the matrix [ 14 20 ]
!
[ 20 29 ]
vector_bc = MATMUL(matrix_b, vector_c)
!vector_bc is now the vector [5 8 11]
END PROGRAM vectors_and_matrices
NOTE 1) The matrix/vectors intrinsic functions help us program
very quickly the corresponding linear algebra computations.
e.g. if the program above was programmed with DOloops :
matrix_b = TRANSPOSE(matrix_a)
!! Same as the Doloop:
DO i = 1,3
DO j = 1,2
matrix_b(i,j) = matrix_a(j,i)
ENDDO
ENDDO
matrix_ab = MATMUL(matrix_a ,matrix_b)
!! Same as the nested Doloop
DO i = 1,2
DO j = 1,2
matrix_ab(i ,j) = 0.0
DO k = 1 ,3
matrix_ab(i,j) = matrix_ab(i,j) + matrix_a(i,k)
*matrix_b(k,j)
ENDDO
ENDDO
ENDDO
Example program matrix
PROGRAM vectors_and_matrices !! Using array
constructors
IMPLICIT NONE
INTEGER i,j
INTEGER , DIMENSION(2 , 3) :: matrix_a = &
RESHAPE((/1,2,2,3,3,4/), (/ 2,3 /))
INTEGER, DIMENSION(3,2) :: matrix_b
INTEGER, DIMENSION(2,2) :: matrix_ab
INTEGER, DIMENSION(2) :: vector_c = (/ 1,2 /)
INTEGER, DIMENSION(3) :: vector_bc
! Set matrix_b as the transpose of matrix_a
matrix_b = TRANSPOSE(matrix_a)
Example program matrix
matrix_ab = MATMUL(matrix_a , matrix_b)
!matrix_ab is now the matrix
[ 14 20 ]
!
[ 20 29 ]
vector_bc = MATMUL(matrix_b , vector_c)
vector_bc = MATMUL(matrix_b , vector_c) ! Vector_bc is
!now the vector :
[ 5 8 11 ]
WRITE(*,*) 'matrix a = '
WRITE(*, '(3I5) ') ( ( matrix_a(i,j) , j=1,3), i=1,2)
WRITE(*, *) 'matrix b ='
WRITE(*, '(2I5)' )( ( matrix_b(i,j) , j=1,2) , i=1,3)
WRITE(*, *) 'vector b times c'
Chapter 8 Additional Features of Arrays
Examples of programs: (1) Ex5-8, (2) generate (Fig
8-5), input file: GENDAT
(3)check_array (Fig.8-7).
(4) matrix.f90 (vectors_and_matrices)
Note: Skip subsections 8.4, 8.5
8.6 ALLOCATABLE ARRAYS:
The arrays studied so far are based on ‘static memory
allocation’ (i.e. memory is allocated at the start of the
program and remains allocated till the program ends).
Allocatable arrays are based on ‘dynamic memory
allocation’ and allow user to control allocation / de-allocation of
memory for array elements.
Steps:
– Firstly, the allocatable array is specified in a type
declaration statement.
– Secondly, space is dynamically allocated for its elements in
a separate allocation statement, after which the array may
be used in the normal way.
– Finally, after the array has been used and is no longer
required, the space for the elements is deallocated by a
deallocation statement.
-Declaration : e.g.
REAL,ALLOCATABLE :: arr1( :,: ) , arr2(: , : )
ALLOCATE(arr1(100,0:10) , arr2(10:30 , 0:10),
STAT =status_variable)
NOTE:
-After ‘ALLOCATE’ arrays can be used like the
standard arrays
-Use : STAT = status_variable to check successful
allocation.
EXAMPLE PROGRAMS
(1) test_all_array
e.g. An example of allocation of allocatable arrays, with error checking
.…
INTEGER :: m=1000,n=100
INTEGER :: error
REAL , ALLOCATABLE , DIMENSION(: ,:) :: p
INTEGER , ALLOCATABLE , DIMENSION( : ,:) :: q
.
ALLOCATE(p(n,m), q(10*n,m) , STAT = error)
IF(error /= 0) THEN
! Space for p, q could not be allocated
WRITE(* ,*) “ Program could not allocate space for p ,q and r ”
STOP
END IF
! Space for p , q successfully allocated
.
.
-DEALLOCATE (list of allocated arrays, STAT = st_var
releases the memory by removing allocated arrays.
e.g. REAL, ALLOCATABLE, DIMENSION( :) :: varying_array
INTEGER :: i ,n, alloc_error , dealloc_error
.
.
READ ( * , *) n
! Read maximum size needed
DO i = 1 , n
ALLOCATE(varying_array( - i : i ) , STAT = alloc_error)
IF(alloc_error / = 0) THEN
WRITE (* , *) “ Insufficient space to allocate array &
&when i = “ , i
STOP
END IF
! Calculate using varying_array
.
.
.
DEALLOCATE(varying_array, STAT = dealloc_error)
IF(dealloc_error / = 0) THEN
WRITE (* , *) “ Unexpected deallocation error ”
STOP
END IF
END DO
.
.
- Allocated arrays allow users to have control on the amount of
memory space used. This is especially needed for very large n
(e.g. if n=10000 then n2 = 100000000)
e.g.
PROGRAM space
IMPLICIT NONE
INTEGER :: n =10000
REAL , ALLOCATABLE , DIMENSION ( : , :) :: a , b
ALLOCATE(a(2*n , 6*n))
! Allocate space for a
! Calculate using a
! Uses 12n2 elem.’s space
! i.e. it needs 12n2 memory locations for real numbers
.
.
.
.
DEALLOCATE(a)
ALLOCATE(b(3*n , 4*n))
! Calculate using b
.
.
.
DEALLOCATE (b)
END PROGRAM space
!Free space used by a
! Allocate space for b
! Uses 12n2 elem’s space
!Free space used by b
Total memory Space = 12n2 elements space
The same subroutine with standard arrays uses 24n2 elements memory space:
PROGRAM space
IMPLICIT NONE
INTEGER :: n
REAL , DIMENSION(2*n , 6*n) :: a !12n2 elem.’s space
REAL , DIMENSION(3*n , 4*n) :: b !12n2 elem.’s space
!Calculate using a
.
.
!Calculate using b
.
.
END PROGRAM space
! Total = 24n2 elem.’ space
NOTE:
There are intrinsic functions which give information on ALLOCATABLE
arrays e.g. ‘ALLOCATED’ intrinsic function checks if it was already allocated
:
e.g.
.
REAL , ALLOCATABLE , DIMENSION (:) :: input_data
ALLOCATE (input_data (1 : 1000000) , STAT = alloc_stat)
……………
IF (ALLOCATED (input_data) ) THEN
READ(*,*) input_data
DEALLOCATE (input_data)
ELSE
WRITE (*,*) “warning : array not allocated”
END IF
Examples: testAllocate1, testAllocate2, testAllocate3
Chapter 9 Additional Features of Procedures
Contents to be covered: Section 9.1.1 Explicit-Shape Dummy
Arrays
Section 9.1.2 Assumed-Shape Dummy Arrays
Section 9.2 The SAVE Attribute and Statement
Section 9.3 Allocatable Arrays in Procedures
Section 9.4 Automatic Arrays in Procedures
Remaining Sections are to be Skipped (also skipped)
Section 9.1.3 Example 9-1, Fig. 9-1, Fig. 9-2
Chapter 9
9.1 Passing Multidimensional Array to
Procedures
The passing of multidimensional (i.e. rank >=2)
arrays is similar to passing single dimension
(i.e. rank=1) arrays. However, the procedure
needs to know: (1) the number of dimensions
(i.e. rank) and (2) the extent of each
dimension to use the array. The possible ways
to pass arrays are: Explicit-Shape , AssumedShape arrays
Chapter 9
9.1.1 Explicit-Shape Arrays
Using this method we pass the array and the extent of each
dimension of the array to the subroutine.The extent values are
used to declare the size of the array in the procedure ( test
example program array2 (Fig7-6, in Chapter 7) . Also e.g.
SUBROUTINE process1 (data1, data2, n,m)
IMPLICIT NONE
INTEGER, INTENT(IN) :: n,m
REAL, INTENT(IN), DIMENSION(n,m) :: data1 ! explicitshape
REAL, INTENT(OUT), DIMENSION(n,m) :: data2 !
explicit-shape
data2= 3.*data1
END SUBROUTINE process1
Chapter 9
e.g.: Two ways for passing arguments lower, upper for
explicit-shape arrays:
(1) As input arguments:
SUBROUTINE explicit (a, b, lower, upper)
IMPLICIT NONE
INTEGER, INTENT(IN) :: lower, upper
REAL, DIMENSION(lower:upper), &
INTENT(IN) :: a, b
….
Chapter 9
(2)
OR, by using a module :
MODULE dataset
IMPLICIT NONE
INTEGER:: lower, upper
lower=10
upper=40
END MODULE dataset
SUBROUTINE explicit_2(a, b)
USE dataset
!This module includes the lower
!and upper bounds of a large group
!of arrays, including a and b
!These are called lower and upper
IMPLICIT NONE
REAL, DIMENSION(lower:upper), INTENT(IN) :: &
a, b
Chapter 9
9.1.2 Assumed-Shape Dummy Arrays
Assumed-shape arrays are declared using colons
as placeholders for each subscript of the array.
Subroutine must have explicit interface (e.g.
must be placed inside a module. Examples in
Book (Skip Example 9-1),
Example 9-2: PROGRAM assumed_shape
(Fig. 9-3).
Chapter 9
Assumed-Shape Dummy Arrays example (not in Book):
MODULE test_module
CONTAINS
SUBROUTINE process1 (data1, data2)
REAL, INTENT(IN), DIMENSION(:,:) :: data1
! Assumed- shape
REAL, INTENT(OUT), DIMENSION(:,:) :: data2
! Assumed-shape
data2= 3.*data1
END SUBROUTINE process1
END MODULE test_module
Chapter 9
9.2 The SAVE Attribute and Statement
When the execution of a procedure terminates, the local
variables and local arrays become undefined (i.e. their
values are erased from the memory). But, if the procedure is
called many times it is useful to save these values for the next
CALL, by using the SAVE keyword. e.g. (1):
REAL , SAVE :: sum_x !The value of var sum_x is saved
Also, variables that are initialized are saved even if SAVE is
not written e. g. (2):
REAL :: sum_x2 = 0. ! The value of var sum_x2 is saved
Example (Fig. 9-4, 9-5): running_average,
test_running_average
Chapter 9
9.3 Allocatable Arrays in Procedures (local arrays): The
allocatable arrays inside procedures are declared the same
way as we do in main programs, but as local arrays. If we
use the SAVE, and the procedure is called many times the
array-contents will be preserved.
9.5 Allocatable Arrays in Procedures (dummy argument
arrays): Note: We need explicit interface.
1. INTENT(IN) : the array can’t be
changed/reallocated/deallocated in the subroutine.
2. INTENT(INOUT) : then the status (‘allocated’ or not) and the
data is passed to the subroutine (when it is called). The array can
Chapter 9
be changed/deallocated/re-allocated and the dummy arg. (data)
will be passed back to the calling program.
3. INTENT(OUT) : The actual arg. (in calling progr.) will be
deallocated (when the subroutine is called) and the subroutine
can change/deallocate/re-allocate and the new array will be
passed back to the calling program through the arg.
Example: program allocatable_arguments (section 9.5)
9.4 Automatic Arrays in Procedures
Automatic Arrays are local arrays inside procedures. They are
explicit-shape arrays with non-constant lower/upper bounds.
e.g.
Chapter 9
SUBROUTINE process1 (data1, data2, n,m)
IMPLICIT NONE
INTEGER, INTENT(IN) :: n,m
REAL, INTENT(IN), DIMENSION(n,m) :: data1
! explicit-shape
REAL, INTENT(OUT), DIMENSION(n,m) :: data2
! explicit-shape
REAL, DIMENSION(n,m) :: temp ! Automatic
temp=SIN(data1)
data2= 3.*data1 + temp
END SUBROUTINE process1
Chapter 9
9.4.1 Automatic versus Allocatable arrays:
1) Automatic array is created on entry and removed on
exit to/from a procedure (subroutine or function).
2) Allocatable arrays must be allocated/deallocated
manually. They can be created/destroyed in (separate
procedures). They can be re-sized during calculation.
Note: Unlike automatic arrays, explicit-shape and
assumed-shape arrays can be dummy arg’s and are
given fixed extents in the calling program.
Chapter 11 Additional intrinsic data types
Objectives: Understand the different KINDS of
a given data type.
How to select a specific kind for
REAL , INTEGER data.
How to select the precision and range of a real
variable in a computer independent manner.
RECALL: REAL Numbers on the computer
REAL numbers: consider any non-zero real number as
a fraction lying between 0.1 and 1.0, called the mantissa (or fraction),
which is multiplied or divided by 10 a certain number of times, where this
number is called the exponent.
a  10
b
exponent
mantissa
NOTE: The mantissa and the exponent are integers numbers.
RECALL: Default (IEEE standard) INTEGER and REAL numbers on a computer
The default (IEEE standard) INTEGER and REAL numbers on a computer is
based on 32-bit representation of numbers. So when we declare data as type
INTEGER or REAL we can only the following numbers (1) and (2) represented
on a computer. The remaining numbers are either zero or +infinity or -infinity .
For REAL, the representation is called single precision.
(1) An integer is a whole number, is always stored exactly in the computer’s
memory, and has a (relatively) limited range :
(between about -2*109 and +2*109 on a typical 32-bit computer).
(2) A real number, on the other hand, is stored as a floating-point number, is stored
as an approximation to a fixed number of significant digits and it has a very large
range :
(typically in the range between about -1038 and +1038 and
accurate in the first seven or eight significant digits on the same 32-bit computer).
Chapter 11 Additional intrinsic data types
11.1 Alternative kinds of REAL data type:
In Fortran, there is a double precision ( REAL
data type ), which is based on a representation
on the computer with 64-bits (i.e. 8 bytes). For this, the
mantissa (or fraction of the number) have 14
(depending on the computer maybe: 15 or 16)
accurate decimal digits and the exponent range is
[-308 , 308] (for base 10).
The content of this chapter is (in part) devoted in
explaining how to use double precision in Fortran
90/95 programs.
Chapter 11 Additional intrinsic data types
11.1.1 Kinds of REAL constants and variables:
The KIND parameter can be used in the REAL declaration to
specify single (or double) precision.
e.g.
REAL(KIND=1) :: value_1
REAL(KIND= 4) :: value_2
REAL(KIND=8 ), DIMENSION(20) :: array
REAL(4) :: temp
! better to use ‘KIND=‘
We often call the variables declared (with KIND) parametrized
variables. In general, KIND=1 or 4 is single and KIND=2 or 8
is double precision. But, it all depends on the
computer/compiler.
Chapter 11 Additional intrinsic data types
In order, to make the Fortran programs portable among computers we use a
named constant (instead of 4 or 8) in KIND: e.g.
INTEGER, PARAMETER :: SINGLE = 4
INTEGER, PARAMETER :: DOUBLE = 8
REAL(KIND= SINGLE) :: value_1
REAL(KIND= DOUBLE), DIMENSION(2) :: array
REAL(SINGLE) :: temp
We can also declare constants: e.g.
34.
! default kind, single precision
34._4 ! Valid if KIND=4 is valid; please avoid this way!
34.E3 ! default kind, single precision
1234.56789_DOUBLE ! Valid, if DOUBLE is declared, as above
Chapter 11 Additional intrinsic data types
3.0E0 ! default kind, single precision constant
3.0D0 ! double precision constant
We can find out the kind of precision on a
computer by using
the intrinsic function KIND.
e.g. PROGRAM kinds (Figure 11-1).
Chapter 11 Additional intrinsic data types
11.1.3 Selecting a precision (in a computer/processor
independent manner)
We use an intrinsic function SELECTED_REAL_KIND :
kind_number = SELECTED_REAL_KIND (p=precision, &
r=range)
! precision is the no. of decimal digits of precision, i.e. accuracy
! range is the exponents range in powers of 10.
! e.g. kind_number = SELECTED_REAL_KIND (p=6, r=37)
This function gives: -1 (precision is not available), -2 (range is
not available), -3 (precision and range are not available).
Note: what is available depends on the computer/compiler.
Chapter 11 Additional intrinsic data types
Table 11-2: Kind related functions return
the following:
SELECTED_REAL_KIND (p, r) ! the smallest kind of REAL with p
! decimal digits of precision and range: [-10^r, 10^r]
SELECTED_INT_KIND (r)
! Smallest kind of INTEGER
! with range: [-10^r, 10^r]
KIND(X)
! the KIND for the var. or const. X
PRECISION(X) ! the decimal digits of precision for the var. or const. X
RANGE(X)
! the decimal exponent range for the var. or const. X
Example: PROGRAM selected_kinds (Figure 11-2)
Chapter 11 Additional intrinsic data types
11.1.4 Mixed-precision (single/double precision) arithmetic
Example (operation + in single/double precision): 1./3 + 1./3
1. 1.D0/3. + 1/3 = 3.333333333333333 E-001 ! 1/3 =0, here
2. 1./3. + 1.D0/3.
= 6.666666633333333 E-001
! 1./3., is single precision
3. 1.D0/3. + 1./3.D0 = 6.666666666666666 E-001
Example: Constants must be declared/written in double precision
to actually have a double precision accuracy. e.g.
PROGRAM test_initial
INTEGER, PARAMETER :: DBL =SELECTED_REAL_KIND(p=13)
REAL(KIND=DBL) :: a1= 6.666666666666666
Chapter 11 Additional intrinsic data types
REAL(KIND=DBL) :: a2= 6.666666666666666_DBL
WRITE(*,*) a1,a2
END PROGRAM test_initial
The program gives the results for a1 and a2:
6.666666507720947 6.666666666666666
(i.e. a1 is in single-precision , because it was not declared/written
as double!).
11.1.5 Higher precision intrinsic functions: y=DBLE(x)
! converts the x to double precision y. But DBLE(a1) will not
! Add lost digits if constant a1 did not have _DBL, like a2
Note: y=REAL(x) ! converts the x to single precision y.
Chapter 11 Additional intrinsic data types
11.1.6 When should one use high precision (i.e. doubleprecision) instead of standard REAL (?)
e.g. REAL :: x, y, a1, a2
1. When the values are : x < -10^(38) or x > 10^(38)
2. When we have: x+y (or x-y) with |x| much smaller than |y|
e.g. x = 3.25 and y= 1000000.0 then:
Single-precision: x+y= 1000003.0
Double-precision: x+y= 1000003.25
3. When the |a1| and |a2| are about the same and we compute
(a1-a2) .
Chapter 11 Additional intrinsic data types
Example : Numerical calculation of derivatives.
e.g. PROGRAM diff (Figure 11-4).
Calculate the derivative of f(x) = 1/x , at x= 0.15 .
Note: (1) the true derivative of f(x) is: -1/(x*x) =44.444444444 .. ; (2) using the approximation
formula: (f(x+d_x) –f(x) )/d_x
Note: The program uses d_x = 1.000E-1 ,.., 1.000E-10 .
When d_x is smaller than 1.000E-5 both single and double
precision solutions are accurate. But for d_x > 1.000E-5 only
the double precision solution is accurate.
Chapter 11 Additional intrinsic data types
SKIP : section 11.1.7
11.2 Alternate lengths of the INTEGER data type
The intrinsic function
kind_number = SELECTED_INT_KIND(e)
(where range is the exponent e for the range [-10^e ,
10^e] , e.g. e=3,9,12,30) gives the integer parameter,
to be used in a declaration for INTEGER type.
e.g. the program: PROGRAM test_selected_int_kinds
Note: e.g e=9 is the default range for INTEGER on Intel
Pentiums : [-2147483648 , 2147483648 ]. A number outside
the range is + infinity or – infinity.
Chapter 11 Additional intrinsic data types
Example of declaration.
INTEGER, PARAMETER :: SHORT=
SELECTED_INT_KIND(3)
INTEGER, PARAMETER :: LONG =
SELECTED_INT_KIND(9)
INTEGER (KIND=SHORT) :: i1
INTEGER (KIND=LONG) :: i2
INTEGER :: 34, 34_4, 24_LONG ! the constant 34_4 is valid if 4
is a legal kind of integer
SKIP: the remaining sections
Descargar

Document