Re: while loop

From: Catherine Rees Lay (spamtrap_at_polyhedron.org.uk)
Date: 03/02/04


Date: Tue, 2 Mar 2004 13:09:54 +0000

In article <MPG.1aad33b81fc00d65989682@news.queensu.ca>, joto <a@a.com>
writes
>Hi, I have a question:
>
>
>In the program below the while loop, DO 50 WHILE (ERROR>1.000000E-01),
>after the 26 CONTINUE line is not working properly. When i run the
>program i get a floating point co-processor fault. If I remove the while
>loop with a DO 50 K=1,5000 the program runs fine and I get an error of
>less than 0.1, so I don't see why the while loop is causing this error
>since after about 5000 iterations the while conditions are no longer met.
>
>
>
>I've also tried to get rid of the while loop, and instead put the
>following in after ERROR=MAXCHANGE/FLOAT(MAXV): which is the line after
>40 CONTINUE
>
>IF(ERROR.GT.0.01) THEN
>GO TO 27
>ENDIF
>
>This should be equivelent to the while loop, however it doesn't appear to
>be. All that happens in this case, is that the program never stops
>running -- it seems like it enters an infinte loop.
>
>The program is below, and I don't know what's going on -- I want this
>while loop to work, I've tried entering the error limit as 0.1 and
>1.000000E-01 and ERLIMIT=FLOAT(0.1), and none of this worked. I'm using
>Fortran 95 by Salford.
>
>Any suggestions would be appreciated,
>
>Thanks.
>
I get the same error as you, but if I run it through FTN95 with /UNDEF,
it complains that ERROR is undefined. Did you mean ERR? /UNDEF is a
wonderful tool and I recommend it as your default option when
developing.

Some general suggestions on style: try IMPLICIT NONE and declare your
variables explicitly (this would have caught your problem even without
/UNDEF). Add some indentation for the loops. Label 40 is referenced so
many times it's hard to figure out when it's in the loop and when it
isn't. And while the rest of your code looks like F77, if you're going
to use DO WHILE, how about ENDDO so at least you can see which of your
CONTINUEs are ends of loop and which are GOTOed. And how about a few
comments? Sorry if this sounds a bit harsh, but you really will save
time debugging in the long run if you make your code easier to read.

HTH,

Catherine.
>
> DIMENSION V(-1:1000,-1:1000),VNEW(-1:1000,-1:1000),VOLD(-1:1000,-
>1:1000), SV(2),Q(2)
> DATA A,B,D,W/3.0,1.5,0.2,0.05/
> DATA ER,E0,U/2.25,8.81E-12,3.0E+8/
> H=0.005
> NT=5000
> NX=NINT(B/H)
> NY=NINT(A/H)
> ND=NINT(D/H)
> NW=NINT(W/H)
> VD=10.0
> ERR=1.0
> DO 90 L=1,2
> E1=E0
> E2=E0*ERR
> DO 10 I=0,NX
> DO 10 J=0,NY
> V(I,J)=0.0
> 10 CONTINUE
> DO 20 I=0,NW
> V(I,ND)=VD
> VNEW(I,J)=0
> 20 CONTINUE
> DO 25 I=0,NX
> V(I,0)=0
> V(I,NY)=0
> 25 CONTINUE
> DO 26 J=0,NY
> V(NX,J)=0
> 26 CONTINUE
>
>
> P1=E1/(2.0*(E1+E2))
> P2=E2/(2.0*(E1+E2))
> MAXV=0.0
> MAXCHANGE=0.0
> DO 50 WHILE (ERROR>0.1)
> 27 DO 40 I=0,NX-1
> DO 40 J=0,NY-1
> IF((J.EQ.ND).AND.(I.LE.NW)) GO TO 40
> IF(J.EQ.ND) THEN
> V(I,J)=0.25*(V(I+1,J)+V(I-1,J))+P1*V(I,J+1)+P2*V(I,J-1)
> GO TO 40
> ENDIF
> IF(I.EQ.0) THEN
> V(I,J)=(2.0*V(I+1,J)+V(I,J+1)+V(I,J-1))/4.0
> GO TO 40
> ENDIF
> 30 V(I,J)=(V(I+1,J)+V(I-1,J)+V(I,J+1)+V(I,J-1))/4.0
>
> VOLD(I,J)=VNEW(I,J)
> VNEW(I,J)=V(I,J)
> MAXCHANGEO=MAXCHANGE
> MAXVO=MAXV
> CHANGE=VNEW(I,J)-VOLD(I,J)
> V(I,J)=VOLD(I,J)+1.5*CHANGE
> ABSCHANGE=ABS(CHANGE)
> IF(ABSCHANGE.GT.MAXCHANGE) THEN
> MAXCHANGE=ABSCHANGE
> ENDIF
> ABSV=ABS(V(I,J))
> IF(ABSV.GT.MAXV) THEN
> MAXV=ABSV
> ENDIF
> IF((J.EQ.ND).AND.(I.LE.NW)) THEN
> MAXCHANGE=MAXCHANGEO
> MAXV=MAXVO
> ENDIF
> 40 CONTINUE
> ERROR=MAXCHANGE/FLOAT(MAXV)
> 50 CONTINUE
>
> IOUT=(NX+NW)/2
> JOUT=(NY+ND)/2
> JOUT2=ND/2
> DO 80 K=1,2
> SUM=0.0
> DO 60 I=1,IOUT-1
> SUM=SUM+E1*V(I,JOUT)+E2*V(I,JOUT2)
> 60 CONTINUE
> SUM=SUM+E1*V(0,JOUT)/2.0
> DO 70 J=JOUT2,JOUT-1
> IF(J.LT.ND) SUM=SUM+E2*V(IOUT,J)
> IF(J.EQ.ND) SUM=SUM+(E1+E2)*V(IOUT,J)/2.0
> IF(J.GT.ND) SUM=SUM+E1*V(IOUT,J)
> 70 CONTINUE
> IF(K.EQ.1) SV(1)=SUM
> IOUT=IOUT-1
> JOUT=JOUT-1
> JOUT2=JOUT2-1
> 80 CONTINUE
> SUM=SUM+2.0*E1*V(IOUT,JOUT)+2.0*E2*V(IOUT,JOUT2)
> SV(2)=SUM
> Q(L)=ABS(SV(1)-SV(2))
> ERR=ER
> 90 CONTINUE
> C0=2.0*Q(1)/VD
> C1=2.0*Q(2)/VD
> Z0=1.0/(U*SQRT(C0*C1))
> WRITE(6,*) H,NT,Z0,ERROR
> PRINT *,H,NT,Z0,ERROR
> STOP
> END
>

-- 
Catherine Rees Lay
To email me, use my first name in front of the "at".


Relevant Pages

  • [ifort] Opening too much time files cause a segmentation fault
    ... My program consist in a general loop that first perform a kind of bisection and then write the results in multiple files. ... The problem doesn't seems to be in my code but when opening the files. ...
    (comp.lang.fortran)
  • Re: question about thread scheduling
    ... I will try what you suggested, the reason that I didn't use the sleep method ... If the NN run in a different thread as the control loop ... Sleepputs your thread to sleep for 3 timer ticks and ...
    (microsoft.public.windowsce.platbuilder)
  • Re: [ifort] Opening too much time files cause a segmentation fault
    ... My program consist in a general loop that first perform a kind of bisection and then write the results in multiple files. ... The problem doesn't seems to be in my code but when opening the files. ...
    (comp.lang.fortran)
  • Re: ZGAMMA revisited
    ... difficult to compute accurately (quad-precision for double precision ... AUTHOR: Marcel Hendrix ... DUP 0< IF 2DROP F#0.0 EXIT ENDIF ... LOOP ...
    (comp.lang.forth)
  • Re: [PATCH 4/6] futex: Add FUTEX_LOCK with optional adaptive spinning
    ... * Try to acquire a futex lock in a loop until the owner changes or the owner ... To lock the futex, set the value to the current TID. ...
    (Linux-Kernel)