Transcript lectures
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 -
computer coordinates activities of the
The Arithmetic Logic Unit (ALU) -
calculations performs the
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) (b) (c) (d) (e) 0 0 0 0 9 0 0 0 9 0 0 0 9 0 0 0 9 0 0 0 9 0 0 0 9 0 0 0 0 0 0 0 0 0 9 0 initial milometer reading 2 after two miles 1 after reversing one mile 0 after reversing one more mile 9 after reversing one more mile
Chapter 1 Intro. to Computers and the Fortran Language
e.g. Storage of 8-digit integers, in base=10 system:
(a) (b) (c) (d) (e) (f) 0 4 5 5 9 0 0 9 0 0 9 0 0 9 0 0 9 0 0 9 0 0 9 0 0 9 0 0 9 0 0 9 0 0 9 0 0 9 0 0 9 0 0 represents -50 000 000 1 represents -49 999 999 9 represents -1 0 represents 0 1 represents +1 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 1111 0000 -2 -1 0 0001 0010 0111 +1 +2 +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
: underscore); a-z, A-Z, 0-9, and _ (the
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 & + input2 ! Also, sum the inputs
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 non executable 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 Math expression 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 real world 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
user defined
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
e.g. For computing cubic roots, for x >0 : (using IF).
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 Style Style
== .EQ.
Meaning
Equal to /= .NE. Not equal to > .GT. Greater than >= .GE. Greater than or equal to < .LT. Less than <= .LE. Less than or 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
‘(‘ , ‘)’ can be omitted
e.g. a
!But may confuse us; so use ‘(‘ , ‘)’
(a
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) d)
, the results of the operators are in and
l2 = (c <
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 .NOT.log1
true true true true false true false false false true true false true false false false false true false true
log1 log2
true true true false false true false false
log1.EQV.log2 log1.NEQV.log2
true false false true false true true false
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 .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-to right) ; 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 Branche
s 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 END IF
action_4
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:
in a SELECT CASE construct Use characters (
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
program. e.g. Verify correctness of block IF: WRITE(*,*) ‘At if1: var1 =‘, var1 of the 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 3.000000
Enter number:
4.
The number is 4.000000
Enter number:
5.
The number is 5.000000
Enter number:
-1.
The number is -1.000000
The mean of this data set is: 4.000000
Enter number: The standard deviation is: 1.000000
The number of data points is: 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 ...
...
...
END DO ! Statement 2 ! ...
! Statement n 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 !
...
Statement n !
! Body 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
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
Examples
The Factorial Function:
function is defined as: 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 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 statement with the innermost currently open loop. Good Programming Practice:
understand and debug. END DO
statement, it associates that
Assign names to all nested loops so that they will be easier to
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 nested loops, then the CYCLE or EXIT statement refers to the
innermost
of the loops containing it. e.g.
unnamed
set of 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 minimum no. of digits to be displayed n no. of spaces to skip r Repeat count (i.e. no. of times to use a group of descriptors) w 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
E12.6
-
.3618E-04 .361764E-04 E14.8
-
.36176400E-04
But with Fw.d format, we lose digits in the display:
F10.4
♦♦♦ -
0.0000
F12.6
F14.8
♦♦♦ -
0.000036
♦♦♦ -
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
ES12.5
ES14.7
-
3.618E-05 3.61764E-05 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
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.
e.g:
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 position
c
Output the next item starting at character 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
2.0000
1.0000
1.4142
1.0000
1.2599
3.0000
4.0000
5.0000
6.0000
7.0000
1.7321
2.0000
2.2361
2.4495
2.6458
1.4422
1.5874
1.7100
1.8171
1.9129
8.0000
9.0000
10.0000
2.8284
3.0000
3.1623
2.0000
2.0801
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
I
w
F
w
.d
[ Read the next
w
characters as an integer (e.g. w=8) Read the next
w
characters as a real number with
E A L
n w.
Aw w
X
Tc
d d
digits after the decimal place (e.g. w=14 , d=5) if no decimal point is present] Read the next
w
characters as characters Read sufficient characters to fill the input list item, stored as characters Read the next
w
characters as the representation of a logical value Ignore the next
n
characters (e.g. n=2) Next character to be read is at position
c (e.g. c=5)
Examples of READ Formats
Format I
w: 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 F
w.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 30 40 Then a , b, c store the value 1.5
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 L
w: 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 1 st 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
treated as is 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
reading.
for The variable
ierror
is an integer that will hold the status of the open the request. If open was successful.
ierror
equals zero then the 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 y x 1 x 2 y y 1 . .
2 x n y n
We know that if we have n = 2 pairs of data i.e.
then there is one line connecting them (if x 1 != x 2 ) TABLE x y x 1 x 2 y y 1 2 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 [ax i + b – y i ] 2 From LINEAR ALGEBRA and CALCULUS we know that the Solution (assuming two x i ’s at least are different) is
a b
[((
n
((
i
n i
1 1
y i x i
) )(
i a
n y
( 1
i
n
1
i
)
n
(
x i
)) /
n i
n
1
x y i i
)) /((
n
1
i x i
) 2
n
(
i
n
1
x i
2 ))]
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 (x i , y i ) we call ‘residual’ r(x i ) = [ax i + b – y i ] ; this states how ‘closely’ the line y = ax + b passes through the point (x i , y i ) e.g. y 10*r(x1) 0 x x1 x2 10*r(x2) The ‘residual sum’:
i n
1 x7 (
i
) 2
i n
1 [
ax i
b
y i
] 2 gives the ‘goodness of the fit’. For best fit the residual sum
i
n
1
r x i
2 0
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: X 3x1 or = [X 1 A 3x1 = [a 11 X 2 a 12 X 3 ] T = [1.0 2.0 3.0] T a 13 ] T A 2x2 = [a 11 a 12 a 21 a 22 [1.0 0.0 ] = 2.0 4.0] = a(1:2, 1:2) A 2x3 = [a 11 a 21 a 12 a 22 a 13 [0.5 0 0.3 a 23 ] = 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. [a 1 , a 2 , a 3 ] (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
can hold 16 elements.
. 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 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
incremen
t (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 Multi dimensional 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 Initial order After first exchange After second exchange After third exchange 1 2 3 4 5 6 7 8 7 1 8 4 6 3 5 2 1 7 8 4 6 3 5 2 1 2 8 4 6 3 5 7 1 2 3 4 6 8 5 7 After fourth exchange After fifth exchange After sixth exchange After seventh exchange 1 2 3 4 6 8 5 7 1 2 3 4 5 8 6 7 1 2 3 4 5 6 8 7 1 2 3 4 5 6 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
program
shifts
control of the 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 3 rd 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): calc_hypotenuse
Fig. 7-1 and 7-2: • • •
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 than one program unit.
within it accessible to more 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
(2)
sinc
(Fig7-16), (Fig 7-13),
test_sinc test_quadf
(Fig-7-17).
(Fig 7-14),
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 Example
:
sub_as_arguments
(Fig. 7-20) ,
test_sub_as_arguments
(Fig 7-21) (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.
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 1 dimension 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 (2 dimensional array) can be viewed as a series of 1 dimensional 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:
A 3 x 4 matrix A 3x4 : A = 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 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 1 st , then the no. of columns.
Other types of arrays are possible: e.g. LOGICAL, DIMENSION (10,4) :: b e.g. b 10x4 = 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, e.g INTEGER, LOGICAL) variables or constants.
e.g for REAL, DIMENSION (3,4) :: a a(3,4) = 2.0*a(3,4) + 1.0
DO i = 1,4
! Doubles a(3,4) and adds 1 to it ! Replace row 1 of a by a(1,i) = a(3,i)
END DO DO i = 1,3
a(i,2) = a(i,1)
END DO
row 3 of a. Row 3 is unaltered ! Replace column 2 of a by column 1 of a. Column 1 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/) ) We could use nested implied ‘DO’ e.g. for 11 21 12 22 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 1 st column (ii) a(1,:) is the 1 st 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. A 3x4 x B 4x4 = C 3x4 = 3x where 4
k
1 DOT_PRODUCT:
b k j
e.g. Vectors
C C C
3 1 . .
. .
. .
X y
X 3x1 = , y 3x1
X
=
y
2
y
3 dot_product computes
i
1 3
y i
TRANSPOSE: e.g. D 4X3 = A T 3X4 =
a a a a a a a a
MAXVAL:
x
e.g. For array X =
x x
Computes the maximum of x(1) , x(2) , x(3)
a a a a
MINVAL: computes the minimum of x(1), x(2) , x(3) PRODUCT: e.g. for X =
x x x
computes x(1)*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) ! Matrix_b is now the matrix [ 1 2 ]
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' WRITE(*, '(I5)‘) (vector_bc(i) , i=1,3)
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
memory for array elements.
of 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
n 2 = 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 12n 2 elem.’s space .
.
. ! i.e. it needs 12n 2 memory locations for real numbers
.
DEALLOCATE(a) !Free space used by a ALLOCATE(b(3*n , 4*n)) ! Allocate space for b ! Calculate using b ! Uses 12n 2 elem’s space .
.
.
DEALLOCATE (b) !Free space used by b END PROGRAM space Total memory Space = 12n 2 elements space
The same subroutine with standard arrays uses 24
n 2 PROGRAM space IMPLICIT NONE
elements memory space:
INTEGER :: n REAL , DIMENSION(2*n , 6*n) :: a !12n
2 REAL , DIMENSION(3*n , 4*n) :: b !12n
2 elem.’s space elem.’s space !Calculate using a .
.
.
!Calculate using b .
END PROGRAM space ! Total = 24n 2 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 , Assumed Shape 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 ! explicit shape 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
a, b 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) :: & …..
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)
: r
unning_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
+
i
nfinity
or
-
i
nfinity
. 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*10 9 and +2*10 9 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 -10 38 and +10 38 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
34.E3
! Valid if KIND=4 is valid; ! default kind,
please avoid this way 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. double precision) 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
the range is
+ infinity
or for
– infinity
.
INTEGER
on Intel Pentiums : [-2147483648 , 2147483648 ]. A number outside
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