Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Do Loops -- Real Step Size 1

Status
Not open for further replies.

cubsfan334

Programmer
Oct 3, 2009
4
US
Hi, I'm new to Fortran and I'm running into trouble with do loops. I keep getting the error that the step size can only be an integer. I'd like to use a step size of .01 or .001. Why is this, and is there a way around it?

Thanks,
cubsfan
 
Like in other languages the DO-loop control variable should be integer.
But you can program a loop with any arbitrary step.
 
Hi cubsfan334,

I'm not sure if I was clear in my previous answer.
There are several ways how to do it. The example below shows you three of them:
Code:
[COLOR=#a020f0]program[/color] loop_step
  [COLOR=#0000ff]! Using real step size in loops[/color]
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

[COLOR=#2e8b57][b]  real[/b][/color] :: x, x_min, x_max, step
  [COLOR=#2e8b57][b]integer[/b][/color] :: i, n

  x_min [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0[/color]
  x_max [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]1[/color]
  step [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0.1[/color]
  [COLOR=#6a5acd]10[/color] [COLOR=#804040][b]format[/b][/color](i2 a6 [COLOR=#008080]f3.1[/color])

  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Using DO loop with control variable:'[/color]
  x [COLOR=#804040][b]=[/b][/color] x_min
  n [COLOR=#804040][b]=[/b][/color] [COLOR=#008080]nint[/color]((x_max [COLOR=#804040][b]-[/b][/color] x)[COLOR=#804040][b]/[/b][/color]step)
  [COLOR=#804040][b]do[/b][/color] i[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color], n[COLOR=#804040][b]+[/b][/color][COLOR=#ff00ff]1[/color]
    [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#ff00ff]10[/color]) i, [COLOR=#ff00ff]". x = "[/color], x
    x [COLOR=#804040][b]=[/b][/color] i[COLOR=#804040][b]*[/b][/color]step
  [COLOR=#804040][b]end do[/b][/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color])

  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Using DO loop with exit on condition:'[/color]
  x [COLOR=#804040][b]=[/b][/color] x_min
  i [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]1[/color]
  [COLOR=#804040][b]do[/b][/color]
    [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#ff00ff]10[/color]) i, [COLOR=#ff00ff]". x = "[/color], x
    x [COLOR=#804040][b]=[/b][/color] x [COLOR=#804040][b]+[/b][/color] step
    i [COLOR=#804040][b]=[/b][/color] i [COLOR=#804040][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
    [COLOR=#804040][b]if[/b][/color] (x [COLOR=#804040][b]>[/b][/color] (x_max [COLOR=#804040][b]+[/b][/color] step)) [COLOR=#804040][b]then[/b][/color]
      [COLOR=#804040][b]exit[/b][/color]
    [COLOR=#804040][b]end if[/b][/color]
  [COLOR=#804040][b]end do[/b][/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color])

  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Using DO WHILE loop with condition:'[/color]
  x [COLOR=#804040][b]=[/b][/color] x_min
  i [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]1[/color]
  [COLOR=#804040][b]do[/b][/color] [COLOR=#804040][b]while[/b][/color] (x [COLOR=#804040][b]<[/b][/color] (x_max [COLOR=#804040][b]+[/b][/color] step))
    [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#ff00ff]10[/color]) i, [COLOR=#ff00ff]". x = "[/color], x
    x [COLOR=#804040][b]=[/b][/color] x [COLOR=#804040][b]+[/b][/color] step
    i [COLOR=#804040][b]=[/b][/color] i [COLOR=#804040][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
  [COLOR=#804040][b]end do[/b][/color]
[COLOR=#a020f0]end program[/color] loop_step
Output:
Code:
$ g95 loop_step.f95 -o loop_step

$ loop_step
 Using DO loop with control variable:
 1. x = 0.0
 2. x = 0.1
 3. x = 0.2
 4. x = 0.3
 5. x = 0.4
 6. x = 0.5
 7. x = 0.6
 8. x = 0.7
 9. x = 0.8
10. x = 0.9
11. x = 1.0

 Using DO loop with exit on condition:
 1. x = 0.0
 2. x = 0.1
 3. x = 0.2
 4. x = 0.3
 5. x = 0.4
 6. x = 0.5
 7. x = 0.6
 8. x = 0.7
 9. x = 0.8
10. x = 0.9
11. x = 1.0

 Using DO WHILE loop with condition:
 1. x = 0.0
 2. x = 0.1
 3. x = 0.2
 4. x = 0.3
 5. x = 0.4
 6. x = 0.5
 7. x = 0.6
 8. x = 0.7
 9. x = 0.8
10. x = 0.9
11. x = 1.0
 
The problem with having a real loop counter is termination. The rounding errors can cause loop termination prematurely or do one extra iteration.
 
Thanks for the responses guys, I had another question also -- I set a parameter for g, the gravatational constant = 6.673E-11. When I execute my program, however, I believe that the program rounds this to 0. Also, the output numbers are also rounded to whole numbers -- I need decimal places. Anyway to fix this?

Thanks,
cubsfan
 
1) Use real(8) or double precision.
2) Change your format to something like E11.3, D11.3 or G11.3

E will print it as 6.673E-11
D will print it as 6.673D-11 (indicating it is a DP number)
G will print it in F format if it fits otherwise it will print in E format. Great for numbers where you're not sure of the range.
 
gullipe, you are genius ! What you revealed is worth the star !
I lived in the darkness: What you say is true, but not only for intel Fortran. The old g77 supports this feature too !
:)

Look - I created 2 sources real_step.for and real_step.f95 with this identical content:
Code:
[COLOR=#0000ff]! gullipe (Programmer):[/color]
[COLOR=#0000ff]! The Intel Fortran Manual [/color]
[COLOR=#0000ff]! (<a href="[URL unfurl="true"]http://docs.nscl.msu.edu/ifc/intelfor_prglangref.pdf)">http://docs.nscl.msu.edu/ifc/intelfor_prglangref.pdf)</a>[/URL] [/color]
[COLOR=#0000ff]! states (on page 10-53), that the variables in the DO-loop can be real [/color]
[COLOR=#0000ff]! as well as integer. [/color]
[COLOR=#0000ff]! Therefore one can write:[/color]
[COLOR=#a020f0]program[/color] real_step
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
[COLOR=#2e8b57][b]  real[/b][/color] :: x, x_min, x_max, step
  x_min [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0[/color]
  x_max [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]1[/color]
  step [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0.1[/color]

  [COLOR=#804040][b]do[/b][/color] x [COLOR=#804040][b]=[/b][/color] x_min, x_max, step
    [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#ff00ff]'(a5,f3.1)'[/color]) [COLOR=#ff00ff]" x = "[/color], x
  [COLOR=#804040][b]end do[/b][/color]
[COLOR=#a020f0]end program[/color] real_step
Now - I can't believe my eyes:
Code:
$ g77 real_step.for -o real_step -ffree-form

$ real_step
 x = 0.0
 x = 0.1
 x = 0.2
 x = 0.3
 x = 0.4
 x = 0.5
 x = 0.6
 x = 0.7
 x = 0.8
 x = 0.9
g77 compiles it and it really runs!

I tried the same with gfortran and g95, but without success
Code:
$ gfortran real_step.f95 -o real_step            
real_step.f95:15.6:

  do x = x_min, x_max, step
     1
Warning: Deleted feature: Loop variable at (1) must be integer
real_step.f95:15.8:

  do x = x_min, x_max, step
       1
Warning: Deleted feature: Start expression in DO loop at (1) must be integer
real_step.f95:15.15:

  do x = x_min, x_max, step
              1
Warning: Deleted feature: End expression in DO loop at (1) must be integer
real_step.f95:15.22:

  do x = x_min, x_max, step
                     1
Warning: Deleted feature: Step expression in DO loop at (1) must be integer

$ g95 real_step.f95 -o real_step
In file real_step.f95:15

  do x = x_min, x_max, step
     1
Error: REAL loop variable at (1) - to enable REAL loop parameters use -freal-loops
How you can see - g95 compiler says, that it has an option -freal-loops for it. I tried it and it really works:
Code:
$ g95 real_step.f95 -o real_step -freal-loops

$ real_step
 x = 0.0
 x = 0.1
 x = 0.2
 x = 0.3
 x = 0.4
 x = 0.5
 x = 0.6
 x = 0.7
 x = 0.8
 x = 0.9
In gfortan the same option doen't work:
Code:
$ gfortran real_step.f95 -o real_step -freal-loops
f951.exe: error: unrecognized command line option "-freal-loops"

But now the question: When it's supported by g77, why it isn't supported by gfortran, which should be the successor of g77? Or is there any other option in gfortran which allows real steps in loops?
 
Hi mikrom

Thanks for the star. I sometimes use this feature in my programming (using the old Microsoft F77 fortran compiler), but then I have to be careful about the loop termination (to loop up to x = 1.0 above, one have to put x_max = 1.05).

This feature may have been not so uncommon in 77 compilers, but the "Intel Fortran Language reference manual" ( states (on page 7-18): "A Do variable or expression of type real is a deleted feature in Fortran 95; it was obsolescent in Fortran 90". And they add: "Intel Fortran fully supports features deleted in Fortran 95"!
 
gullipe said:
I sometimes use this feature in my programming ... but then I have to be careful about the loop termination (to loop up to x = 1.0 above, one have to put x_max = 1.05).
Yes I know I have in my source above
Code:
while (x < (x_max + step))
Interesting that this feature was in f77 but then it was sweeped out from f95. Though I never used it (because of lacks of my knowledge)
:)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top