AMI-5: An Adaptive
Multidimensional Integrator
AMI-5 is an adaptive multidimensional five-point integrator to approximate the iterated integral
with u not necessarily bounded.
Here, each lower-limit function fi and each upper-limit function gi
is a function of i variables, i = 0, ... , n - 1 (meaning, of
course, that f0 and g0 are constants).
You can download the zipped source with a couple of examples, or you can have fun
figuring out the simulation of recursive descent in a nonrecursive environment by looking at the source listing shown below.
C A M I - 5
C
C-----------------------------------------------------------------------
SUBROUTINE AMI5(N,A,B,F,G,U,BOUND,STEP,S,NS,V,IFLAG)
C-----------------------------------------------------------------------
C
C
C A D A P T I V E
C
C M U L T I D I M E N S I O N A L
C
C I N T E G R A T O R
C
C F I V E - P O I N T E X T R A P O L A T E D S I M P S O N
C
C
C-----------------------------------------------------------------------
C
C LUCIO TAVERNINI
C DIVISION OF MATHEMATICS, COMPUTER SCIENCE, AND STATISTICS
C UNIVERSITY OF TEXAS AT SAN ANTONIO
C SAN ANTONIO, TEXAS 78285
C
C AUGUST 15, 1983 -- REVISED JULY 12, 1988
C
C ADAPTED FROM THE ORIGINAL MDQUAD, WRITTEN FOR THE UNIVERSITY OF
C WISCONSIN COMPUTER CENTER LIBRARY IN 1968
C
C-----------------------------------------------------------------------
C
C --- ADAPTIVE APPROXIMATION TO AN N-FOLD ITERATED INTEGRAL ---
C
C THE ITERATED INTEGRALS ARE NUMBERED FROM 1 TO N STARTING
C WITH THE OUTERMOST INTEGRAL AND PROCEEDING TO THE INNERMOST.
C
C-----------------------------------------------------------------------
C
C
C INPUT PARAMETERS:
C
C
C - N -
C
C N IS THE DIMENSION OF THE INTEGRAL.
C
C DATATYPE: INTEGER.
C
C REQUIREMENT: 0 < N < 11.
C
C
C - A , B -
C
C A AND B ARE, RESPECTIVELY, THE LOWER AND UPPER LIMITS OF
C INTEGRATION FOR THE OUTERMOST INTEGRAL.
C
C DATATYPE: REAL*8.
C
C REQUIREMENT: A < B.
C
C
C - F , G -
C
C F AND G ARE ENTRY POINT NAMES OF USER-SUPPLIED FUNCTIONS
C WHICH DEFINE, RESPECTIVELY, THE LOWER AND UPPER LIMITS OF
C INTEGRATION. F MUST BE CODED BY THE USER TO BE EQUIVALENT
C TO THE FOLLOWING. (G MUST BE CODED SIMILARLY.)
C
C
C FUNCTION F(I,X)
C INTEGER I
C REAL*8 F,X(1)
C
C GO TO(1,2,...,N-1),I
C
C 1 F = VALUE OF LOWER LIMIT FOR LEVEL I+1
C AS A FUNCTION OF X(1)
C RETURN
C
C 2 F = VALUE OF LOWER LIMIT FOR LEVEL I+2
C AS A FUNCTION OF X(1) AND OF X(2)
C RETURN
C .
C .
C .
C
C N-1 F = VALUE OF LOWER LIMIT FOR LEVEL N
C AS A FUNCTION OF X(1),...,X(N-1)
C RETURN
C
C END
C
C
C REQUIREMENT: F MUST RETURN A VALUE NOT GREATER THAN THE
C VALUE RETURNED BY G OVER THE REGION OF
C INTEGRATION. IF THIS CONDITION FAILS TO BE
C SATISFIED, THE INTEGRAL TO WHICH THE LIMITS
C APPLY IS TAKEN TO BE ZERO. (THAT IS, THE
C LIMITS ARE TAKEN TO BE IDENTICAL.)
C
C
C - U -
C
C U IS THE ENTRY POINT NAME OF A USER-SUPPLIED REAL*8 FUNCTION
C WHICH EVALUATES THE INTEGRAND. U MUST BE CODED BY THE USER
C TO BE EQUIVALENT TO THE FOLLOWING.
C
C FUNCTION U(X)
C REAL*8 U,X(1)
C U = VALUE OF THE INTEGRAND AT X(1),...,X(N)
C RETURN
C END
C
C
C - BOUND -
C
C BOUND IS THE BOUND ON THE ESTIMATED GLOBAL DISCRETIZATION ERROR
C AMI USES SIMPSON'S RULE TO APPROXIMATE EACH ONE-
C DIMENSIONAL INTEGRAL. A NONUNIFORM GRID IS USED. THE
C SIMPSON APPROXIMATION COMPUTED ON EACH INTERVAL IS
C COMPARED TO THE RESULT OBTAINED BY APPLYING SIMPSON'S
C RULE TWICE, AFTER SPLITTING THE INTERVAL INTO TWO EQUAL
C HALVES. EXTRAPOLATION TO ZERO IS USED TO ESTIMATE THE
C LOCAL DISCRETIZATION ERROR.
C
C DATATYPE: REAL*8.
C
C REQUIREMENT: BOUND > 0.
C
C
C - STEP -
C
C STEP SPECIFIES THE SMALLEST INTEGRATION STEP WHICH CAN BE
C USED BY AMI. SHOULD THE INTEGRATION STEP ATTAIN A
C SMALLER VALUE DURING THE COMPUTATIONS, AMI ACCEPTS THE
C CURRENT ESTIMATE EVEN THOUGH THE ESTIMATED ERROR MAY
C EXCEED THE ERROR BOUND.
C
C DATATYPE: REAL*8.
C
C REQUIREMENT: STEP >= 0.
C
C
C - S , NS -
C
C S AND NS SPECIFY THE USER-SUPPLIED AMI WORKSPACE. S IS THE
C FIRST-ELEMENT NAME OF A FORTRAN ARRAY WHICH CAN BE USED BY
C AMI AS A SCRATCH WORKSPACE. NS SPECIFIES THE NUMBER
C OF ELEMENTS OF SIZE REAL*8 AVAILABLE TO AMI. AMI REVERTS
C TO A UNIFORM GRID IF INSUFFICIENT STORAGE IS AVAILABLE FOR
C THE USE OF ADAPTIVE INTEGRATION THROUGHOUT.
C
C DATATYPE: THE DATATYPE OF S IS NOT IMPORTANT,
C THE DATATYPE OF NS MUST BE INTEGER.
C
C REQUIREMENT: NS MUST INDICATE THE NUMBER OF ELEMENTS
C OF SIZE REAL*8 THAT ARE AVAILABLE. THE VALUE OF
C NS MUST BE AT LEAST 5*N. IF NS = 5*N,
C A UNIFORM GRID IS USED THROUGHOUT.
C
C
C-----------------------------------------------------------------------
C
C
C OUTPUT PARAMETERS:
C
C
C - V -
C
C V CONTAINS THE VALUE OF THE APPROXIMATE INTEGRAL.
C
C DATATYPE: REAL*8.
C
C
C - IFLAG -
C
C IFLAG RETURNS INFORMATION TO THE USER. THE MEANING OF
C IFLAG IS TO BE INTERPRETED AS FOLLOWS.
C
C IFLAG = 0 MEANS THAT THE COMPUTATION HAS BEEN COMPLETED
C NORMALLY. IF NOT, EACH DIGITS OF (THE BASE 10
C REPRESENTATION OF) IFLAG IS ASSIGNED THE VALUE 1 TO INDICATE
C THAT ONE OF THE CONDITIONS SHOWN IN THE TABLE GIVEN BELOW HAS
C OCCURRED. OTHERWISE, THE DIGIT HAS VALUE 0. THE DIGITS ARE
C NUMBERED FROM RIGHT TO LEFT STARTING WITH 1.
C
C
C DIGIT MEANING
C ----- -------
C
C 1 FUNCTION F HAS FAILED TO RETURN A VALUE LESS
C THAN THE VALUE RETURNED BY FUNCTION G (WHEN
C BOTH WERE EVALUATED AT THE SAME POINT) DURING
C THE COMPUTATIONS.
C
C 2 INSUFFICIENT STORAGE HAS BEEN ALLOCATED FOR
C THE USE OF ADAPTIVE INTEGRATION THROUGHOUT.
C A UNIFORM MESH HAS BEEN USED FOR PORTIONS
C OR FOR ALL OF THE COMPUTATIONS.
C
C 3 THE LOWER BOUND ON THE INTEGRATION STEP WAS
C ATTAINED DURING THE COMPUTATIONS.
C
C 4 A FATAL ERROR HAS OCCURRED. REFER TO THE
C PRINTER/TERMINAL OUTPUT FOR ADDITIONAL
C INFORMATION.
C
C DATATYPE: INTEGER.
C
C
C-----------------------------------------------------------------------
C
C
C COMMON:
C
C
C BEFORE CALLING AMI5 FOR THE FIRST TIME, THE USER MUST ASSIGN
C A FORTRAN CHANNEL FOR ANY ERROR MESSAGES THAT MAY BE GENERATED
C BY AMI5. THE COMMON BLOCK NAME IS OUTCHL. IT CONTAINS A
C SINGLE INTEGER VARIABLE, WHERE THE USER MUST STORE THE CHANNEL
C NUMBER:
C
C
C INTEGER OUTCHL
C COMMON/OUTCHL/OUTCHL
C
C
C-----------------------------------------------------------------------
C
C
C ----------
C PARAMETERS
C ----------
C
INTEGER IFLAG,N,NS
REAL*8 A,B,BOUND,STEP,V,U,F,G
C
C USER-ALLOCATED WORKSPACE
REAL*8 S(NS)
C
C ------
C LOCALS
C ------
C
INTEGER NC,NT
C
C FORTRAN CHANNEL FOR ERROR MESSAGES
INTEGER OUTCHL
COMMON/OUTCHL/OUTCHL
C
C ASSIGN WORKSPACE
NT = NS/5
NC = NT/N
C
C TEST PARAMETERS
C
IFLAG = 0
C
IF( N .LT. 11 .AND. N .GT. 0 ) GO TO 10
IFLAG = 1000
WRITE(OUTCHL,100)
WRITE(OUTCHL,101) N
10 CONTINUE
C
IF( B .GT. A ) GO TO 20
IF( IFLAG .EQ. 0 ) WRITE(OUTCHL,100)
IFLAG = 1000
WRITE(OUTCHL,102) A,B
20 CONTINUE
C
IF( BOUND .GT. 0 ) GO TO 30
IF( IFLAG .EQ. 0 ) WRITE(OUTCHL,100)
IFLAG = 1000
WRITE(OUTCHL,103) BOUND
30 CONTINUE
C
IF( STEP .GE. 0 ) GO TO 40
IF( FLAG .EQ. 0 ) WRITE(OUTCHL,100)
IFLAG = 1000
WRITE(OUTCHL,104) STEP
40 CONTINUE
C
IF( NC .GT. 0 ) GO TO 50
IF( IFLAG .EQ. 0 ) WRITE(OUTCHL,100)
IFLAG = 1000
WRITE(OUTCHL,105) NS
50 CONTINUE
C
60 IF( IFLAG .GT. 0 ) RETURN
C
CALL AMI5WK(U,F,G,N,A,B,BOUND,STEP,V,IFLAG,NC,
* S(1),S(NT+1),S(2*NT+1))
C ------
RETURN
C ------
C
100 FORMAT('0 * A M I 5 * INPUT PARAMETER ERROR(S):')
C
101 FORMAT(16X,'PARAMETER 1: N =',I10/
* 16X,'REQUIREMENT: 0 < N < 11.')
C
102 FORMAT(16X,'PARAMETER 2: A =',E15.6/
* 16X,'PARAMETER 3: B =',E15.6/
* 16X,'REQUIREMENT: A < B.')
C
103 FORMAT(16X,'PARAMETER 7: BOUND =',E15.6/
* 16X,'REQUIREMENT : BOUND > 0.')
C
104 FORMAT(16X,'PARAMETER 8: STEP =',E15.6/
* 16X,'REQUIREMENT: STEP >= 0.')
C
105 FORMAT(16X,'PARAMETER 10: NS =',I3/
* 16X,'REQUIREMENT: NS >= 5*N, WHERE N IS PARAMETER 1.')
C
END
C-----------------------------------------------------------------------
SUBROUTINE AMI5WK(U,F,G,N,AEP,BEP,EPSMAX,STEP,
* VALUE,IFLAG,NC,A,I,Q)
C-----------------------------------------------------------------------
C
C SUBSCRIPTING SCHEME USED FOR THE J-TH INTEGRATION INTERVAL
C AT RECURSION LEVEL L TO STORE VALUES OF THE INTEGRAND:
C
C
C
C
C Q(1,L,J) Q(2,L,J) Q(3,L,J)
C
C | | |
C | | |
C +-------------+-------------+-------------+-------------+
C | |
C | |
C
C P(1,L) P(2,L)
C
C
C ------------------
C VARIABLE WORKSPACE
C ------------------
REAL*8 A(N,NC),I(N,NC),Q(3,N,NC)
C
C ---------------
C FIXED WORKSPACE
C ---------------
INTEGER COUNTR(10),J(10),JEND(10),JTAB(10),
* K(10),M(10),MSTART(10),NSTEPS(10)
C
LOGICAL C001,C010,C100
C
REAL*8 AEP,BEP,EON,EPS(10),EPSMAX,U,F,G,H(10),HO3,HO6,
* I1,I2,LENGTH(10),P(2,10),
* STEP,SUM0(10),SUM1(10),SUM2(10),SUM3(10),V(11),VALUE,X(10)
C
C
C +--------------+
C | INITIALIZE |
C +--------------+
C
EON = EPSMAX/N
ASSIGN 500 TO J500
ASSIGN 1100 TO J1100
ASSIGN 2300 TO J2300
C001 = .FALSE.
C010 = .FALSE.
C100 = .FALSE.
A(1,1) = AEP
LENGTH(1) = BEP - AEP
L = 0
C
C +---------------------+
C | RECURSIVE DESCENT |
C +---------------------+
C
C --------------------------------------------------
C BEGIN: INITIALIZE TABLES FOR ADAPTIVE INTEGRATION.
C --------------------------------------------------
C
C INCREMENT LEVEL COUNTER.
100 L = L + 1
C
C SKIP EVALUATION OF F AND G FOR OUTER LIMITS OF INTEGRATION.
IF( L .EQ. 1 ) GO TO 200
A(L,1) = F(L-1,X)
LENGTH(L) = G(L-1,X) - A(L,1)
200 CONTINUE
C
C INITIALIZE APPROXIMATION AT THIS LEVEL TO ZERO
V(L) = 0
C
C TEST FOR INTEGRATION INTERVAL OF LENGTH ZERO
C001 = C001 .OR. LENGTH(L) .LT. 0
IF( LENGTH(L) .LE. 0 ) GO TO 5100
C
C H(L) IS THE DISTANCE BETWEEN GRID POINTS FOR LEVEL L.
H(L) = .5*LENGTH(L)
C
C EPS(L) IS USED TO BOUND THE ESTIMATED DISCRETIZATION
C ERROR AT LEVEL L.
EPS(L) = EON
C
C DECREASE ERROR BOUND TO SATISFY GLOBAL BOUND ON
C ASYMPTOTIC ERROR ESTIMATE.
LM1 = L - 1
IF( LM1 .LT. 1 ) GO TO 400
DO 300 INDEX = 1,LM1
300 EPS(L) = EPS(L)/LENGTH(INDEX)
400 CONTINUE
C
C INITIALIZE POINTERS FOR ADAPTIVE INTEGRATION WORKLIST.
K(L) = -1
J(L) = 1
MSTART(L) = NC
M(L) = NC
JEND(L) = 0
C
C -----------------------------------------
C COMPUTE POINTS FOR SIMPSON APPROXIMATION.
C -----------------------------------------
COUNTR(L) = 1
430 IF( COUNTR(L) .GT. 3 ) GO TO 600
X(L) = A(L,1) + ( COUNTR(L) - 1)*H(L)
C ---------------------------------------
C RECURSIVE DESCENT OR DIRECT EVALUATION?
IF( L .EQ. N) GO TO 450
JTAB(L) = J500
GO TO 100
450 V(L+1) = U(X)
C ---------------------------------------
C STORE POINT.
500 Q(COUNTR(L),L,1) = V(L+1)
COUNTR(L) = COUNTR(L) + 1
GO TO 430
600 CONTINUE
C
C --------------------------------
C EVALUATE SIMPSON APPROXIMATIONS.
C --------------------------------
I(L,1) = LENGTH(L)/6.*( Q(1,L,1) + 4.*Q(2,L,1) + Q(3,L,1) )
C
C -------------------------------------------------
C END: INITIALIZE TABLES FOR ADAPTIVE INTEGRATION.
C -------------------------------------------------
C
C +----------------------------------------+
C | VARIABLE STEP (ADAPTIVE) INTEGRATION |
C +----------------------------------------+
C
C -------------------------------------
C ARE WE THROUGH WITH CURRENT WORKLIST?
C -------------------------------------
800 IF( J(L) .EQ. JEND(L) ) GO TO 3300
C
C WE ARE NOT THROUGH: EVALUATE MIDPOINTS
C BETWEEN PREVIOUS POINTS.
COUNTR(L) = 1
1020 IF( COUNTR(L) .GT. 2 ) GO TO 1200
X(L) = A(L,J(L)) + ( COUNTR(L) - 0.5 )*H(L)
C ---------------------------------------
C RECURSIVE DESCENT OR DIRECT EVALUATION?
IF( L .EQ. N ) GO TO 1050
JTAB(L) = J1100
GO TO 100
1050 V(L+1) = U(X)
C ---------------------------------------
C STORE VALUE OF NEW MIDPOINT.
1100 P(COUNTR(L),L) = V(L+1)
COUNTR(L) = COUNTR(L) + 1
GO TO 1020
1200 CONTINUE
C
C -----------------------------------------------------------
C EVALUATE NEW SIMPSON APPROXIMATIONS OVER PREVIOUS INTERVAL.
C -----------------------------------------------------------
C
J1 = J(L)
HO6 = H(L)/6.
I1 = HO6*( Q(1,L,J1) + 4.*P(1,L) + Q(2,L,J1) )
I2 = HO6*( Q(2,L,J1) + 4.*P(2,L) + Q(3,L,J1) )
C
C ERR = ASYMPTOTIC ERROR ESTIMATE.
ERR = ( I1 + I2 - I(L,J1) )/15.
C
C TEST ASYMPTOTIC ESTIMATE AGAINST BOUND.
C100 = C100 .OR. H(L) .LT. STEP
IF( ABS(ERR) .LT. EPS(L) .OR. H(L) .LT. STEP ) GO TO 3200
C ------------------------------------
C ESTIMATED ERROR IS ABOVE UPPER BOUND
C ------------------------------------
C TEST FOR STORAGE OVERFLOW
IF( M(L) .NE. J1 ) GO TO 3100
C
C --------------------------------------
C BEGIN: RECOVER FROM STORAGE OVERFLOW.
C --------------------------------------
C
C CHANGE TO A UNIFORM INTEGRATION STEP.
C010 = .TRUE.
SUM1(L) = Q(1,L,J1) + Q(3,L,J1)
SUM2(L) = Q(2,L,J1) + P(1,L) + P(2,L)
C
C SAVE H(L)
Q(1,L,J1) = H(L)
H(L) = .5*H(L)
NSTEPS(L) = 4
SUM0(L) = I1 + I2
C
C REPEAT UNTIL ESTIMATED ERROR IS BELOW THE PRESCRIBED BOUND
2100 SUM3(L) = 0
C -----------------------------------
C BEGIN: LOOP TO SUM FUNCTION VALUES.
C -----------------------------------
COUNTR(L) = 1
2200 IF( COUNTR(L) .GT. NSTEPS(L) ) GO TO 2400
X(L) = A(L,J1) + ( COUNTR(L) - 0.5 )*H(L)
C ---------------------------------------
C RECURSIVE DESCENT OR DIRECT EVALUATION?
IF( L .EQ. N ) GO TO 2250
JTAB(L) = J2300
GO TO 100
2250 V(L+1) = U(X)
C ---------------------------------------
2300 SUM3(L) = SUM3(L) + V(L+1)
COUNTR(L) = COUNTR(L) + 1
GO TO 2200
2400 CONTINUE
C ---------------------------------
C END: LOOP TO SUM FUNCTION VALUES.
C ---------------------------------
C
C EVALUATE SIMPSON APPROXIMATION.
I2 = H(L)/6.*( SUM1(L) + 2.*SUM2(L) + 4.*SUM3(L) )
ERR = ( I2 - SUM0(L) )/15
C
C TEST ASYMPTOTIC ERROR ESTIMATE.
C100 = C100 .OR. H(L) .LT. STEP
IF(ABS( ERR) .LT. EPS(L) .OR. H(L) .LT. STEP ) GO TO 2500
SUM2(L) = SUM2(L) + SUM3(L)
NSTEPS(L) = 2*NSTEPS(L)
H(L) = .5*H(L)
SUM0(L) = I2
GO TO 2100
C
2500 V(L) = ERR + I2 + V(L)
C
C RESTORE H(L)
H(L) = Q(1,L,J(L))
J(L) = J(L) + K(L)
GO TO 800
C
C -----------------------------------
C END: RECOVER FROM STORAGE OVERFLOW.
C -----------------------------------
C
3100 CONTINUE
C
C MORE STORAGE IS AVAILABLE. SPLIT THE CURRENT
C INTERVAL INTO TWO SUBINTERVALS AND PLACE THEM
C IN THE NEXT WORKLIST
M1 = M(L)
M2 = M(L) + K(L)
A(L,M1) = A(L,J1)
A(L,M2) = A(L,J1) + H(L)
I(L,M1) = I1
I(L,M2) = I2
Q(1,L,M1) = Q(1,L,J1)
Q(2,L,M1) = P(1,L)
Q(3,L,M1) = Q(2,L,J1)
Q(1,L,M2) = Q(2,L,J1)
Q(2,L,M2) = P(2,L)
Q(3,L,M2) = Q(3,L,J1)
M(L) = M2 + K(L)
J(L) = J(L) + K(L)
GO TO 800
3200 CONTINUE
C
C ESTIMATED ERROR IS WITHIN BOUNDS. ACCEPT APPROXIMATION.
V(L) = ERR + I1 + I2 + V(L)
C UPDATE CURRENT WORKLIST POINTER FOR NEXT SUBINTERVAL.
J(L) = J(L) + K(L)
GO TO 800
3300 CONTINUE
C -----------------------------------------
C WE ARE THROUGH WITH THE CURRENT WORKLIST.
C -----------------------------------------
C
C --------------------------
C IS THE NEW WORKLIST EMPTY?
C --------------------------
IF( M(L) .EQ. MSTART(L) ) GO TO 5100
C
C NEW WORKLIST IS NOT EMPTY. TEST TO SEE IN WHICH DIRECTION
C POINTERS ARE TO BE MOVING.
IF(K(L).GT.0) GO TO 4100
C
C POINTERS ARE TO MOVE FROM LOW TO HIGH
3400 K(L) = 1
J(L) = M(L) + 1
JEND(L) = NC + 1
M(L) = 1
MSTART(L) = 1
EPS(L) = .5*EPS(L)
H(L) = .5*H(L)
GO TO 800
4100 CONTINUE
C
C POINTERS ARE TO MOVE FROM HIGH TO LOW
K(L) = -1
J(L) = M(L) - 1
JEND(L) = 0
M(L) = NC
MSTART(L) = NC
EPS(L) = .5*EPS(L)
H(L) = .5*H(L)
GO TO 800
5100 CONTINUE
C
C +---------------------------------+
C | RETURN FROM RECURSIVE DESCENT |
C +---------------------------------+
C
C BACK UP LEVEL COUNTER.
L = L - 1
C
C ARE WE THROUGH WITH LEVEL ONE?
IF( L .NE. 0 ) GO TO 5200
C
C ----------------------------
C WE ARE AT LEVEL ZERO: DONE.
C ----------------------------
VALUE = V(1)
IF( C001 ) IFLAG = IFLAG + 1
IF( C010 ) IFLAG = IFLAG + 10
IF( C100 ) IFLAG = IFLAG + 100
RETURN
5200 CONTINUE
C
C RESTORE RETURN ADDRESS.
JX = JTAB(L)
C RETURN.
GO TO JX, (500,1100,2300)
C
END