Silverfrost Forums

Welcome to our forums

##[SOLVED]##Simple program not working right

11 Nov 2013 9:23 (Edited: 15 Nov 2013 10:05) #13305

I need to break 0 to 1 into 10, 100, and 1000 sections i.e 0.0 0.1 0.2 0.3 ... in the first part of my code but it is not working as intended, here is the part of code which relates to this:

Program Euler_Huene
    implicit none
    real, dimension(4,0:10) :: yeh1 = 0.0   !4th row is for x amounts
    real, dimension(4,0:100) :: yeh2 = 0.0
    real, dimension(4,0:1000) :: yeh3 = 0.0
    real, dimension(4,0:10) :: yhh1 = 0.0
    real, dimension(4,0:100) :: yhh2 = 0.0
    real, dimension(4,0:1000) :: yhh3 = 0.0   
    real, parameter :: h1 = 0.1, h2 = 0.01, h3 = 0.001
    do i = 0, 999
        if (i < 10) then
            yeh1(4,i+1) = yeh1(4,i) + h1
            yhh1(4,i+1) = yhh1(4,i) + h1
        end if
        if (i < 100) then
            yeh2(4,i+1) = yeh2(4,i) + h2
            yhh2(4,i+1) = yhh2(4,i) + h2
        end if 
        if (i < 1000) then
            yeh3(4,i+1) = yeh3(4,i) + h3
            yhh3(4,i+1) = yhh3(4,i) + h3
        end if
    end do

The part for breaking 0 to 1 to 10 sections work but the others don't. This is what I get from code : yhh3(4,900)=0.899992, yhh2(4,90)=8.99999, yhh1(4,9)=0.9 but all of them should be 0.9 right?

11 Nov 2013 12:45 #13307

First - try using the double precision real numbers as the standard 4 byte reals do not have the resolution. Check out real8 and real10. Ian

11 Nov 2013 2:13 #13308

Quoted from IanLambley First - try using the double precision real numbers as the standard 4 byte reals do not have the resolution. Check out real8 and real10. Ian

thank you, I will try that

12 Nov 2013 6:02 #13310

You could also simplify your do loops and have 3 loops.

Program Euler_Huene 
    implicit none 
    real, dimension(4,0:10)   :: yeh1 = 0.0   ! 4th row is for x amounts 
    real, dimension(4,0:100)  :: yeh2 = 0.0 
    real, dimension(4,0:1000) :: yeh3 = 0.0 
    real, dimension(4,0:10)   :: yhh1 = 0.0 
    real, dimension(4,0:100)  :: yhh2 = 0.0 
    real, dimension(4,0:1000) :: yhh3 = 0.0    
    real*8, parameter :: h1 = 0.1d0, h2 = 0.01d0, h3 = 0.001d0
    integer :: i
!
    do i = 0, 10 
       yeh1(4,i) = h1 * i
       yhh1(4,i) = h1 * i
    end do
    do i = 0, 100 
       yeh2(4,i) = h2 * i
       yhh2(4,i) = h2 * i
    end do
    do i = 0, 1000
       yeh3(4,i) = h3 * i 
       yhh3(4,i) = h3 * i 
    end do

'h1 * i' should be calculated as real8 then stored as real4 'h1 * dble(i)' might look better but should not be any different. This should avoid changing all arrays from real4 to real8, if this is a requirement. If that doesn't work, then use real*8 throughout.

John

13 Nov 2013 6:45 #13312

I agree with John, you need to use Double precision to get the accuracy you desire.

Here is John's code in double precision without any DO loops.

    real*8, dimension(4,0:10)   :: yeh1 = 0.0d0
    real*8, dimension(4,0:100)  :: yeh2 = 0.0d0
    real*8, dimension(4,0:1000) :: yeh3 = 0.0d0
    real*8, dimension(4,0:10)   :: yhh1 = 0.0d0
    real*8, dimension(4,0:100)  :: yhh2 = 0.0d0
    real*8, dimension(4,0:1000) :: yhh3 = 0.0d0
    real*8, parameter :: h1 = 0.1d0, h2 = 0.01d0, h3 = 0.001d0
    integer :: i

    forall(i=0:10) yeh1(4,i) = h1 * i
    forall(i=0:10) yhh1(4,i) = h1 * i

    forall(i=0:100) yeh2(4,i) = h2 * i
    forall(i=0:100) yhh2(4,i) = h2 * i

    forall(i=0:1000) yeh3(4,i) = h3 * i
    forall(i=0:1000) yhh3(4,i) = h3 * i

It is completely redundant that the arrays are initialized to zero, but it does no harm.

13 Nov 2013 11:47 #13313

David,

'It is completely redundant that the arrays are initialized to zero, but it does no harm.'

That's not the case for yeh1(1:3,:) etc ?

Also, it can do 'harm', for larger arrays, as the .exe file is then much larger. I prefer to use yeh1 = 0, as an executable statement.

FORALL has always annoyed me, as it implies some efficiency but never delivers on all compilers I have tested !

John

15 Nov 2013 10:01 #13317

Hi, thank you all, my problem is solved by implementing your suggestions in my code. However I don't know what is forall command I guess I will learn it in the near future as I progress in learning FORTRAN language and programing. I also do'nt know what difference it makes if you initiate a variable in type declaration or do it in the executable commands can someone explain it for me? Actually I initialized arrays in a desperate attempt to fix my precision problem although I knew it has nothing to do with it 😄

15 Nov 2013 6:52 #13320

Quoted from shahrooz I also do'nt know what difference it makes if you initiate a variable in type declaration or do it in the executable commands can someone explain it for me?

If you write the following you are initializing the variable when the subroutine is [u:cfdf1bb6cd]first[/u:cfdf1bb6cd] called. In practice the initialization is done when the code is compiled or when the executable is loaded into memory. In this case the variable also has the SAVE attribute so that the variable may be accessed on the second and subsequent calls. You can also write real, save :: a = 1 but the save attribute isn't needed.

If you call the subroutine more than once it prints the sequence:

1.0 2.0 2.0 etc

subroutine xxx()
real :: a = 1.0
print *, a
a = 2.0 
end

If you write the following a is set to 1 [u:cfdf1bb6cd]each time[/u:cfdf1bb6cd] the subroutine is called

If you call the subroutine more than once it prints the sequence:

1.0 1.0 1.0 etc

subroutine xxx()
real :: a
a = 1.0
print *, a
a = 2.0 
end
18 Nov 2013 8:40 #13334

thanks

Please login to reply.