Search code examples
debuggingfortranscopesubroutine

Does Fortran modify input arguments through subroutine multiple calls?


I have a subroutine called several times in an if-then-goto loop.The subroutine has two input arguments:

1.is a constant

2.is an array of definite size(i.e 200X1) whose elements change in a do loop right before the subroutine is called.

The problem is that subroutine doesn't understand that change and returns the same results every time it is called (i.e the results of the first time that it is called).It seems as if the values of all variables that are calculated inside the sudroutine are somehow saved and do not change although input atgument no.2 changes.. Is something wrong with my code?Is there a Fortran bug i'm not aware of? My code looks like this:

      PROGRAM calcul.f


      REAL aa(100000),dd(100000),mm(100000),yy(100000),hh(100000),mn(100000),ss(100000),ml(100000),m0(100000)
      INTEGER N,snv
      DOUBLE PRECISION m0(100000),excerpt(1000),k1(100000),sqsum,s2,vk1,mk1,sdk1,v

      filelength=610
      W=200

      OPEN (1,file='filename.dat')
      DO i=1,filelength
      READ (1,*) aa(i),dd(i),mm(i),yy(i),hh(i),mn(i),ss(i),ml(i),m0(i)
      END D0
      CLOSE (1)

   10 FORMAT(g12.6)
   11 FORMAT(I5,1x,g12.6)
       c1=1
       c2=W
       snv=0

   14   IF ((c2.LT.filelength).AND.(c1.LT.(filelength-(W-1)))) THEN

        DO i=c1,c2
        excerpt(i)=m0(i)
        END DO

        CALL calk1(W,excerpt)

        OPEN (3,file='meank1.dat')
        READ (3,*) N,mk1
        OPEN (2,file='resultsk1.dat')
        DO i=1,N
        READ (2,*) k1(i)
        END DO

        sqsum=0.0d0
        DO i=1,N
        sqsum=dble(sqsum+((k1(i)-mk1)**2))
        s2=sqsum
        END DO
        vk1=(s2)/N
        sdk1=dsqrt(vk1) 

        OPEN (4,file='resultsv.dat')
        v=dble(sdk1/mk1)
        snv=snv+1
        WRITE (4,11) snv,v
        CLOSE (2)
        CLOSE (3)       
        mk1=0.0d0
        vk1=0.0d0
        sdk1=0.0d0
        v=0.0d0
        c1=c1+1
        c2=c2+1
        GOTO 14
        END IF
        CLOSE (4)
        END 

My subroutine is:

      SUBROUTINE calk1(winlength,sm)

      DOUBLE PRECISION sm(100000),sumk1,sum,s,x,x2,k1,sk1,mk1
      INTEGER snk1  

      OPEN (2,file='resultsk1.dat')
 10   FORMAT (g12.6)
      start=1
      w=winlength
      c3=6
      snk1=0
      sumk1=0.0d0
      sk1=0.0d0

  13  IF (c3.LE.w) THEN
      l1=1
      l2=c3  
      c=c3
  12  IF ((l1.LE.(w-5)).AND.(l2.LE.w)) THEN 
      sum=0.0d0
      s=0.0d0

      DO k=l1,l2
      sum=sum+sm(k)
      s=sum
      END DO

      av=0.0d0
      av2=0.0d0
      x=0.0d0
      x2=0.0d0
      DO k=l1,l2
      av=av+dble(((k)/(c))*(sm(k)/s))
      av2=av2+dble((((k)/(c))**2)*(sm(k)/s))
      x=av
      x2=av2
      END DO

      k1=x2-((x)**2)
      sumk1=sumk1+k1
      snk1=snk1+1
      WRITE (2,10) k1
      l1=l1+1
      l2=l2+1
      k1=0.0d0
      GOTO 12
      ELSE 
      c3=c3+1
      GOTO 13
      END IF
      END IF
      CLOSE (2)

      N=snk1
      sk1=sumk1
      mk1=dble((sk1)/N)  
      OPEN (3,file='meank1.dat')
      WRITE (3,10) N,mk1
      CLOSE (3)
      RETURN
      END

Solution

  • I haven't attempted to compile the code (I see there are still some errors that would upset a compiler), but I can suggest a problem.

    However, the first thing to say is: if this is your code you'll make things much easier for yourself if you use much more modern Fortran features.

    You say that excerpt changes each time before the subroutine is entered. This is true, but not in a meaningful way. Let's look at what is happening to the array.

    This is all looped:

           c1=1
           c2=W
    
           DO i=c1,c2
             excerpt(i)=m0(i)
           END DO
    
           CALL calk1(W,excerpt)
    
           c1=c1+1
           c2=c2+1
    

    Well, W isn't changed in an interation. In this first iteration you are (using array syntax) setting excerpt(1:W)=m0(1:W); in the second setting excerpt(2:W+1)=m0(2:W+1), and so on. That is: each time you call calk1, excerpt(1:W) is still exactly m0(1:W) which hasn't changed. The only change to excerpt is after the W-th element, which you suggest won't be used in the subroutine anyway.

    As to what you should do instead with that excerpt setting loop, I can't say: it depends on what you want to happen. Perhaps

           DO i=c1,c2
             excerpt(i-c1+1) = m0(i)
           END DO
    

    ?

    But use modern Fortran instead.