Counting Numbers in Curly Braces in Fortran?

Click For Summary

Discussion Overview

The discussion revolves around counting numbers enclosed in curly braces within a Fortran program, specifically from a data file named Aggregation.dat. Participants explore various methods and considerations for implementing this functionality in Fortran, while also discussing alternative programming languages.

Discussion Character

  • Technical explanation
  • Homework-related
  • Debate/contested

Main Points Raised

  • One participant seeks assistance in counting numbers specifically between curly braces in a Fortran context.
  • Some participants inquire whether the request is related to a homework assignment and ask about the original poster's experience with Fortran.
  • Alternative programming languages such as Awk, Perl, Python, and Ruby are suggested as potentially more suitable for the task.
  • There is a discussion about what exactly should be counted: characters, numbers, or digits within the braces.
  • A proposed solution involves reading the file line by line, identifying the position of curly braces, and counting based on the defined criteria.
  • One participant mentions that if there are multiple numbers in braces, they represent aggregates, while a single number indicates a free molecule, leading to a desire to count only free molecules.
  • Another participant provides a Fortran code snippet that reads the data file and extracts numbers from the curly braces, but notes the need for adjustments if the number of lines to skip varies.
  • Suggestions are made to allow user input for the number of lines to skip or to define a parameter for this purpose in the code.
  • One participant suggests looking for the first occurrence of brackets or the keyword "AGGREGATES" to streamline the process of finding the relevant data.

Areas of Agreement / Disagreement

Participants express various viewpoints on the best approach to counting the numbers in curly braces, and there is no consensus on a single method or solution. The discussion remains unresolved regarding the optimal implementation in Fortran.

Contextual Notes

There are considerations regarding the variability in the number of lines to ignore, which may depend on the specifics of the simulation being conducted. This introduces uncertainty in the implementation of the proposed solutions.

Karlisson
Messages
7
Reaction score
0
< Mentor Note -- thread moved to HH from the technical forums, so no HH Template is shown >[/color]

I have a file Aggregation.dat
########################################################################################
6.999e+04 4.50000e+01 2.22222e+00 4.94813e+00 2.50000e+01 1.00000e+00
7.004e+04 4.40000e+01 2.27273e+00 4.99711e+00 2.50000e+01 1.00000e+00
7.009e+04 4.30000e+01 2.32558e+00 5.04732e+00 2.50000e+01 1.00000e+00
MAX 25 MIN 1 AVG 2.325581 STD 5.047315 AGG_NUM 43 AGGREGATES { 0 } { 6 } { 7 } { 8 } { 9 } { 14 } { 63 57 35 70 62 3 31 32 1 24 64 10 39 94 5 68 74 54 2 40 12 28 27 17 } { 21 } { 30 } { 33 } { 34 } { 36 } { 37 } { 41 } { 43 } { 46 } { 52 48 } { 49 } { 50 } { 51 } { 56 } { 59 } { 61 } { 66 } { 69 } { 73 } { 20 91 60 4 71 19 13 58 53 80 25 76 47 93 29 16 45 38 22 92 72 18 65 11 75 } { 77 } { 78 } { 79 } { 81 } { 84 } { 85 } { 86 } { 87 } { 88 } { 89 } { 90 } { 83 15 67 42 82 44 55 26 95 } { 96 } { 97 } { 23 98 } { 99 }
#######################################################################################

I would like to count only the numbers that are only between "{ }", does somebody have an idea of how to do in fortran?

Please help me.
 
Last edited by a moderator:
Physics news on Phys.org
Welcome to PF!

Is this a homework assignment?

What is your experience with Fortran?

Would some other language like Awk, Perl, Python or Ruby be more suited to the problem?
 
jedishrfu said:
Welcome to PF!

Is this a homework assignment?

What is your experience with Fortran?

Would some other language like Awk, Perl, Python or Ruby be more suited to the problem?
I am doing research for my MSc with the assistance of simulations, but since I use scripts to some calculations in fortran, for this my option in fortran,
Excuse my writing, I do not speak English.
 
Do you want to count characters (topic), numbers (first post), digits, or something else?

Take { 23 98 } for example:
1 because it is one bracket pair?
2 because there are two numbers?
4 because there are 4 numeric characters (digits)?
7 because there are 7 characters between the brackets?

Worst case: loop over the whole file, check digit by digit where you are, keep track of what you want to count. I don't know Fortran, but that solution will work in every programming language and does not require more specialized features.
 
Karlisson said:
I would like to count only the numbers that are only between "{ }", does somebody have an idea of how to do in fortran?

How would you do it in C? Or in Tcl/Tk? Do you know any other programming languages?

Have you done any character file scanning up to now in your learning of FORTRAN?
 
mfb said:
Do you want to count characters (topic), numbers (first post), digits, or something else?

Take { 23 98 } for example:
1 because it is one bracket pair?
2 because there are two numbers?
4 because there are 4 numeric characters (digits)?
7 because there are 7 characters between the brackets?

Worst case: loop over the whole file, check digit by digit where you are, keep track of what you want to count. I don't know Fortran, but that solution will work in every programming language and does not require more specialized features.
Each number is related to a molecule. If you have more than one number between "{}" means that it is an aggregate, Ex .: { 28 31 5 }.
If there is only one number in "{}", this molecule is free, Ex .: {19}. I want to count only the free molecules.
 
berkeman said:
How would you do it in C? Or in Tcl/Tk? Do you know any other programming languages?

Have you done any character file scanning up to now in your learning of FORTRAN?
I use tcl / tk. To this objective, I have not done any script. But I have done for other objectives.
 
Hhhmmm...I copied and pasted the input data from above, it looks like this:
Code:
6.999e+04 4.50000e+01 2.22222e+00 4.94813e+00 2.50000e+01 1.00000e+00
7.004e+04 4.40000e+01 2.27273e+00 4.99711e+00 2.50000e+01 1.00000e+00
7.009e+04 4.30000e+01 2.32558e+00 5.04732e+00 2.50000e+01 1.00000e+00
MAX 25 MIN 1 AVG 2.325581 STD 5.047315 AGG_NUM 43 AGGREGATES { 0 } { 6 } { 7 } ...
meaning, the aggregates are found in the forth line of the input file; so, I read and ignore the first 3 lines.

Take the following code and put it in a file named, say, nagg.f90
Code:
program nagg
  character(1000) line
  integer i, j, k, first, last

  read(*,*) line
  read(*,*) line
  read(*,*) line
  read(*,'(A1000)') line    
  first = index(line, "{")
  last  = index(line, "}", .true.)
  write(*,*) "Aggregates:"
  i = first - 1
  do
    j = (i-1) + ( index(line(i:1000), "{") + 1 )
    k = (i-1) + ( index(line(i:1000), "}") - 1 )
    if (index(trim(adjustl(line(j:k)))," ") == 0) write(*,*) line(j:k)
    if (k+1 == last) exit
    i = k + 2
  end do    
end program nagg
Compile like this:
Code:
gfortran -o nagg nagg.f90
Run like this:
Code:
nagg < Aggregation.dat
It should output the following:
Code:
 Aggregates:
  0 
  6 
  7 
  8 
  9 
  14 
  21 
  30 
  33 
  34 
  36 
  37 
  41 
  43 
  46 
  49 
  50 
  51 
  56 
  59 
  61 
  66 
  69 
  73 
  77 
  78 
  79 
  81 
  84 
  85 
  86 
  87 
  88 
  89 
  90 
  96 
  97 
  99
 
gsal said:
Hhhmmm...I copied and pasted the input data from above, it looks like this:
Code:
6.999e+04 4.50000e+01 2.22222e+00 4.94813e+00 2.50000e+01 1.00000e+00
7.004e+04 4.40000e+01 2.27273e+00 4.99711e+00 2.50000e+01 1.00000e+00
7.009e+04 4.30000e+01 2.32558e+00 5.04732e+00 2.50000e+01 1.00000e+00
MAX 25 MIN 1 AVG 2.325581 STD 5.047315 AGG_NUM 43 AGGREGATES { 0 } { 6 } { 7 } ...
meaning, the aggregates are found in the forth line of the input file; so, I read and ignore the first 3 lines.

Take the following code and put it in a file named, say, nagg.f90
Code:
program nagg
  character(1000) line
  integer i, j, k, first, last

  read(*,*) line
  read(*,*) line
  read(*,*) line
  read(*,'(A1000)') line 
  first = index(line, "{")
  last  = index(line, "}", .true.)
  write(*,*) "Aggregates:"
  i = first - 1
  do
    j = (i-1) + ( index(line(i:1000), "{") + 1 )
    k = (i-1) + ( index(line(i:1000), "}") - 1 )
    if (index(trim(adjustl(line(j:k)))," ") == 0) write(*,*) line(j:k)
    if (k+1 == last) exit
    i = k + 2
  end do 
end program nagg
Compile like this:
Code:
gfortran -o nagg nagg.f90
Run like this:
Code:
nagg < Aggregation.dat
It should output the following:
Code:
Aggregates:
  0
  6
  7
  8
  9
  14
  21
  30
  33
  34
  36
  37
  41
  43
  46
  49
  50
  51
  56
  59
  61
  66
  69
  73
  77
  78
  79
  81
  84
  85
  86
  87
  88
  89
  90
  96
  97
  99
I am very grateful for the help. But in fact my input file is much higher, I just put the final. Instead of ignoring just three lines, we would have to ignore 1002 lines in this case. And if this number of lines change occasionally because they depend on the number of steps from my simulation?

Up to this point the script worked just fine, thank you.
 
Last edited:
  • #10
Karlisson said:
I am very grateful for the help. But in fact my input file is much higher, I just put the final. Instead of ignoring just three lines, we would have to ignore 1002 lines in this case. And if this number of lines change occasionally because they depend on the number of steps from my simulation?
There are a couple of simple changes that you can make to the code posted by @gsal:
1. If the number of lines to ignore changes often, take input from the user on how many lines to skip over and run a counting loop (DO ... NEXT) to do just that.
2. If the number of lines to ignore changes infrequently, define a parameter that specifies the number of lines to skip over, again using a counting loop. The disadvantage of this approach is that if the parameter needs to be changed, you need to recompile the code, but if that doesn't happen often, that's not too big a price to pay.
 
  • #11
If you are interested in the first line with brackets, look for brackets and ignore the lines until you find one with brackets. Or look for "AGGREGATES" if that is always in front of the aggregates.
 
  • #12
mfb said:
If you are interested in the first line with brackets, look for brackets and ignore the lines until you find one with brackets. Or look for "AGGREGATES" if that is always in front of the aggregates.
good idea.
 
  • #13
Mark44 said:
There are a couple of simple changes that you can make to the code posted by @gsal:
1. If the number of lines to ignore changes often, take input from the user on how many lines to skip over and run a counting loop (DO ... NEXT) to do just that.
2. If the number of lines to ignore changes infrequently, define a parameter that specifies the number of lines to skip over, again using a counting loop. The disadvantage of this approach is that if the parameter needs to be changed, you need to recompile the code, but if that doesn't happen often, that's not too big a price to pay.
OK thanks.