

1. The Basics
In this section we will look at the basics of what a program is and how to make the program run or execute.
The non-trivial example programs can be found in the directory:
$PHYTEACH/part_2/examples
with the name of the file the same as that of the program discussed in this guide.
Some sections are more advanced and are indicated clearly indicated by a thick black line to the right of the text. These can be skipped certainly on a first reading and indeed you will be able to tackle the problems without using the material they discuss.
1.1 A very simple program
A program is a set of instructions to the computer to perform a series of operations. Those operations will often be mathematical calculations, decisions based on equalities and inequalities, or special instructions to say write output to the screen. The program consists of “source code” which is “stored” in a text file. This code contains the instructions in a highly structured form. Each computer language has a different set of rules (or syntax) for specifying these operations. Here we will only consider the Fortran 90/95 (F95 for short) programming language and syntax.
This is a complete F95 program.
The first and last lines introduce the start of the program and show where it ends. Between the first and last lines are the program “statements”. The lines beginning with an exclamation mark are special statements called comments. They are not instructions to the computer, but instead are there to enable us (the programmer) to improve the readability of the program and help explain what the program is doing.
The line beginning write is a statement giving a specific instruction to print to the screen.
Note that except within quotes:
Upper and lower case are NOT significant
(different from Unix commands and files)
Blank lines and spaces are not significant.
1.2 Running the program
Before we can run the program we must get the computer to convert this symbolic language (F95) into instructions it can understand directly. This process is called “compilation”. At the same time the computer will check our program source for errors in the syntax, but not for errors in our logic! In general programs will be assembled from source in many files; bringing all of these instructions together is called “linking”. We perform both of these tasks using the Unix command f95.
f95 -o ex1 ex1.f90
./ex1
write(*,*) ’Hello there’ ’OK’
f95 -o ex1 ex1.f90
1.3 Variables and expressions
The most important concept in a program is the concept of a variable. Variables in a program are much like variables in an algebraic expression, we can use them to hold values and write mathematical expressions using them. As we will see later F95 allows us to have variables of different types, but for now we will consider only variables of type real. Variables should be declared before they are used at the start of the program. Let us use another example to illustrate the use of variables.
f95 -o ex2 ex2.f90
./ex2
This program uses four variables and has many more statements than our first example. The variables are “declared” at the start of the program before any executable statements by the four lines:
After the declarations come the executable statements. Each statement is acted upon sequentially by the computer. Note how values are assigned to three of the variables and then an expression is used to calculate a value for the fourth (s).
Unlike in an algebraic expression it would be an error if, when the statement calculating the displacement was reached, the variables g, t and u had not already been assigned values.
Some other things to note:
1. Comments are used after the declarations of the variables to explain what each variable represents.
2. The ‘*’ represents multiplication
3. The ‘**’ is the operator meaning “raise to the power of”, it is called technically exponentiation.
4. In this program we have used single letters to represent variables. You may (and should if it helps you to understand the program) use longer names. The variable names should start with a character (A-Z) and may contain any character (A-Z), digit (0-9), or the underscore (_) character.
5. Upper and lower case are not distinguished. For example therefore the variables T and t, and the program names vertical and Vertical are identical.
The usefulness of variables is that we can change their value as the program runs.
All the standard operators are available in expressions. An important question is if we have the expression
g * t **2
what gets evaluated first? Is it g*t raised to the power of 2 or t raised to the power 2 then multiplied by g? This is resolved by assigning to each operator a precedence; the highest precedence operations are evaluated first and so on. A full table of numeric operators is (in decreasing precedence)
Let’s look at ways of improving this program. An important idea behind writing a good program is to do it in such a way so as to avoid errors that you may introduce yourself! Programming languages have ways of helping you not make mistakes. So let’s identify some possible problems.
Consider the following modified form of our program:
We have changed three lines and some of the comments. The line:
implicit none
is an important statement which says that all variables must be defined before use. You should always include this line in all programs. 1
The second change is to the line:
real, parameter :: g = 9.8
This in fact defines g to be a constant equal to the value 9.8; an attempt to reassign g via a statement like the one in the original version (g = 9.8 on a line by itself) will now lead to an error. The syntax of this statement is as follows: After the definition of the variable type real we give a series of options separated by commas up until the ‘::’ after which we give the variable name with an optional assignment.
_____________________
1 It is an unfortunate legacy of older versions of Fortran that you could use variables without defining them, and in that case Fortran supplied rules to determine what the variable type was.
We will meet more options later.
Try out these new ideas:
1.4 Other variable types: integer, complex and character
As we have hinted at, there are other sorts of variables as well as real variables. Important other types are integer, complex and character.
Let’s first consider integer variables; such variables can only hold integer values. This is important (and very useful) when we perform calculations. It is also worth pointing out now that F95 also distinguishes the type of values you include in your program. For example a values of ‘3.0’ is a real value, whereas a value of ‘3’ without the ‘.0’ is an integer value. Some examples will illustrate this.
Enter the following program:
First some things to note about the program:
1. We can declare more than one variable of the same type at a time by separating the variable names with commas:
real :: d, r, rres
2. We can place more than one statement on a line if we separate them with a semicolon:
d = 2.0 ; r = 3.0
Some expressions look a little odd at first. Consider the following expression:
n = n + 1
where n is an integer. The equivalent algebraic expression is meaningless, but in a program this is a perfectly sensible expression. We should interpret as:
“Evaluate the right hand side of the expression and set the variable on the left hand side to the value evaluated for the right hand side”.
The effect of the above expression is therefore to increment the value of n by 1. Note the role played by the ‘=’ sign here: it should be thought of not as an equality but instead as an “assignment”.
The complex type represents complex numbers. You can do all the basic numerical expressions discussed above with complex numbers and mix complex and other data types in the same expression. The following program illustrates their use.
The character data type is used to store strings of characters. To hold a string of characters we need to know how many characters in the string. The form of the definition of characters is as follows:
character (len = 10) :: word
! word can hold 10 characters
We will meet character variables again later.
1.5 Intrinsic functions
So far we have seen how to perform simple arithmetic expressions on variables. Real problems will involve more complicated mathematical expressions. As we shall see later, F95 enables you to define your own functions which return values. However, some functions are so common and important that they are provided for us as part of the language; these are called intrinsic functions.
Let us consider a program to compute projectile motion. The program computes the horizontal, x, and vertical, y, position of the projectile after a time, t: 2
1.6 Logical controls
So far all the programming statements we have met will simply enable us to produce efficient calculators. That is useful, but there is a lot more to programming. In this and Section 1.8 we introduce two crucial ideas. The first is the idea of taking an action conditional upon a certain criteria being met. An example will help to introduce this idea. For many years it was the case in Part IA of the Tripos that your maths mark was only included if it improved your overall result. Let us write a program to perform that simple sum. We read in four marks and output a final average.
The if statement is the simplest, but most important, of a number of ways of changing what happens in a program depending on what has gone before. It has the general form:
if ( logical expression) action
As another example we can use it to check for negative values:
if (x < 0) x=0 ! replace negative x with zero
The if construct may also be used in more extended contexts (as above), such as:
if (logical expression) then
xxx
else
xxx
end if
Here if the condition is false the statements following the else are executed. We can also include additional tests which are treated sequentially; the statements following the first logical test to be reached which is true are executed: if ( logical expression) then
if (logical expression) then
xxx
else if (logical expression) then
xxx
else
xxx
end if
1. The full maths course is always counted in the average
2. Quantitative biology mark is only counted if it improves the average
3. Elementary maths for biology is never counted.
if clauses may appear nested, that is one inside another. Suppose we wish to compute the expression which fails if d < 0 or a is zero. If these were entered by a user then they could (incorrectly) take on these values. A good program should check this. Here is some code to do this which illustrates nested if clauses
if (a /= 0.0) then
if (d < 0.0) then
write(*,*) ’Invalid input data d negative’
else
x = b * sqrt(d) / a
end if
else
write(*,*) ’Invalid input data a zero’
end if
1.7 Advanced use of if and logical comparisons
In a large program it is likely that if clauses will be nested, i.e. appear one within another. This causes us no problems, but might make it less clear which end if goes with which if. To overcome this we can name the if clauses. An example illustrates the syntax. Let’s use the example we have just met:
outer: if (a /= 0.0) then
inner: if (d < 0.0) then
write(*,*) ’Invalid input data d negative’
else inner
x = b * sqrt(d) / a
end if inner
else outer
write(*,*) ’Invalid input data a zero’
end if outer
The names are outer and inner; note the syntax, especially the colon. Named if clauses are useful when you want to make your intention clear, but are not essential.
The logical expressions we have met in if clauses can be used more generally with a logical variable. Logical variables take on the value of .true. or .false.. Here is a simple example which illustrates their use.
logical :: l1, l2
l1 = x > 0.0
l2 = y /= 1.0
if (l1 .and. l2) then…
This program fragment could equally well have been written
if ((x > 0.0) .and. (y /= 1.0)) then
Using logical variables may make some things easier to understand.
1.8 Repeating ourselves with loops: do
Loops are the second very important concept needed in a program. If a set of instructions needs to be repeated, a loop can be used to do this repetition. As we shall see we have a lot of control over the loop and this makes them extremely powerful; this is especially true when combined with the if clauses we have just met.
The general form of the do loop is:
do var = start, stop [,step]
xxx
end do
where as before the parts in square brackets are optional.
The loop works by setting var to start. If var stop the statements up to the end do are executed. Then var is incremented by step. The process then repeats testing var against stop each time around the loop.
This program is an example which computes factorials:
if (n > 10) exit
1.9 The stop statement
We have just seen how the exit command can be used to terminate a do loop. If you wish execution of your program to cease, you can insert a stop statement; this can incorporate some text, which is output when your program halts and identifies where this happened, e.g.
stop ’this is where it all ends up’
1.10 Arrays
A great deal of scientific computation involves the manipulation of vectors, matrices and more general arrays of numbers. In F95 we can have an array of variables set up in the declarations statements.
How do we specify arrays? The simplest way is to give the dimension in parentheses.
real :: a(3) ! a is an array of 3 values: a vector
real :: m(3,3) ! m is a rank 2 array: a matrix
We call the part in parentheses a shape. Each element of the array can be addressed in the program using a similar notation. Here is a simple example:
Notice how we use a loop to compute the sum over all elements of the vector.
A second example will show us how we can implement simple vector and matrix operations:
We can also have arrays of integer, complex or any other data types declared in analogous ways.
Arrays may be declared using other forms than those given above which can be useful for different situations. The dimension option to the declaration may be used to set a shape for all declared variables which do not have a particular shape specified for them. The dimension statement serves several purposes in a F95 declaration. In the following, note the critical nature of the punctuation, particularly ‘,’, ‘:’ and ‘::’.
An example of the simplest form of an array declaration for a matrix might be:
real, dimension(10,11) :: a ! a is a rank 2 array
The array subscripts are assumed to start at unity, but this can be altered by using the explicit form of the declaration in which the range of the array subscripts is given separated by a colon:
real, dimension(0:9) :: a ! vector of 10 elements
! starting at 0
We can also declare a variable to be an array of unknown size. We do this as follows
real, dimension(:), allocatable :: a
and at an appropriate time, when it is known how big this array needs to be, we use the following (say to create an array of 10 elements):
m=10
allocate(a(m))
where m is an integer variable. When the use of the array in the program is finished, the space can be released by using
deallocate(a)
1.11 Array arithmetic
One very useful feature of F95 is the ability to work with whole arrays. In most programming languages one can, say, add two arrays using a loop. For example
real :: a(10), b(10), c(10)
integer :: i
[ some statements to setup the arrays]
do i=1,10
c(i) = a(i) + b(i)
end do
F95 allows you to perform whole array operations in a natural way. Most of the normal arithmetic operations can be carried out on arrays, where they apply in an element by element fashion. The above example can be written as: real :: a(10), b(10), c(10)
real :: a(10), b(10), c(10)
[some statements to setup the arrays]
c = a + b
where (logical array test)
[statements if test true]
elsewhere
[statements if test false]
end where