next up previous index
Next: Defining a Module and Up: The Goodness of Fit Previous: More Mathematical Background

More about Fortran

Before we focus on implementing equations 2.17, 2.18, and 2.19, we must first modify our main Fortran program a little, so that it takes definitions of complete and incomplete gamma functions from an external module. Since those definitions are more than likely to be used in many other contexts, it is a good idea to implement them separately in a module that can then be included in other Fortran programs.

Figure: Program chi.f90 modified to include definitions from module euler and to write $\chi ^2$ fit data on a file chi.out.
...nd program chi\end{verbatim}\end{tex2html_preform}\end{footnotesize}\end{figure}

Figure 2.10 shows a couple of modifications. First, notice that the definition of long:  

integer, parameter :: long = selected_real_kind(9,99)
vanished from the listing, to be replaced by a call
use euler
This is the name of a compiled module, which is to be searched for definitions used by our program. In particular the definition of long has been moved there.

The other novelty in this program is a new integer constant output, which is then used in the call to open. Unlike in C, in Fortran file manipulation facilities are a part of the language itself. This ensures a high level of portability of Fortran programs. From a programmer's point of view it makes little difference whether open has to be loaded from a libc.a or whether it is a part of the language itself, because it has to be called anyway.

In our case the open  statement

open (unit=output, file='chi.out', status='replace', action='write', &
      iostat=status, err=99)
has the following effect. A file chi.out is opened for writing and bound to a Fortran logical unit number output. If the file already exists, it is removed and replaced with a new file. Whatever exit status is going to be returned by this operation will be saved on the integer variable status. In case an error is returned, the program will jump to label 99.

The writing then proceeds as before with the exception that instead of writing on * we write on output, i.e., on a logical unit bound to file chi.out.

It may happen that for some reason, the file cannot be opened for writing . For example, there may already be a file chi.out in that directory, and it may be protected. Or perhaps there is not enough space in user's area to open a new file. In that case the program will jump to the following part of the code:

99 continue
  write(*, '(1a, $)')   'error: cannot open file chi.out, '
  write(*, '(1a, 1i6)') 'IO status = ', status
  stop 1
The statement continue  does nothing: it is a useful flag though to which one can jump. Once there the program writes an error message and the value of the IO status returned by open. This value can then be looked up in order to find out what went wrong.

The statment stop 1 , stops the program and prints 1 on standard output.

It is a good Fortran tradition to group all error handlers towards the end of the program file, so that they don't clutter the code itself. Another way to handle potential problems would be to inspect the value of status. It should be 0 if an operation was successful and it should be set to a positive integer if it wasn't. In that case the resulting code would look similar to the way IO problems are handled in C.

But if all went just fine and the file chi.out has been written out and closed  successfully, the program proceeds to

q = goodness( (n - 2.0_long) / 2.0_long, chi_2 / 2.0_long )
Function goodness and its interface are defined in module euler. Observe the notation 2.0_long, which upgrades 2.0 to a format specified by long.

After the function returns, $\chi ^2$ fit results, $a \pm \sigma_a$, $b \pm \sigma_b$, $\chi ^2$, and Q, are written on standard output and the program exits through stop 0.

The reason why we have chosen to write plot data on a separate file, chi.out, is because we don't want the two streams of data mixed.

Fortran write statement is quite similar to printf in C and to format  of Common Lisp. An experienced multilingual programmer would probably assert that they're all similar, because they all have to perform a similar task. Its first argument specifies a logical unit, i.e., a file, to write on. Its second argument is a string that specifies a format in which data is to be written out. The remaining entities following the write statement on the same line are data items to be written out. Table 2.2 explains the meaning of formatting directives used in the program.

Table 2.2: Format specifications used in program listed in Figure 2.10.
specifier meaning
/ an additional newline
1a one string of unspecified length

one floating point number 7 spaces wide, and with 3 digits after the decimal point


do not terminate the write with a newline: otherwise all writes are terminated with a newline by default

1i6 one integer 6 spaces wide

two times whatever has been specified inside the brackets


next up previous index
Next: Defining a Module and Up: The Goodness of Fit Previous: More Mathematical Background
Zdzislaw Meglicki