Fortran Fortran, is it possible to count the number of times a particular valu

  • Thread starter Thread starter fluidistic
  • Start date Start date
  • Tags Tags
    Count Fortran
AI Thread Summary
The discussion centers on using Fortran to count occurrences of integer values from a data file, specifically how to efficiently implement this using an array instead of individual variables for each count. Participants suggest initializing an array to store counts and eliminating the cumbersome if-then-else structure for counting. A participant struggles with correctly assigning values to the count array and initializing it properly, leading to incorrect output. The conversation also touches on the choice of programming languages for data analysis, with Python being recommended for its ease of use, while the original poster expresses a desire to learn Java for future projects. Overall, the thread highlights the challenges and solutions in programming for data analysis in Fortran.
fluidistic
Gold Member
Messages
3,928
Reaction score
272
I have a data file with 21 values in it, which range from 2 to 10 by integers values.
I would like to know whether it's possible to write a Fortran code to count the number of times a particular value (for instance "6") appear in the file. Let's call x_i the number of times the value i appears in the data file.
Eventually I would like to write in a new text file the following:

Code:
i=0
do while (i.le.21)
write (11,*)i, x_i
i=i+1
end do

So when I plot into gnuplot the data of the file 11, I can check out immediatly whether the data distribution looks like a Gaussian.

I took a numerical analysis course a few years ago, but from what I remember I don't see anything that could help me here.
Do you have any idea?
Thanks.
 
Technology news on Phys.org
Well I've found out a way, although I think it's pretty horrible and inneficient.
Here my full code:
Code:
program dataanalyzer
implicit none

real :: mean 
integer :: x_i ,i , x_j ,n, n_0,n_1,n_2,n_3,n_4,n_5,n_6,n_7,n_8,n_9,n_10
n=21
n_0=0
n_1=0
n_2=0
n_3=0
n_4=0
n_5=0
n_6=0
n_7=0
n_8=0
n_9=0
n_10=0

i=1
x_j=0

open(12,file='datanotes.txt')
do while (i.le.21)
open(11,file='notes.txt', status='old')
read(11,*)x_i
x_j=x_i+x_j
if (x_i==0) then
n_0=n_0+1
else if (x_i==1) then
n_1=n_1+1
else if (x_i==2) then
n_2=n_2+1
else if (x_i==3) then
n_3=n_3+1
else if (x_i==4) then
n_4=n_4+1
else if (x_i==5) then
n_5=n_5+1
else if (x_i==6) then
n_6=n_6+1
else if (x_i==7) then
n_7=n_7+1
else if (x_i==8) then
n_8=n_8+1
else if (x_i==9) then
n_9=n_9+1
else if (x_i==10) then
n_10=n_10+1
end if

i=i+1
end do
write(12,*)n_0,n_1,n_2,n_3,n_4,n_5,n_6,n_7,n_8,n_9,n_10

close(11)

mean=x_j/21.
write(*,*)'The mean value is',mean 


end program
Do you know of a better way?
 
Instead of having a particular named variable for each possible value, e.g., n_0 ... n_10, use an integer array, like icount (0:10), where the number of zero data items is stored in icount (0), the number of one data items is stored in icount (1), etc. The cumbersome 'if-then-else' structure can be eliminated.
 
Thanks for your reply and insight SteamKing
SteamKing said:
Instead of having a particular named variable for each possible value, e.g., n_0 ... n_10, use an integer array, like icount (0:10), where the number of zero data items is stored in icount (0), the number of one data items is stored in icount (1), etc. The cumbersome 'if-then-else' structure can be eliminated.

I'm confused. Do you mean icount could have values than range from 0 to 10 (i.e. range is 11) so I should declare it as
Code:
integer, dimension (11) :: icount
?
I don't know how to assignate the value of the number of times x_j appears in the data, to icount.
 
for an array to take on indeces other than 1 thru n, you simply specify the end indices explicitly: dimension(0:10)

also, you shouldn't be opening file unit 11 inside the loop...you should before you enter the loop.
 
gsal said:
for an array to take on indeces other than 1 thru n, you simply specify the end indices explicitly: dimension(0:10)

also, you shouldn't be opening file unit 11 inside the loop...you should before you enter the loop.

I see. Thanks.
I've been trying different things, but wasn't successful to assignate a meaningful value of counting to icount.
I've simplificated my previous program into
Code:
program notes
implicit none

real :: mean 
integer :: x_i ,i  ,k
integer, dimension(0:10) :: icount

i=1

open(12,file='datanotes2.txt',status='old')
open(11,file='notes.txt', status='old')

do while (i.le.21)
read(11,*)x_i




i=i+1
end do

    do k=0,10,1
    write(12,*)k,icount(k)
    end do

close(11)
close(12)



end program
I'm wondering if my line
Code:
read(11,*)x_i
should involve
Code:
icount(something)
.
 
Each time you read an x_i, make sure it's within the range 0 -> 10, and then increment icount(x_i). You need to zero out icount() first though, before you start the loop. The program is using the array icount() to implement a "histogram".
 
rcgldr said:
Each time you read an x_i, make sure it's within the range 0 -> 10, and then increment icount(x_i). You need to zero out icount() first though, before you start the loop. The program is using the array icount() to implement a "histogram".

Basically I tried this and other related tries but I failed to get meaningul numbers.
For example the code
Code:
program notes
implicit none

real :: mean 
integer :: x_i ,i  ,k
integer, dimension(0:10) :: icount

i=1

open(12,file='datanotes2.txt',status='old')
open(11,file='notes.txt', status='old')

icount(0)=0
do while (i.le.21)
read(11,*)x_i
icount(x_i)=icount(x_i)+1
i=i+1
end do

    do k=0,10,1
    write(12,*)k,icount(k)
    end do

close(11)
close(12)
end program
gives me
Code:
      0           0
           1     5340772
           2           3
           3     6373366
           4           2
           5    15982582
           6           5
           7     5398641
           8 -1075462965
           9    12539569
          10   156810263
And yeah the values of the file 11 are within 0 and 10. The mean is approximately 5.
But I know the code is wrong. For example if x_1=5 and x_2=8, the loop says that icount(5)=0+1=1 and then the second iteration says icount(8)=1+1=2.
The n'th iteration should do icount(x_n)=n. So that's wrong indeed. I don't know how to fix this properly.
 
In your latest code, only icount (0) has been initialized. How about the rest of the array?

Instead of icount (0) = 0, you need to loop thru all of the entries in icount array and initialize.
 
  • Like
Likes 1 person
  • #10
actually, fortran 90 can handle arrays a-la-matlab, so, there is no need to loop, simply initialize the array without any indices:
Code:
icount = 0
 
  • Like
Likes 1 person
  • #11
Thank you very much guys. This worked!
I'm going to play some more with "allocatable" to read other txt or data files with arbitrary dimension.
 
  • #12
Why Fortran?
 
  • #13
Why not?
 
  • #14
Somehow it would be not my language of choice for this kind of problem.
 
  • #15
Borek said:
Why Fortran?

My dream was to do it in java, but I have 0 knowledge of it. Since I knew some Fortran I wanted to make sure I could do it in that language and then try to learn a new language :)
By the way, what language would you "recommend"?
 
  • #16
Python perhaps.

How large are your data files?
 
  • #17
Borek said:
Python perhaps.

How large are your data files?

I have one file that I downloaded, if I remember well it's equivalent to a 10,000*10,000 matrix or something similar. Now I don't really have any specific other files, I thought about generating them or download some data I can find to play with. I have in mind for example downloading the rating of internet chess/go players and see how "screwed" the Gaussian is due to computer programs (for chess). Or maybe the number of moves a chess games lasts if I download a pack of thousands of chess games, etc.

Ok so python is really recommended as far as I can see. For "serious" calculations I thought about using Fortran and for fun I wanted to learn java mainly because I've a tablet with Android and I've read that all applications in Android are written in java. In this way python would be similar to Fortran for my purpose, so I guess I'll head toward java if I have the time.
 
  • #18
fluidistic said:
I've been trying different things, but wasn't successful to assignate a meaningful value of counting to icount.
I've simplificated my previous program into
Code:
program notes
[/QUOTE]
"Assignate" and "simplificate" are not words in English.

I can see how you got them - assignation is a word and simplification is a word, so by back-substitution, you arrived at assignate and simplificate.

The correct words are "assign" and "simplify."
 
  • Like
Likes 1 person

Similar threads

Replies
5
Views
5K
Replies
4
Views
2K
Replies
6
Views
2K
Replies
8
Views
2K
Replies
8
Views
4K
Replies
8
Views
4K
Replies
4
Views
2K
Replies
2
Views
2K
Back
Top