Fortran Class Notes Lecture 4 – “Do” Loops Now it’s time to learn about the “do” command and the looping effect it creates. Remember that programming is useful for performing repetitive operations very quickly? “Do” loops are a major part of that. They are used to make the computer do something many times, with some change(s) each time through. “Do” loops are powerful tools for applications such as processing large arrays, reading/writing tabular information from/to files, and numerically integrating over “differential” time steps. By using variables, a “do” loop can use the same few lines of code to generate vastly different results every time the computer cycles through the loop. You even have the flexibility to choose whether the loop runs a predefined number of times or stops once a certain condition has been met. Let’s look at a simple “do” loop program to get started: program do1 write(*,*) 'Enter an integer to be POWERED UP.' read (*,*) k ! This next write statement inserts a blank line on the screen. ! It's a good trick for making the output look nicer. write(*,*) ' ' do i=1,5 write(*,*) k**i end do write(*,*) ' ' write(*,*) 'Value of i after the "do" loop: ', i stop end This program produces the first five powers of any integer base number. (A bit of syntax: Fortran uses double asterisks to denote exponents.) In this case, we are using “i” as the counting variable, and we’re also using its value in the looped formula. When the computer gets to the “do” command, it sets i = 1 and performs all the commands between “do” and “end do”. Then it goes back to the “do” line, sets i = 2, and checks to see if this new value of “i” is greater than the end value, which is 5 here. As long as the new value of “i” is less than or equal to the end value, the code within the loop will be run again. So, after k^5 is written to the screen, the computer sets i = 6, sees that i is now greater than the end value of 5, and moves on past the “end do” line. The final screen output illustrates this point, because it will show that i = 6 after the “do” loop is finished running. The final value of the counting variable may be important to know in some programs, so keep in mind that it will be one greater than the maximum value you set. Or, to be more technical about it, the final value will be one increment greater than the highest value less than or equal to the end value. (Note: these statements do not apply if the loop ends prematurely, either to a program error or a “kick out” condition, which will be explained later in this lesson.) Example: do t=0.5,5 In this case, the final value after the “do” loop is complete will be t = 5.5, because the increment is 1 (by default), the end value is 5, and the last value less than or equal to 5 is 4.5. So, the counting variable may never actually equal the end value you set, especially if you are counting with a real variable or if your increment is something other than 1. Note that you do not need to set a value for “i” before using the “do” command, because the “do” loop sets its own values for “i”, thus overwriting any previous value “i” may have had. Let’s look at another program with a more advanced “do” loop and an alternative syntax: program do2 25 write(*,*) 'Enter a positive integer to be POWERED UP.' read (*,*) k write(*,*) ' ' j=0 do i=5,0,-1 if (k.ge.1) write(*,*) k**i if (k.lt.1.AND.i.eq.5) then write(*,*) 'Please enter only positive integers!' j=1 end if end do if (j.eq.1) goto 25 write(*,*) ' ' write(*,*) 'Value of i after the "do" loop: ', i stop end This program combines a “do” loop with two “if” constructs for more sophisticated flow control. The other difference in this “do” command is the third element, -1. This is the increment value. If you leave it off, Fortran will use the default value of 1. The increment can be just about anything to suit your needs. This program is using an integer counting variable, so we could use increments of 1, 3, -2, etc. If you are using a real counting variable, you can use increments like 0.5 and -2.76. The increment can be a variable, but it can’t be changed within the loop it controls. There is an indirect way to use shifting increments, which we’ll look at later in this lesson. The purpose of the two-part IF comparison is to make sure that the write statement is only performed once. Otherwise, you’d get six warnings every time you input an integer less than 1. Finally, the j = 0 statement is very important. “j” is basically an error variable, telling the program when the input is invalid, so we need to reset it to default after giving the user another chance to enter a valid integer. Without resetting “j” to 0, the “goto” command will be activated indefinitely after an initial invalid input, even if subsequent inputs are valid. This kind of thing is important to keep in mind when using complex flow controls. Now, let’s look at a more flexible way to control “do” loops: program do3 25 write(*,*) 'Enter a positive integer to be POWERED UP.' read (*,*) k write(*,*) ' ' j=0 n=0 do i=1,100000 if (k.ge.1) write(*,*) k**i if (k.lt.1.AND.i.eq.5) then write(*,*) 'Please enter only positive integers!' j=1 end if n=n+k**i if (n.gt.100) goto 15 end do 15 if (j.eq.1) goto 25 write(*,*) ' ' write(*,*) 'Value of i after the "do" loop: ', i write(*,*) 'Value of n after the "do" loop: ', n stop end This time, we’re not actually using the “do” counting variable. All that matters is that it is set to run so many times that whatever we’re doing inside the loop will be finished long before the actual counting variable ever reaches its end value. Inside the loop, we’re using an indirect sort of counting variable that can be increased by whatever increment we want, even an increment that changes each time the loop runs. Since we’ve made sure that the “do” loop will never finish running on its own, a new condition and “goto” command have been set up to “kick out” of the loop after a certain point. Note that you can use “goto” to exit a “do” loop, but you can never enter a “do” loop except through the “do” command line. This whole setup is very common in programming, because it lets you perform repetitive calculations even if you don’t know how many times you want to repeat the code. For example, you can use this structure for a numerical integration scheme like RK(4,4) in which the differential time step, dt, changes depending on the coarseness of the previous results within the solution. In this program, the “kick out” condition is designed to run the loop fewer times as the output numbers become larger. For an input of 1, the loop will run 100 times, but for an input of 5, it will only run four times. The variable “n” is just the sum of all the powers of “k” that have been run so far. Because the formula for updating “n” involves its own previous value, we have to initialize n = 0 outside the loop. The initialization ensures that we aren’t using some random, crazy value of “n” the first time through the loop. Run these source codes in Force and try changing some of the parameters or even setting up your own problem. Soon, we’ll use “do” loops to read from and write to external files. It’s a very useful skill that you’ll probably be using often, so make sure you understand how to set up these loops!
Pages to are hidden for
"Fortran Class Notes Lecture 4 – “Do” Loops Now"Please download to view full document