_A GUI ENVIRONMENT FOR FORTRAN DEVELOPERS_ by Vinod Ananthraraman Listing 1: Branching based on the termination status of an executable program run via a Shell call. batfile% = OpenFile("\vshell\bat\compile.bat", FILEWR) 'Open batch file. If batfile% Then Print #batfile%, "NMAKE /F " + MakeFile 'Batch file runs NMAKE. Print #batfile%, "IF NOT ERRORLEVEL 1 exitdump temp1.tmp 0" 'If NMAKE runs successfully 'then write to temp1.tmp. Print #batfile%, "exitdump temp2.tmp 0" 'Write to temp2.tmp. Close batfile% If Len(Dir$("temp1.tmp")) > 0 Then Kill "temp1.tmp" 'If temporary files temp1.tmp If Len(Dir$("temp2.tmp")) > 0 Then Kill "temp2.tmp" 'or temp2.tmp exist, delete. x = Shell("c:\vshell\bat\compile.bat", 1) 'Now run the batch file. Compile_Timer.Enabled = TRUE 'Enable Compile_Timer. Shellform.Enabled = FALSE 'Disable the Main form. End If Listing 2: The file "mcarlo.for" with the Fortran DLL routines for Monte Carlo integration. SUBROUTINE MCARLO(INDF,C1,C2,C3,C4,XVAL,YVAL,ISIN) c c Takes INDF, the index of the function to integrate, its c coefficients (C1 to C4), and a random point (XVAL, YVAL) and c determines if the random point was inside the c function. If the point is inside the function, MCARLO sets ISIN c to 1 or -1 according as the point is on the negative or c positive side of the abscissa (the X coordinate axis). INTEGER INDF REAL*4 C1,C2,C3,C4 REAL*4 XVAL, YVAL INTEGER ISIN REAL*4 TRUEPT EXTERNAL FUNC,F1,F2,F3,F4,F5 ISIN = 0 TRUEPT = FUNC(INDF,XVAL,C1,C2,C3,C4) IF ((TRUEPT .GE. 0) .AND. (YVAL .LE. TRUEPT) + .AND. (YVAL .GE. 0)) THEN ISIN = 1 ELSE IF ((TRUEPT .LT. 0) .AND. (YVAL .GE. TRUEPT) + .AND. (YVAL .LE. 0)) THEN ISIN = -1 END IF RETURN END REAL*4 FUNCTION FUNC(INDF, X,C1, C2, C3, C4) c c Calls one of the functions F1-F5, depending on the value of the c index INDF. INTEGER INDF REAL*4 X, C1, C2,C3, C4 SELECT CASE (INDF) CASE (1) FUNC = F1(X,C1,C2) CASE (2) FUNC = F2(X,C1,C2) CASE (3) FUNC = F3(X,C1,C2,C3) CASE (4) FUNC = F4(X,C1,C2,C3,C4) CASE (5) FUNC = F5(X,C1,C2,C3) CASE DEFAULT FUNC = -999 END SELECT RETURN END REAL*4 FUNCTION F1(X,C1,C2) c c Linear function REAL*4 X, C1, C2 F1 = (C1*X) + C2 RETURN END REAL*4 FUNCTION F2(X,C1,C2) c c Square root function REAL*4 X, C1, C2 F2 = C1*SQRT(X) + C2 RETURN END REAL*4 FUNCTION F3(X,C1,C2,C3) c c Quadratic function REAL*4 X, C1, C2, C3 F3 = C1*X**2 + C2*X + C3 RETURN END REAL*4 FUNCTION F4(X,C1,C2,C3,C4) c c Third degree polynomial function REAL*4 X, C1, C2, C3, C4 F4 = C1*X**3 + C2*X**2 + C3*X + C4 RETURN END REAL*4 FUNCTION F5(X,C1,C2,C3) c c Trigonometric function REAL*4 X, C1, C2, C3 F5 = C1*SIN(X) + C2*COS(X) + C3 RETURN END SUBROUTINE RANDOMXY(XS,XE,YS,YE,RANX, RANY) c c Given the end points of a rectangular region, returns a random point c (RANX,RANY) within that region. REAL*4 XS,XE,YS,YE REAL*4 RVAL, RANX, RANY CALL RANDOM(RVAL) RANX = (XE - XS)*RVAL + XS CALL RANDOM(RVAL) RANY = (YE - YS)*RVAL + YS RETURN END Listing 3: The Visual Basic declarations file "mcarlo.bas" created by VShell to access the routines in the Fortran DLL "mcarlo.dll". This DLL was itself created by VShell from the Fortran source code in "mcarlo.for" shown in Listing 2. Declare Sub MCARLO Lib "c:\vb\mcarlo.dll" (Var1 As Long, Var2 As Single, Var3 As Single, Var4 As Single, Var5 As Single, Var6 As Single, Var7 As Single, Var8 As Long, Var9 As Long) Declare Function FUNC Lib "c:\vb\mcarlo.dll" (Var1 As Long, Var2 As Single, Var3 As Single, Var4 As Single, Var5 As Single, Var6 As Single) As Single Declare Function F1 Lib "c:\vb\mcarlo.dll" (Var1 As Single, Var2 As Single, Var3 As Single) As Single Declare Function F2 Lib "c:\vb\mcarlo.dll" (Var1 As Single, Var2 As Single, Var3 As Single) As Single Declare Function F3 Lib "c:\vb\mcarlo.dll" (Var1 As Single, Var2 As Single, Var3 As Single, Var4 As Single) As Single Declare Function F4 Lib "c:\vb\mcarlo.dll" (Var1 As Single, Var2 As Single, Var3 As Single, Var4 As Single, Var5 As Single) As Single Declare Function F5 Lib "c:\vb\mcarlo.dll" (Var1 As Single, Var2 As Single, Var3 As Single, Var4 As Single) As Single Declare Sub RANDOMXY Lib "c:\vb\mcarlo.dll" (Var1 As Single, Var2 As Single, Var3 As Single, Var4 As Single, Var5 As Single, Var6 As Single) Listing 4: Visual Basic front end code that calls routines in "mcarlo.dll" and displays the result of the Monte Carlo integration. NumIn = 0 'NumIn is the effective number of random points inside the function. 'Points in the negative side of the function have a weight of -1. For j% = 1 To Nr 'Nr is the number of random points used for the integration. Call RANDOMXY(Xstart,Xend,Ystart,Yend,Xvalue!,Yvalue!) 'This DLL routine returns (Xvalue!,Yvalue!), a random point in the 'rectangular region between (Xstart,Ystart) and (Xend,Yend). Call MCARLO(FnIndex,Coeff1,Coeff2,Coeff3,Coeff4,Xvalue!,Yvalue!,IsIn&) 'The DLL routine to determine if the random point is inside the 'function. The index of the function being integrated and its 'coefficients are parameters. NumIn = NumIn + IsIn& Next j% TotalAreaLabel.Visible = TRUE IntegralLabel.Visible = TRUE Integral# = (NumIn / Nr) * (Xend - Xstart) * (Yend - Ystart) 'The integral value estimated by Monte Carlo integration. TotalAreaLabel.Caption = "Sampled area: " + Str$((Xend - Xstart) * (Yend - Ystart)) 'Display the total area sampled for random points. IntegralLabel.Caption = "Value of integral (colored): " + Str$(Integral#) 'Display the estimated integral value.