这是一个较长的代码,我遇到了麻烦,我认为这是因为我不确定我是否完全理解行WRITE(6,*) 'INPUT S,K,TAU,SIGMA,R,DELTA,DTAU'
和READ(5,*) S,K,TAU,SIGMA,R,DELTA,DTAU
。如果我只是运行.f文件,我得到
executable.exe
INPUT S,K,TAU,SIGMA,R,DELTA,DTAU
然后我输入以下输入
100.0d0,100.0d0,3.0d0,0.2d0,0.08d0,0.04d0,0.03d0
执行此操作后,我在目录中获取一个名为“fort.2”的新文件。我不知道代码中的哪个据说可以生成?因为如果我改变
WRITE(2,10) T(I),BD(I)
到
WRITE(3,10) T(I),BD(I)
我仍然得到文件“fort.2”。无论如何我怀疑“fort.2”是正确的输出,因为在其中有两列(1)T(I)
的值和(2)BD(I)
的值。第一列是正确的T(I)
,0.03d0
步骤更改为3.0d0
,这来自DTAU, TAU
。但是BD(I)
每个0.03d0
步骤都不会发生变化,它会在几个0.03d0
步骤中保持不变,然后会突然发生变化(如步进功能)。 BD(I)
应该针对每个3.0d0
步骤进行更改。现在我不知道我有点失落。主要代码:
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
答案 0 :(得分:1)
在程序中,行
WRITE(6,*) 'INPUT S,K,TAU,SIGMA,R,DELTA,DTAU'
应该向用户写出指令。在那之后,行
READ(5,*) S,K,TAU,SIGMA,R,DELTA,DTAU
等待以RETURN
结尾的逗号分隔值列表。所以我猜这是预期的行为。如果您运行该程序,当您看到输出
INPUT S,K,TAU,SIGMA,R,DELTA,DTAU
输入7,以逗号分隔的值,程序将为您计算结果。
另一方面,如果您将原始WRITE
声明更改为
WRITE(6,*) S,K,TAU,SIGMA,R,DELTA,DTAU
你会得到一些随机输出,因为那些你正在写出来的值的变量在那时是未初始化的。
修改强>:
许多网页都详细解释了WRITE
格式。请参阅示例this one。在您的具体情况下,有WRITE
行和FORMAT
行,它们一起指定输出的外观:
WRITE(2,10) T(I),BD(I)
...
10 FORMAT(1X,2F14.8)
WRITE(2,10) T(I),BD(I)
将变量写入文件流2
(您最有可能使用open (unit = 2, file = "fort.2")
之类的命令打开这些变量,其格式为10
行指定的格式(这只是写声明下面的两行)。格式说明符的工作原理在我提供的链接中有解释。
编辑2 :
正如评论中所指出的,fort.2
是一些fortran编译器使用的标准名称,如果写入流nr。 2
没有先使用OPEN
语句。如果您想确保代码正常工作并自己设置文件名,请使用
OPEN(UNIT=2, FILE='myfile.txt')
答案 1 :(得分:0)
BD(I)正在逐步改变,因为它的计算是在这个IF测试中:
IF (VC.LT.VE(J).AND.IEARLY.EQ.0) THEN
BD(I) = DEXP(XMIN+J*DX)
T(I) = DTAU*DFLOAT(I)
IEARLY = 1
ENDIF
从I = 1到I = 10,当J = 3时,IF测试成功。当I = 11时,当J = 2时成功,改变BD(I)的计算。当I = 38时,IF测试在J = 1时成功,BD(I)的计算再次改变。