user8080533
user8080533

Reputation: 1

Frustrating code gives me strange output, maybe due to WRITE and READ?

This is a longer code that im having trouble with, and i think it is because im not sure i am fully understanding line WRITE(6,*) 'INPUT S,K,TAU,SIGMA,R,DELTA,DTAU' and READ(5,*) S,K,TAU,SIGMA,R,DELTA,DTAU. If I simply run the .f file I get

executable.exe INPUT S,K,TAU,SIGMA,R,DELTA,DTAU

Then I enter the following inputs

100.0d0,100.0d0,3.0d0,0.2d0,0.08d0,0.04d0,0.03d0

After I do this I get a new file in my directory called "fort.2". I don't know where in the code this is said to be produced ? Since if I change

WRITE(2,10) T(I),BD(I) 

to

WRITE(3,10) T(I),BD(I)

I still get the file "fort.2". Anyhow I am suspicious of "fort.2" to be the correct output since, inside it there are two columns (1) the values of T(I) and values of (2) BD(I) . The first column is correct T(I) changing with 0.03d0 steps up to 3.0d0 , this comes from DTAU, TAU . However BD(I) does not change for each 0.03d0 step, it is constant for several 0.03d0 steps and then suddenly changes (like a step function). BD(I) is supposed to change for every 3.0d0 step. Right now i don't know I'm kinda lost. Main code:

      IMPLICIT NONE
      INTEGER MS,NS,JS,N,I
      PARAMETER(MS=50000,NS=50000)
      REAL*8 S,K,TAU,SIGMA,R,DELTA,SMIN,SMAX,DTAU,ALPHA,BETA,LAM
      REAL*8 V(0:MS),BD(0:NS),T(0:NS)
      COMMON/OUTPUT/V,BD,T

      WRITE(6,*) 'INPUT S,K,TAU,SIGMA,R,DELTA,DTAU'
      READ(5,*) S,K,TAU,SIGMA,R,DELTA,DTAU

      N = TAU/DTAU
      ALPHA = 2.0D0*R/SIGMA**2
      BETA = 2.0D0*(R-DELTA)/SIGMA**2
      LAM = (BETA-1.0D0) + DSQRT((BETA-1.0D0)**2+4.0D0*ALPHA)
      LAM = LAM/2.0D0
      SMIN = K/(1.0D0+1.0D0/LAM)               ! PERPETUAL BOUNDARY
      SMAX = 10.0D0*K
      CALL EXP_DIFF(S,K,TAU,SIGMA,R,DELTA,SMAX,SMIN,DTAU,JS)

      WRITE(6,*) 'PRICE: ', V(JS)
      DO I = 0, N
       WRITE(2,10) T(I),BD(I)
      ENDDO
10    FORMAT(1X,2F14.8)

      STOP
      END


C=======================================================================
      SUBROUTINE EXP_DIFF(S,K,TAU,SIGMA,R,DELTA,SMAX,SMIN,DTAU,JS)
      IMPLICIT NONE
      INTEGER MS,NS,JS,M,N,I,J,IEARLY
      PARAMETER(MS=50000,NS=50000)
      REAL*8 S,K,TAU,SIGMA,R,DELTA,XMIN,XMAX,DTAU,DX,ALPHA,SMIN,SMAX,
     &       P1,P2,P3,VC,A,B
      REAL*8 VE(0:MS),V(0:MS),BD(0:NS),T(0:NS)
      COMMON/OUTPUT/V,BD,T

      IF (S.GT.SMAX) THEN
       STOP 'THE OPTION IS WORHTLESS'
      ENDIF

      IF (S.LT.SMIN) THEN
       STOP 'THE OPTION WORTHS K-S FOR CERTAIN'
      ENDIF

      XMIN = DLOG(SMIN)
      XMAX = DLOG(SMAX)
      DX = SIGMA*DSQRT(3.0*DTAU) 
      JS = (DLOG(S)-XMIN)/DX
      DX = (DLOG(S)-XMIN)/FLOAT(JS)
      ALPHA = R - DELTA - SIGMA**2/2.0
      P1 = SIGMA**2*DTAU/(2.0*DX**2) + ALPHA*DTAU/(2.0*DX)
      P2 = 1.0 - SIGMA**2*DTAU/DX**2
      P3 = 1.0 - P1 -P2
      P1 = P1/(1.0+R*DTAU)
      P2 = P2/(1.0+R*DTAU)
      P3 = P3/(1.0+R*DTAU)
      WRITE(6,*) 'P1,P2,P3',P1,P2,P3
      IF (P1.LT.0.0.OR.P2.LT.0.0.OR.P3.LT.0.0) STOP 'DECREASE DTAU'

      M = (XMAX-XMIN)/DX
      N = TAU/DTAU
      IF (M.GT.MS.OR.N.GT.NS) STOP 'INCREASE MS AND NS'
      DO J = 0, M
       VE(J) = MAX(K-DEXP(J*DX+XMIN),0.0)
       V(J) = VE(J)
      ENDDO

      BD(0) = K
      T(0) = 0.0      
      DO I = 1, N
       IEARLY = 0
       A = V(M)
       B = V(M-1)
       DO J = M-1, 1, -1
        VC = P1*A+P2*B+P3*V(J-1)
        IF (VC.LT.VE(J).AND.IEARLY.EQ.0) THEN
         BD(I) = DEXP(XMIN+J*DX)
         T(I) = DTAU*DFLOAT(I)
         IEARLY = 1
        ENDIF
        V(J) = MAX(VC, VE(J))
        A = B
        B = V(J-1)
       ENDDO
      ENDDO

      RETURN
      END

Upvotes: 0

Views: 97

Answers (2)

Jack
Jack

Reputation: 6168

BD(I) is changing step-wise because the calculation of it is in this IF test:

    IF (VC.LT.VE(J).AND.IEARLY.EQ.0) THEN
       BD(I) = DEXP(XMIN+J*DX)
       T(I) = DTAU*DFLOAT(I)
       IEARLY = 1
    ENDIF

From I=1 through I=10, that IF test succeeds when J=3. When I=11, it succeeds when J=2, changing the calculation of BD(I). When I=38, that IF test succeeds at J=1, and the calculation of BD(I) is changed again.

Upvotes: 0

Thomas Kühn
Thomas Kühn

Reputation: 9820

In the program, the line

WRITE(6,*) 'INPUT S,K,TAU,SIGMA,R,DELTA,DTAU' 

is supposed to write out an instruction to the user. After that, the line

READ(5,*) S,K,TAU,SIGMA,R,DELTA,DTAU

waits for a list of comma separated values ending with a RETURN. So I would guess that this is intended behaviour. If you run the program, when you see the output

INPUT S,K,TAU,SIGMA,R,DELTA,DTAU

type in 7, comma-separated, values and the program will calculate the results for you.

If, on the other hand, you alter the original WRITE statement to

WRITE(6,*) S,K,TAU,SIGMA,R,DELTA,DTAU

you will get some random output, because the variables, whose values you are writing out, are at that point uninitialised.

EDIT:

The WRITE format is explained on many web pages in great detail. See for example this one. In your specific case, there is a WRITE line and a FORMAT line, which together specify, how your output looks like:

      WRITE(2,10) T(I),BD(I)
      ...
10    FORMAT(1X,2F14.8)

WRITE(2,10) T(I),BD(I) writes the variables to file stream 2(which you opened most likely with a command like this somewhere open (unit = 2, file = "fort.2")), with the format specified at line 10 (which is just two lines below the write statement). How the format specifiers work is explained in the link I provided.

EDIT 2:

As pointed out in the comments, fort.2 is a standard name used by some fortran compilers if writing to stream nr. 2 without first using an OPEN statement. If you want to be sure that the code works correctly and set the filename yourself, use

OPEN(UNIT=2, FILE='myfile.txt')

Upvotes: 1

Related Questions