Fortran programming help arrays and arithmetic

In summary, the programmer is trying to learn how to normalize the precipitation values in a text file. They ask for help with how to work with data values read in from the file. The programmer is not sure how to isolate and identify the individual values in a column. They ask for help with how to calculate the mean of a set of numbers. The programmer is told that the mean is the sum of all the numbers divided by the number of numbers. If there are more than one number in a column, then the mean is calculated using the sum of the squares of the numbers in the column. If there are only one number in a column, then the mean is calculated using the sum of the numbers.
  • #1
twomsta
4
0
Hi folks,

To begin with, I have no past programming experience and have just begun to teach myself programming in FORTRAN 95 and I've hit a wall. I'd be very grateful for any assistance here.

I have around 150 text files with three columns of data (I have attached one as an example, and included as my code so far). Essentially, my aim is to normalize all the precipitation data values in the far right column. But to begin with I have written some code to learn the basics and familiarize myself with programming. So far the code counts how many rows of data are in the text file before using that number to limit how many rows are read (I believe so anyways... as I was having issues with the output when FORTRAN tried to read beyond the length of the text file). No doubt my code so far is unconventional as it was a bit of guessing and modifying, but so far it has done what I wanted.

My question comes down to this:
How exactly do I work with the data values read in as 'prcp', in such a way that I can calculate the mean, standard deviation and eventually the z-score. I assume I need to define an array or dimensions of some sort?

I have read and attempted many tutorials, but has left me a bit lost...Thanks for any help!

Code:
program readmet
implicit none 
character(6):: date !I only need the year and month
integer :: endd, period, Nlines
real :: prcp
print*, 'Reads in monthly rainfall values from bureau station data'

!Now calculate the number of rows located in text file (nlines)
Nlines=0
open (5, file='Tprcphq.097091.month.txt')
do
  read (5,*,END=10)
  nlines=nlines+1
  end do
10 close (5)

open (6,file='metout.txt')
write(6,*)' YYYYMM, precipitation (mm)'
write (6,*)'______________________________________________________'

open (5,file='Tprcphq.097091.month.txt')
read (5,*)!read header  
do period= 2, nlines 
  read (5,*)date,endd, prcp
  write (6,*) date, prcp
  print *, date, prcp
     end do
end program readmet
 

Attachments

  • Tprcphq.097091.month.txt
    33.7 KB · Views: 540
Technology news on Phys.org
  • #2
You don't have to define arrays to calculate the mean.

How would you calculate the mean of a set of numbers if you were doing it by hand?
 
  • #3
Thanks for the reply, but unfortunately I don't see what you are getting at :redface:...

Let me put it this way... my output results in two columns of 1277 rows (i.e. the mean would equal the sum off all values in the second column divided by 1277), yet all the values in the second column are read and represented solely by 'prcp'.

Sorry I'm feeling particularly 'slow' today, but I just don't understand how to isolate and identify all the individual values in the second column in such a way that I can carry out simple calculations.
 
  • #4
Yes, I can see that you are 'slow' today.

What is the mean of a string of numbers? It's the sum of all the numbers divided by the number of numbers.

Don't you think you can write some Fortran code which will add up the numbers you read from the data files, count how many numbers you've read, and then calculate what the mean value is? You don't care about storing each individual number for this calculation: you are only interested in the sum and how many numbers there were.
 
  • #5
Listen, I have just started teaching Fortran to myself in my spare time, and my mathematical skills are sound outside of programming. I'm not sure if you are trying to come across as demeaning, but I don't need someone to explain the concept of the 'mean' of a set of numbers.

I'm Sure that I am looking at it the wrong way, but if I was able to work with the data that I have read in I wouldn't of bothered posting in this forum.
 
  • #6
Do you understand how one can update a running total?
 
  • #7
Of course you could use arrays, but this isn't necessary here.
E.g. to calculate the mean you could do

prcpmean=0.0e0
do period= 2, nlines
read (5,*)date,endd, prcp
prcpmean=prcpmean+prcp
end do
prcpmean=prcpmean/(nlines-1)
write(*,*) prcpmean

and similarly for the variance etc.
 
  • #8
You can also eliminate that first loop.
Code:
program readmet
implicit none 
character(6):: date !I only need the year and month
integer :: endd, period, prcpcount
real :: prcp, prcpsum, prcpmean, prcpsquares, prcpvar

print*, 'Reads in monthly rainfall values from bureau station data'

open (6,file='metout.txt')
write(6,*)' YYYYMM, precipitation (mm)'
write (6,*)'______________________________________________________'

open (5,file='Tprcphq.097091.month.txt')
prcpcount = 0
prcpsum=0.0e0
prcpsquares=0.0e0

read (5,*,end=50)!read header
do
  read (5,*,end=50) date, endd, prcp
  write (6,*) date, prcp
  print *, date, prcp
  prcpcount = prcpcount + 1
  prcpsum = prcpsum + prcp
  prcpsquares = prcp*prcp
  end do
50 close (5)

if (prcpcount>1) then
  prcpmean = prcpsum / prcpcount
  prcpvar = (prcpsquares - (prcpsum*prcpsum)/prcpcount)/(prcpcount - 1)
  print *, prcpmean, prcpvar
else
  print *, "Not enough data"
end if

end program readmet
However, now that I've shown you the single pass method of computing the sample variance, I'm going to tell you that your original instincts were good, and (with Fortran) reading through 'Tprcphq.097091.month.txt' twice is the way to go. This is because the 1-pass method of computing the sample deviation can overburden the floating point precision with intermediate results that are quite large values.
Not only that, but you may very well want to hold those values in memory so that you can compute things like the median value.
So...
Code:
program readmet
implicit none 
character(6):: date !I only need the year and month
integer :: endd, period, prcpcount, nprcp
real :: prcp, prcpsum, prcpmean, prcpsq, prcpsquares, prcpvar
real, allocatable :: prcps

print*, 'Reads in monthly rainfall values from bureau station data'

open (6,file='metout.txt')
write(6,*)' YYYYMM, precipitation (mm)'
write (6,*)'______________________________________________________'

open (5,file='Tprcphq.097091.month.txt')
prcpcount = 0
prcpsum=0.0e0
prcpsquares=0.0e0

read (5,*,end=50)!read header
do
  read (5,*,end=50) date, endd, prcp
  prcpcount = prcpcount + 1
  prcpsum = prcpsum + prcp
  end do
50 close (5)

if (prcpcount>1) then
  allocate (prcps(prcpcount))
  prcpmean = prcpsum / prcpcount
  rewind 5
  read (5,*)!read header
  do nprcp= 1, prcpcount
    read (5,*) date, endd, prcp
    prcpsq = prcp-prcpmean
    prcpsquares = prcpsq*prcpsq
    prcps(nprcp) = prcp
    write (6,*) date, prcp
    print *, date, prcp
    end do
  prcpvar = prcpsquares/(prcpcount - 1)
  print *, prcpmean, prcpvar
  ... whatever wlse you want to do with the values...
  DEALLOCATE(prcps)
else
  print *, "Not enough data"
end if

end program readmet
One final warning. It has been a couple of decades since I have done any serious Fortran programming, so expect errors in my code.
 
  • #9
SteamKing said:
Yes, I can see that you are 'slow' today.

This is unnecessarily harsh. Since this is a FORTRAN programming question, let's assume the OP also wants to learn some programming and not just a one-trick solution to a statistics calculation. Ok?
 
  • #10
FactChecker said:
This is unnecessarily harsh. Since this is a FORTRAN programming question, let's assume the OP also wants to learn some programming and not just a one-trick solution to a statistics calculation. Ok?

In that case, maybe you should give the OP some constructive advice about programming, instead of just criticizing other people's efforts.
 
  • Like
Likes 1 person
  • #11
AlephZero said:
In that case, maybe you should give the OP some constructive advice about programming, instead of just criticizing other people's efforts.
There is no reason to think that the OP ever came back after SteamKing's "slow" comment except to tell off SteamKing. I expect he may not return. There is very little to defend about SteamKing's snide "effort", but if you want to, Ok. Maybe I'm just being slow today.
 
  • #12
FactChecker said:
This is unnecessarily harsh. Since this is a FORTRAN programming question, let's assume the OP also wants to learn some programming and not just a one-trick solution to a statistics calculation. Ok?

You did see that the OP used that term first, right? I don't think SK intended to be insulting. He was just acknowledging what the OP said, before proceeding to provide more help to the OP.
 
  • #13
Another point: here on PF, we tend to frown on handing out solutions to problems directly. For the OP's original question of how to calculate the mean without using an array, I would have given a simple example of using a variable to accumulate a sum, and then left it to him to adapt it to his particular situation. Something like this:

Code:
sum = 0
n = 0
do
    read (5,*,end=50) data
    sum = sum + data
    n = n + 1
end do
50  print *, n, ' numbers read, with a total of ', sum
 
  • #14
Thankyou very much DrDu and Scott, that was what I was after... I had tried writing a similar bit of code earlier on but evidently I was making a mistake somewhere along the line.

To the other comments, there was no need to question my understanding of simple statistical terms in the first place and it wasn't just a one off solution to the mean that I was even after. I wasn't looking for a handout or answer to all my problems, just an example such as jtbell provided. As in the tutorials that I have been doing I have found that examples of similar solutions have been the best way of learning, which I then adapt it to suit my data.

Thanks again for all your help and advice! I should be able to calculate the rest of it.
 
Last edited:

FAQ: Fortran programming help arrays and arithmetic

What is Fortran programming?

Fortran is a high-level programming language that is commonly used for scientific computing and numerical analysis. It was developed in the 1950s and has since gone through several updates and revisions. Fortran is known for its strong support for mathematical and scientific operations, making it a popular choice for scientific programmers.

What are arrays in Fortran programming?

Arrays in Fortran are data structures that can hold multiple values of the same data type. They are useful for storing large sets of data and performing operations on them efficiently. Arrays in Fortran are declared using the DIMENSION statement and can have up to seven dimensions.

How do I declare and initialize an array in Fortran?

To declare and initialize an array in Fortran, you can use the DIMENSION statement followed by the array name and the desired dimensions. For example, DIMENSION A(10) declares an array named A with 10 elements. To initialize the array, you can use the DATA statement, followed by the array name and the desired values. For example, DATA A /1, 2, 3, 4, 5, 6, 7, 8, 9, 10/ initializes the array A with the values 1 to 10.

How do I perform arithmetic operations on arrays in Fortran?

To perform arithmetic operations on arrays in Fortran, you can use the built-in array operations provided by the language. These include addition, subtraction, multiplication, and division. For example, A + B adds the elements of arrays A and B and stores the result in a new array. It is important to note that arrays used in arithmetic operations must have the same dimensions.

Can I use loops to perform operations on arrays in Fortran?

Yes, loops can be used to perform operations on arrays in Fortran. The DO loop is commonly used for this purpose. It allows you to iterate over the elements of an array and perform a specific operation on each element. This is useful for performing complex operations on arrays or for updating the values of an array based on certain conditions.

Similar threads

Replies
4
Views
2K
Replies
4
Views
2K
Replies
5
Views
4K
Replies
12
Views
2K
Replies
8
Views
3K
Replies
4
Views
2K
Replies
5
Views
1K
Replies
13
Views
2K
Replies
8
Views
4K
Back
Top