Week ? Questions

General Programming Practices, Fortran Language, Fortran Compiler, Unix, General Computing, Numerical Methods, Class Procedures

General Programming Practices

Are there times when you can't find errors even with the debugger?

Yes and no. In 20 years of using debuggers, I've never run across an error that I couldn't locate with a debugger. However, to find some of them, I've had to learn how to use the debugger to look at the contents of individual machine instructions and watch execution one machine instruction at a time. That's a much heavier use of a debugger than most of you will get into, an relied on the fact that I was able to make sense of the actual machine instructions. Several of these errors turned out to be errors in the compiler rather than in my Fortran.

How do you take a piece of code from one program and insert it into another?

The easiest way is to open each program in a separate window. Use the mouse to select the text that you want to copy (hold down the left button). In a Workstation window you just have to highlight the text, but in a Windows window you need to select the Copy item from an Edit menu. After that selection go to the window with the program to receive the text. Put your editor into Insert mode at the point you want the text, just as if you were ready to type it in. In a Workstation window all you need to do now is click the center mouse button. For Windows, select "paste" from the Edit menu.

In your opinion, since Fortran is so old and other languages are constantly coming out, in our careers, will it ever be done away with?

One thing that is certain in this world is change. I expect Fortran to vanish as a programming language, or to evolve beyond current recognition within the span of your professional careers. At some point I expect descendants of things like Visual Basic or voice driven methods to dominate. However, you'll probably see recognizable Fortran strong for at least another 10 years just based on the inventory of useful programs and the dominance of HPF (high performance Fortran) in the parallel processing business.

How does the computer know that the variables represent the same value if they're called different things in the program than in the function?

It's all in the alignment between the elements of the calling argument list and the dummy argument list of the function. If I write:

     z  = 2*hfun(a,b,c)+1.
and later define the function hfun with the opening statement:

      function hfun(x1,x2,x3)
The computer makes a direct pair-wise connection between the arguments in the reference and the function itself. x1 pairs with a, x2 pairs with b, and x3 pairs with c. That's all that the computer cares about. When the "z=2*hfun(a,b,c)+1." assignment statement is executed the computer makes a note that the first dummy argument of hfun, "x1" refers to the address in memory given the name "a". The second argument "x2" is really the contents of "b", etc.

Why should we use the debugger program if we can use vi to look through your program?

Always look through my programs with vi or the Web browser first. You use the debugger, when there is some question in your mind exactly how the program will work. Then by using the "step" command in the debugger, and watching how the values of variables change, you get a better idea of the actual operation of the program.

Fortran Language

For this week my question is: in the function statement, what determines what variables are contained in the parentheses.

You do. You look at the expressions evaluated in your function, and locate those things that you only evaluate once based upon known information (gravitational constant, speed of sound, things like that). Those should be parameters whose value is set within the function, or in rare instances set within a Module.

real, parameter :: g=9.807, c=300.

Those quantities needed by the function that will take on more than one value during the execution of you program or are not known until obtained as input, should be passed through the parentheses.

One piece of information that is still confusing to me is the order of operations. I do not believe that is the correct term but I mean the differences with a program, subprogram, subroutine, and things such as that.

First thing you need to know is that when I use the term "subprogram" to cover behavior of both "subroutines" and "functions". For now "subprogram" means either "function" or "subroutine". Later I may confuse matters by referring to a "Block Data" routine as a subprogram, but it is a very special, limited (and obsolete) subprogram.

I use the term "main program" to refer to the program unit beginning with a "program card", and hopefully only use "program" alone to refer to the total collection of "main program" and all subprograms and modules, needed to do your complete job. The "main program" is the only program unit with a guaranteed place in the order of doing things. Execution of your Fortran program always starts with the first executable statement of your main program. From there the order in which your subroutines and functions are executed depends on where you put the CALL statements for the subroutines, and where you use your functions in assignments or other program expressions. When a CALL is associated with a branching structure, the associated subroutine may not even be used in a given execution of a program. Look at the following simple program.

      program test
      implicit none
      real a,b,c, func1, func2
     call sub1(a)
     if (a.ne.0) then
         call sub2(a,b)
         c = b*func1(a)
         b = 1.0
     subroutine sub1(x)
     implicit none
      real x
      subroutine sub2(x,y)
      implicit none
      real x,y
      y= 3./x
      real function  func1(x)
      implicit none
      real func1,x
      func1 = x**2+1
      real function  func2(x)
      implicit none
      real func2,x
      func1 = 1/x**2

In this example, execution begins with the call to sub1 which causes the value of "a" in the main program to be set to 1.0. The main program then tests "a" and decides to all subroutine sub2, to set the value of "b", it then executes the instructions in function func1 as part of the process of assigning a value to c (c=b*func1(a)). Because of the path through the IF, THEN, ELSE, the function func2 is never used.

Try running several of my examples under xldb using just the "step" command to help you understand the flow of the program instructions.

I learned many things this past week, but one of the most important was how to write my own functions. I think that this will help me do some of my other classes' homework faster since I can write a program for it. One aspect that I didn't understand was with the "open, write, and close" commands. Where do you find the unit numbers to place there?

The concept of a unit number, goes back to the days when we moved a lot of data (and programs) on and off of tape units. Each tape unit had its assigned number, as did the card reader (usually unit 5) , card punch (usually unit 7), and high speed printer (unit 6). As a result of these old conventions the computer keyboard is frequently unit 5 and the screen is unit 6 by default. We don't use tapes much anymore, relying primarily with disk files. You are free to associate any integer unit number (sometimes restricted to less than 100) with a file name via the open statement. If you want to write information to a file named "output.data", you pick a number to associate with the name (I usually start with 11, and work up as I need more files). You make the formal association between the number and the file name with the open statement, at the same time that you set up some other internal information for using the file with the OPEN statement.

      open (11, file='output.data')
Now you can use the write statement to put information into that file with statements like:

write(11,*) x,y,z

The CLOSE statement is useful if you want to quit writing the "output.data", but repeat some or all of the write(11,... statements to put information into another file (say "output1.data"). Before you can associate the unit number 11 with a different file, you must disassociate it from "output.data" with the simple:


In the process of closing a file, the CLOSE statement, does something very important. You rarely notice, but a PRINT or WRITE statement does not put information directly onto the disk. It stores the information in a block of the computer memory associated with your program, called a buffer. When the buffer is filled its contents are then automatically written to the disk. It is much faster to write one large string of information to disk than a bunch of small chunks with the same total length. If you look at some of my samples that produce graphics by executing gnuplot, you will see that use CLOSE to be certain that the files I've written for gnuplot contain all of the information that they should.

When you write an IF-THEN statement do you have to write the instructions on the following line?

I the THEN is present, yes. For example

      if (x.gt.5) then
However if you only want to execute a single statement on a "True", you can put it on a single line using a standard logical IF (no THEN):

      if (x.gt.5) y=4/(x-5)
In the IF statement if there is only 1 ELSE, do you have to say ELSE IF ( ... )?

No. Both the ELSE and ELSE IF statements are optional when using IF,THEN. Look at the above for an example of no ELSE or ELSE IF. You use ELSE alone when you are in a situation requiring one (and only one) of two possible actions. For example, either do the calculation, or stop on an error condition:

      if (x.gt.5) then
         print *, ' Invalid value for x, ', x
How would you set parameters for an IF-THEN statement (i.e. 10<x<30)?

When using bounded ranges like 10<x<30, you must resort to Boolean algebra (here the application of .AND.). For example

      if (x.gt.10 .and. x.lt.30) then

Is there a limit to how many IF statements that can be put into a program?

No, not formally. I have killed some compilers with program units (subroutine, function, main program) that have way to many statements. This is, however, bad programming practice, and I haven't had the problem in years, because I carefully break things down to sensibly sized (few hundred lines at most) subroutines and functions, and also because the compilers have gotten better.

When do you use an integer or a floating point in the functions?

Usually its simply your decision based on the kind of number you need for the calculation. For most calculations, you need floating point numbers. However, when you just need to count some set of things, or provide a finite number of identification numbers, integers work well. We won't get into heavy integer use until we start using arrays. In the case of dummy arguments to the function, the type (integer or real) may be dictated to you by somebody's definition of the function.

I'm still not clear as to what a parameter is or what " implicit none" does.

A parameter is just a way to associate a simple name with a constant value for example:

       parameter (pi=3.14159)
It is constant in the sense that it can never be changed in your program after the initial definition. This lets you abbreviate a long string of digits with a meaningful name, and protects you from accidentally switching this important value in your program. What accident? I might set a variable "g=9.807" and later intend to enter the line "h=10", but because I get uncoordinated late at night actually type the line "g=10". If "g" had been set as a parameter, this later typographic error would show up as a Fortran syntax error, rather than subtly changing "g".

Implicit None forces you to declare the type of every variable in your program and results in a syntax error for every variable that you enter which hasn't appeared in a type (REAL, INTEGER, etc) statement. This again protects you from typographic errors. I might intend to enter the line:

      height = hmax- .5*g*t**2
but actually type

      hieght = hmax - .5*g*t**2
This later line would result in a Fortran error as long as I hadn't repeated the mistake of typing "hieght" in a REAL statement

Fortran Compiler


If Unix is case sensitive, then why is it that we seem to be able to use any case?

You can use any case when you write a Fortran program, because the Fortran compiler is not case sensitive (unless you trigger a special option). The compiler reads your program file, not Unix. You get into case sensitivity problems when you are talking to Unix itself. For example, when you are trying to list the files in your current directory try typing "LS" instead of "ls".

General Computing

Why do I always have problems with the telnet hookup from a cac lab?

Have you stretched the window until the scroll bars vanish? Have you used the "set term=vt100" command? If yes to both then, you should arrange to meet me in a CAC lab, so I can take a look at what's happening.

Why do the ptph links keep screwing up?

The only problem that I've experienced is dialup connections through the CAC. After I've been on for one hour, I can be disconnected at any time to make room for another user. This is official Computer Center policy. If you are experiencing a different kind of problem, send me the details, and I'll try to track down the problem.

Numerical Methods

What is interpolation used for?

The class Web notes present a common use of filling in values for physical quantities in the gaps between regions of known values. Once we learn arrays, you will see a much more common and powerful use for interpolation. As an example, I may have very precise data on the viscosity of water from data taken every 10 degrees Centigrade from the freezing point to the boiling point. In a serious calculation of the flow of water, I need values of viscosity at any temperature. When I need the viscosity at 31 C, I interpolate between the known values at 30C and 40C. Interpolation is my way of dealing with the fact that I can only have data for any physical information at a finite number of points.

Class Procedures

When is it good to Email nsm105?

Whenever you have questions on Application Labs, Homework grades, or material that Nate has specifically presented on Wednesday Recitation. You can E-mail me (jhm@psu.edu) for any question or problem, except perhaps Applications Labs (I'm not directly involved in that portion of the class).

When is our first test?

Wednesday February 19 at 8PM in 102 Forum.

I have one question concerning homework #5, though. in the directions, it says to have the inclination angle of the cannon to be set in radians, but later on it says that cannon.f reads it in degrees. does this mean that the rest of cannon.f (the part we don't write) converts it, or do we have to include something that converts it in our function? if so, do we have to set a parameter statement for pi?

Look at the input subroutine, it does the conversion for you. When you write your line in the subroutine, you can assume that the angle is already in radians.

I don't understand why my program is not working for homework five but am working on it.

Any time you stumped on a problem send E-mail to me or your TA. We will try to help you past difficulties. Usually we can look at your file on the computer, and offer suggestions in an E-mail reply. Saves you trying to find us at odd hours of the day

Back to other 1997 Questions and Answers / Home

Maintained by John Mahaffy : jhm@psu.edu