Generating a random number in a given range in Fortran 77
I am starting to try to do some engineering experiments using fortran 77. I am using the Force 2.0 compiler and editor. I have the following requests:
- How can I generate a random number between the specified range, eg. if i need to generate one random number between 3.0 and 10.0, how can i do that?
- How can I use data from a text file to be called in calculations in my program. for example i have temperature, pressure and humidity values (hourly values per day, so there are only 24 values in each text file).
- Do I also need to define in the program the number of values in the text file?
The Fortran 77 standard does not specify a random number generator, but you can use any of the countless sources freely provided for this purpose; http://www.cisl.ucar.edu/zine/96/spring/articles/3.random-6.html , for example, has a nice, useful subroutine f77 SRAND
ready for copy and paste.
a source to share
Knuth has a public domain source released in both C and FORTRAN for the pseudo-random number generator described in Section 3.6 of The Art of Computer Programming.
a source to share
Second question:
If your file, for example, looks like this:
hour temperature pressure humidity
00 15 101325 60
01 15 101325 60
... 24 of them, for each hour one
this simple program will read:
implicit none
integer hour, temp, hum
real p
character(80) junkline
open(unit=1, file='name_of_file.dat', status='old')
rewind(1)
read(1,*)junkline
do 10 i=1,24
read(1,*)hour,temp,p,hum
C do something here ...
10 end
close(1)
end
(the indent is a little screwed up, but I don't know how to set it correctly in this strange environment)
My advice: read data types (INTEGER, REAL, CHARACTER), arrays (DIMENSION), I / O (READ, WRITE, OPEN, CLOSE, REWIND) and loops (DO, FOR) I will be doing useful things in no time.
I've never done anything with random numbers so I can't help you, but I think there are some built-in functions in fortran. I'll check it out and report back tomorrow. As for the third question, I'm not sure what you think (you don't know how many lines of data you will have in the file? Or?)
a source to share
You want to check your compiler manual for a specific random number generator function, but most likely it generates random numbers between 0 and 1. This is easy to handle - you just scale the interval to be the proper width, then slide it to fit the correct starting point: i.e. to display r
in [0, 1]
to s
in [a, b]
, use s = r*(b-a) + a
, where r
is the value you got from the random number generator and s
is a random value in the range you want.
Idigas's answer illuminates your second question well - read data using formatted input and then use it just like any other variable.
For your third question, you will need to figure out how many lines there are in the text file only if you want to do something with all of them - if you look at reading a line, process it, and then move on, you can get by without knowing number of lines ahead of time. However, if you want to store all the values in a file (for example, with arrays of temperature, humidity and pressure so that you can calculate vapor pressure statistics), you need to set up the storage somehow. Typically, FORTRAN 77 does this by preallocating an array larger than you think is necessary, but this can quickly become problematic. Is there a chance to upgrade to Fortran 90? The updated version has much better features for dealing with standardized heap allocation, not to mention many other benefits.I would highly recommend using the F90 if at all possible - you will make your life a lot easier.
Another option, depending on the type of processing you are doing, is to research algorithms that only use single passes through the data, so you don't have to store everything in order to calculate things like means and standard deviations, for example.
a source to share
This routine generates a random number in Fortran 77 between 0 and ifin, where i is the seed; some large number such as 746397923
subroutine rnd001(xi,i,ifin)
integer*4 i,ifin
real*8 xi
i=i*54891
xi=i*2.328306e-10+0.5D00
xi=xi*ifin
return
end
You can change to take a specific range.
a source to share