Re: better method
- From: Paul van Delst <Paul.vanDelst@xxxxxxxx>
- Date: Mon, 16 Jun 2008 10:13:45 -0400
rudra wrote:
go to statement, as we know, is quite infamous and i always feel
'guilty' when i had to use this. say in the given program:
!========================================!
! L-J potentials !
! dependence of U with sigma and r !
!========================================!
implicit none
integer, parameter :: dp = selected_real_kind(2,2)
integer:: i
real(DP):: sig
real(DP):: r,u,minu
real(DP):: del=0.01,sdel=.5
real(DP),dimension(1000):: valu
sig=1.0
20 if(sig<=3.0)then
write(*,*) "increasing sigma"
r=.9
10 if(r<10.0)then
u=4*((sig/r)**12-(sig/r)**6)
write(10,*) sig,r,u
r=r+del
go to 10
endif
write(10,*) ""
sig=sig+sdel
go to 20
endif
close(10)
end
given that sig and r is real, is there any method of avoiding these
go to statement?
How about something like
! Define literal constants to elimate Magic Numbers!
REAL(DP), PARAMETER :: TEN = 10.0_DP
....
rtest_loop: DO
IF ( r >= TEN ) EXIT
u=4.0_DP*((sig/r)**12-(sig/r)**6)
write(10,*) sig,r,u
r=r+del
END DO rtest_loop
?
Same for the "sig" loop. You don't seem to mind testing for <= for sig, hence my use of >= in the rtest_loop.
If even that usage of floating point equality testing bothers you then maybe you could modify the function below (which just does x>y, not x>=y, for floats) to do what you want,
FUNCTION Is_Greater_Than( x, y ) RESULT( Greater_Than )
REAL(DP), INTENT(IN) :: x, y
LOGICAL :: Greater_Than
IF ( (x-y) >= SPACING( MAX( ABS(x), ABS(y) ) ) ) THEN
Greater_Than = .TRUE.
ELSE
Greater_Than = .FALSE.
END IF
END FUNCTION Is_Greater_Than
and then,
rtest_loop: DO
IF ( Is_Greater_Than(r,TEN) ) EXIT
u=4.0_DP*((sig/r)**12-(sig/r)**6)
write(10,*) sig,r,u
r=r+del
END DO rtest_loop
You can also do as I did and make the above function elemental, stick it in a module, and then do something like,
INTERFACE OPERATOR (.GreaterThan.)
MODULE PROCEDURE Is_Greater_Than
END INTERFACE OPERATOR (.GreaterThan.)
so you could use it thusly,
rtest_loop: DO
IF ( r .GreaterThan. TEN) ) EXIT
u=4.0_DP*((sig/r)**12-(sig/r)**6)
write(10,*) sig,r,u
r=r+del
END DO rtest_loop
I find the latter to be easier to read. The functional form always makes me wonder which arg am I testing to be greater than which?
cheers,
paulv
p.s. The "SPACING( MAX( ABS(x), ABS(y) ) )" methodology is taken from James Giles and James Van Biskirk's postings to clf over the years. If you don't go the operator route, you can also scale the comparison via an optional argument if the precision of the input numbers is suspect (i.e. less than "full" double precision due to any previously performed operations).
.
- Follow-Ups:
- Re: better method
- From: Craig Powers
- Re: better method
- From: Michel Olagnon
- Re: better method
- References:
- better method
- From: rudra
- better method
- Prev by Date: Re: Allocatable components + mixed-language
- Next by Date: Re: better method
- Previous by thread: Re: better method
- Next by thread: Re: better method
- Index(es):
Relevant Pages
|
|