 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
shahrooz
Joined: 23 Oct 2013 Posts: 10 Location: Iran
|
Posted: Mon Nov 11, 2013 10:23 am Post subject: ##[SOLVED]##Simple program not working right |
|
|
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:
Code: |
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?
Last edited by shahrooz on Fri Nov 15, 2013 11:05 am; edited 2 times in total |
|
Back to top |
|
 |
IanLambley
Joined: 17 Dec 2006 Posts: 506 Location: Sunderland
|
Posted: Mon Nov 11, 2013 1:45 pm Post subject: |
|
|
First - try using the double precision real numbers as the standard 4 byte reals do not have the resolution. Check out real*8 and real*10.
Ian |
|
Back to top |
|
 |
shahrooz
Joined: 23 Oct 2013 Posts: 10 Location: Iran
|
Posted: Mon Nov 11, 2013 3:13 pm Post subject: Re: |
|
|
IanLambley wrote: | First - try using the double precision real numbers as the standard 4 byte reals do not have the resolution. Check out real*8 and real*10.
Ian |
thank you, I will try that |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Tue Nov 12, 2013 7:02 am Post subject: |
|
|
You could also simplify your do loops and have 3 loops.
Code: | 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 real*8 then stored as real*4
"h1 * dble(i)" might look better but should not be any different.
This should avoid changing all arrays from real*4 to real*8, if this is a requirement.
If that doesn't work, then use real*8 throughout.
John |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Wed Nov 13, 2013 7:45 pm Post subject: |
|
|
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.
Code: |
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. _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Thu Nov 14, 2013 12:47 am Post subject: |
|
|
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 |
|
Back to top |
|
 |
shahrooz
Joined: 23 Oct 2013 Posts: 10 Location: Iran
|
Posted: Fri Nov 15, 2013 11:01 am Post subject: |
|
|
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  |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Fri Nov 15, 2013 7:52 pm Post subject: Re: |
|
|
shahrooz wrote: | 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 first 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
Code: |
subroutine xxx()
real :: a = 1.0
print *, a
a = 2.0
end
|
If you write the following a is set to 1 each time the subroutine is called
If you call the subroutine more than once it prints the sequence:
1.0
1.0
1.0
etc
Code: |
subroutine xxx()
real :: a
a = 1.0
print *, a
a = 2.0
end
|
_________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
shahrooz
Joined: 23 Oct 2013 Posts: 10 Location: Iran
|
Posted: Mon Nov 18, 2013 9:40 pm Post subject: |
|
|
thanks |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|