Nested iterators produce only zeros as data (gfortran)

In summary: I'll check the code again...In summary, the conversation discusses the difficulties the speaker is having with plotting a bifurcation diagram for the logistic map. They are trying to calculate 1128 iterations of a given equation and write the last 128 points of data in a file, but are encountering issues with the value of y staying at zero. They have tried simplifying the code and changing the counter variable from a real to an integer, but are still unable to get the desired results.
  • #1
agsiar
2
0
Hello. I'm supposed to plot a bifurcation diagram for the logistic map. What I'm trying to do is calculate 1128 iteration of y=a*y*(1-y), scrap the first 1000 and write the last 128 points of data in the LogisticMapDiagram.dat file and then plot that with gnuplot, but the value of y stays in zeroes all the time.
The code:

program BifurcationDiagram
implicit none
real y, a
integer i
open (unit=2, file="LogisticMapDiagram.dat")
write (2,*) "# a"," y"
y=0.4
a=0.0
print *, "beginning do"
do i=1,1128,1
do a=0.,4.,0.01
y=a*y*(1-y)
if (i .ge. 1001) then
write (2,*) a, y
end if
end do
end do
print *, "i'm done"
end program​

I've noticed that running a simplified version of the above program yields part of the results that I'm looking for:
program Test
real y, a
y = 0.4
a=3.7
open (unit=2, file="Test.dat")
do i=1,1128,1
y=a*y*(1-y)
if (i .ge. 1001) then
write (2,*) a, y
end if
end do
print*, "i'm done"
end program​
I've also noticed that if I don't specify a value of a and change do i=1,1128,1 for do a=0.,4.,0.01 in the immediately above code, I go back to getting nothing but zeroes for y. Thing is, I really do need to sweep the value of a, preferably in steps of 0.001 instead of steps of 0.01.

I've been told that fortran doesn't like using real numbers in its do statement, but I did another test tabulating sin(x) using x as the counter for the iterator and it worked. The test in question:
program TabulatingSine
real x
open (unit=2, file="SenoTabulado.dat")
write (2,10) "#x","seno(x)"
10 format (a,4x,a)
do x=0.,6.28318530718,0.001
write (2,20) x, sin(x)
20 format (f10.5,4x,f10.5)
end do
print *, "the program did something"
print *, "bye."
end program​

I've thought of not using a as the counter, but I can't come up with any way to make it work and I honestly don't know what to do here anymore...

P.S: The indentation got kinda screwed after CP-ing the code...

EDIT:
Nope, changing the counter from a real number to an integer and make the value of a vary within that do makes no difference... Code:

program DiagramaBifurcacion
implicit none
real y, a
integer i, j
!double precision y, a
open (unit=2, file="MapaLogisticoDiagrama.dat")
write (2,*) "# a"," y"
y=0.4
a=-0.01
print *, "beginning do"
do j=0,400,1
a=a+0.01
do i=1,1128,1
y=a*y*(1-y)
if (i .ge. 1001) then
write (2,*) i, a, y
end if
end do
end do
print *, "i'm done"
end program​
Now I'm truly at a complete loss of what to do...
 
Last edited:
Technology news on Phys.org
  • #2
First, please use code and /code tags enclosed in square brackets '[' and ']' surrounding source code...makes it easier for everybody to read.

It is best to only use integer number in loop variables. You have the right idea in your last example:

Code:
do j=0,400
  a=a+0.01
end do

or, simply

Code:
do j=0,400
  a=j/100.0
end do

may be more accurate in certain instances, because adding small numbers to large ones sometimes gets lost...you are o.k., now, though.

Noticed in the second example above that in the division I do use a real "100.0" and not an integer "100" The thing is that if I had used an integer then it becomes integral division which always yields zero when the numerator is smaller than the denominator.

Anyway...one thing you need to observe is that if you start with a=0.0 and evaluate "y = a*y*(1-y)", then, no matter what the initial value of y is, it will end up zero right away; then, because y is a multiplier on the right-hand-side, it will continue to be zero no matter what the value of 'a' is...

So, in your very first piece of code, the very first value for 'a' in the inner loop is zero...that's it, you are done...now, you will never be able to get out of there...y will be zero forever! Follow? So, your program is doing exactly what you have programmed...that's a problem with most computers, they do exactly what you tell them to do.

So, first fix is: do not use a=0...you know what the result is...zero.

Second, I don't know why, but I would switch the order of the loops...
Code:
do j=1,400
    a = j/100.0
    do i = 1,1128
        y = a*y*(1-y)
    end do
end do
That way, your consecutive 1128 iterations kind of make more sense as the seed (a) was set at the beginning of this set of iterations and that's it; then, re-seeding for the next set and so on.
 
  • #3
Thanks, I didn't know of the code wrapping.
I've tried what you mentioned and sadly it doesn't help. Even before the change, the problem wasn't that a always had the same value (zero), it was that y changed from it's initial value (0.4) to zero and stayed there. Here's the modified code, which is pretty much the same:
Code:
    program DiagramaBifurcacion
        implicit none
        real y, a
        integer i, j
        !double precision y, a
        print *, "abro archivo ''MapaLogisticoDiagrama.dat'' en unidad 2"
        open (unit=2, file="MapaLogisticoDiagrama.dat")
        print *, "escribo ''# a'' y ''    y'' en archivo"
        write (2,*) "# a","    y"
        y=0.4
        print *, y
        print *, "empiezo el do"
        do j=1,400
            a = j/100.0
            do i = 1,1128
                y = a*y*(1-y)
                if (i .ge. 1001) then
                    write (2,*) a, y
                end if
            end do
        end do
        print *, "ya terminé"
    end program
This is a chunk of the data it produces:
3.4900000 0.0000000
3.4900000 0.0000000
3.4900000 0.0000000
3.4900000 0.0000000
3.4900000 0.0000000
3.4900000 0.0000000
3.4900000 0.0000000
3.4900000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000
3.5000000 0.0000000

As you see, the value of a does change, but y stays the same throughout the whole execution.

This is a chunk of data produced by the code previously shown with a constant value of a:
3.5000000 0.82694072
3.5000000 0.50088418
3.5000000 0.87499726
3.5000000 0.38281968
3.5000000 0.82694072
3.5000000 0.50088418
3.5000000 0.87499726
3.5000000 0.38281968
3.5000000 0.82694072
3.5000000 0.50088418
3.5000000 0.87499726
3.5000000 0.38281968
3.5000000 0.82694072
3.5000000 0.50088418
3.5000000 0.87499726
3.5000000 0.38281968
3.5000000 0.82694072
3.5000000 0.50088418
3.5000000 0.87499726
3.5000000 0.38281968
3.5000000 0.82694072
3.5000000 0.50088418
3.5000000 0.87499726
3.5000000 0.38281968

As you see a doesn't change, but it produces data that can be plotted with gnuplot. Making a program and manually change the value of a to make different files doesn't sound like the best idea, that's why I'd rather make all data fall into one file without me having to change from 1.01 to 1.02 all the way to 4. But I don't know how to make gfortran do that or gfortran is being derp...

Edit:
Tried silverfrost's ftn95 and had the same issue. So I guess it has something to do with the program and not the compiler.

Edit2:
It's fixed! and now when plotted gives me the bifurcation diagram I wanted! A friend online helped me see the error that I was oblivious of for almost a whole day! Here's the final code:
Code:
    program DiagramaBifurcacion
        implicit none
        real y, a
        integer i, j
        !double precision y, a
        print *, "abro archivo ''MapaLogisticoDiagrama.dat'' en unidad 2"
        open (unit=2, file="MapaLogisticoDiagrama.dat")
        print *, "escribo ''# a'' y ''    y'' en archivo"
        write (2,*) "# a","    y"
        print *, y
        print *, "empiezo el do"
        do j=1,400
            y=0.4
            a = j/100.0
            do i = 1,1128
                y = a*y*(1-y)
                if (i .ge. 1001) then
                    write (2,20) a, y
20                  format (f10.5,4x,f15.9)
                end if
            end do
        end do
        print *, "ya terminé"
    end program
The change was to move the y=0.4 inside the first loop, and then it worked! :)
yeah I know, I'm a noob.
 
Last edited:

Related to Nested iterators produce only zeros as data (gfortran)

1. Why am I getting only zeros when using nested iterators in gfortran?

This could be due to a few reasons. One possibility is that your nested iterators are not properly initialized and/or incremented, causing the loop to always start at zero and never progress. Another possibility is that your loop conditions are not correctly defined, causing the loop to terminate before any non-zero values are produced.

2. How can I debug my code to find the issue with nested iterators producing only zeros?

One way to debug your code is to print out the values of your iterators at each step of the loop. This can help you identify any issues with initialization or incrementing. Additionally, you can use a debugger tool to step through your code and see where it may be going wrong.

3. Can the issue with nested iterators producing only zeros be related to my input data?

Yes, it is possible that your input data is causing the issue. If your nested iterators are using values from an external source, make sure the data is in the correct format and that it contains non-zero values. If you are generating your own data within the loop, double check your calculations to ensure they are producing non-zero results.

4. Are there any specific compiler or language settings that could cause nested iterators to produce only zeros?

It is possible that certain compiler or language settings could affect the behavior of nested iterators. For example, if your compiler has strict error checking enabled, it may flag any issues with your iterator initialization or loop conditions. Additionally, certain optimization settings may alter the behavior of your code and result in only zeros being produced.

5. Are there any best practices for using nested iterators in gfortran to avoid issues with zero data?

Some best practices for using nested iterators in gfortran include properly initializing and incrementing your iterators, double checking your loop conditions, and carefully reviewing your code for any potential errors. It may also be helpful to use a debugger or print statements to track the values of your iterators and identify any potential issues. Additionally, it can be beneficial to break down your code into smaller, testable parts to help identify and fix any problems with nested iterators.

Similar threads

  • Programming and Computer Science
Replies
20
Views
2K
  • Programming and Computer Science
Replies
4
Views
962
  • Programming and Computer Science
Replies
1
Views
1K
  • Programming and Computer Science
Replies
1
Views
1K
  • Programming and Computer Science
Replies
5
Views
1K
  • Programming and Computer Science
Replies
8
Views
1K
Replies
2
Views
816
  • Programming and Computer Science
Replies
13
Views
2K
  • Programming and Computer Science
Replies
5
Views
4K
  • Programming and Computer Science
Replies
4
Views
767
Back
Top