REAL WORK(1000),TNODE(4) MAIN 1 INTEGER IWORK(200) MAIN 2 EXTERNAL F,G,LEFT MAIN 3 LOGICAL LEFT MAIN 4 C MAIN 5 C TEST DRIVER TO ILLUSTRATE THE USE OF HEAP SUBROUTINES FOR MAIN 6 C QUADRATURE. MAIN 7 C THIS PROGRAM CALLS THE ADAPTIVE QUADRATURE SUBROUTINE AGQ MAIN 8 C TO INTEGRATE THE TWO FUNCTIONS MAIN 9 C F(X)=EXP(X) MAIN 10 C AND MAIN 11 C G(X)=1./SQRT(X) MAIN 12 C ON (0., 1.) TO AN ABSOLUTE ACCURACY OF 1.E-05 MAIN 13 C THE DEFINITIONS OF THE ARGUMENTS TO SUBROUTINE AGQ ARE GIVEN MAIN 14 C IN THE COMMENTS FOR THAT SUBROUTINE. MAIN 15 C FOR EACH OF THESE TWO PROBLEMS THIS TEST PROGRAM PRINTS MAIN 16 C Q = THE COMPUTED ESTIMATE OF THE INTEGRAL MAIN 17 C E = THE COMPUTED ESTIMATE OF THE ERROR MAIN 18 C N = THE NUMBER OF SUBINTERVALS IN THE FINAL PARTITION OF MAIN 19 C THE INTERVAL (0., 1.) MAIN 20 C IFLAG = A SUCCESS (0) OR FAILURE (1) INDICATOR. MAIN 21 C MAIN 22 CALL AGQ(0.,1.,F,1.E-05,Q,E,N,100,WORK,IWORK,IFLAG) MAIN 23 WRITE (6,102) MAIN 24 WRITE(6,100) Q,E,N,IFLAG MAIN 25 CALL AGQ(0.,1.,G,1.E-05,Q,E,N,100,WORK,IWORK,IFLAG) MAIN 26 WRITE(6,100) Q,E,N,IFLAG MAIN 27 C MAIN 28 C AFTER THE SECOND PROBLEM WE REORGANIZE THE HEAP SO THAT THE MAIN 29 C ROOT INTERVAL IS THE LEFTMOST ONE, AND THEN PRINT THE MAIN 30 C SUBINTERVALS USED LEFT TO RIGHT. MAIN 31 C MAIN 32 CALL HPBLD(100,4,WORK,N,IWORK,LEFT) MAIN 33 M=N MAIN 34 WRITE(6,103) MAIN 35 DO 1 I=1,M MAIN 36 CALL HPACC(100,4,WORK,N,IWORK,TNODE,1) MAIN 37 WRITE(6,101) (TNODE(J), J=1,4) MAIN 38 CALL HPDEL(100,4,WORK,N,IWORK,LEFT) MAIN 39 1 CONTINUE MAIN 40 C MAIN 41 100 FORMAT(1X,2E16.8,2I10) MAIN 42 101 FORMAT( 1X,4E16.8) MAIN 43 102 FORMAT(16H QUAD. EST. ,16H ERR. EST. ,10H NO. INTS ,10H SMAIN 44 1UCCESS=0 ) MAIN 45 103 FORMAT(65H FINAL SUBINTERVALS...ERR EST, QUAD EST, L. END PT, RTMAIN 46 1. END PT ) MAIN 47 STOP MAIN 48 END MAIN 49 LOGICAL FUNCTION LEFT(A,B,NCHAR) LEFT 1 DIMENSION A(1), B(1) C C A TEST HEAP FUNCTION. C THIS FUNCTION SETS LEFT = TRUE IF THE THIRD COMPONENT OF C NODE A IS .LT. THE THIRD COMPONENT OF NODE B. C FOR THE TEST PROBLEM THIS COMPONENT CONTAINS THE LEFT END- C POINT OF THE INTERVAL DEFINED BY THE NODE. C LEFT= A(3) .LT. B(3) RETURN END FUNCTION F(X) F 1 F=EXP(X) RETURN END FUNCTION G(X) G 1 G=1./SQRT(X) RETURN END SUBROUTINE AGQ(A,B,F,EPS,Q,E,N,NMAX,XNODES,T,IFLAG) AGQ 1 C C 1-D ADAPTIVE QUADRATURE-EXAMPLE USING HEAPS C INPUT C A, B = LIMITS OF INTEGRATION A.LT.B C F = NAME OF USER SUPPLIED INTEGRAND FUNCTION, FUNCTION F(X) C EPS = REQUESTED ABSOLUTE ACCURACY OF QUADRATURE C NMAX = MAX NUMBER OF NODES ALLOWED C XNODES = ARRAY FOR NODE STORAGE, DIMENSIONED AT LEAST 4*NMAX C T = INTEGER ARRAY USED INTERNALLY, DIMENSIONED AT LEAST NMAX C OUTPUT C Q = QUADRATURE ESTIMATE C E = ERROR ESTIMATE C N = NUMBER OF NODES REQUIRED FOR THE QUADRATURE C IFLAG = ERROR INDICATOR C = 0 PROGRAM APPARENTLY SUCCESSFUL C = 1 NODE STORAGE EXCEEDED, CALCULATION TERMINATED C C EACH NODE IN THE HEAP REPRESENTS A SUBINTERVAL AND IS C A FOUR WORD ARRAY. C NODE(1) = ERROR ESTIMATE C NODE(2) = QUADRATURE ESTIMATE C NODE(3) = LEFT INTERVAL ENDPOINT C NODE(4) = RIGHT INTERVAL ENDPOINT C EXTERNAL GREATR,F LOGICAL GREATR REAL TNODE(4),N1(4),N2(4),XNODES(1) INTEGER T(1) C CALL HPINIT(NMAX,N,T) CALL QINIT(TNODE,A,B) E=TNODE(1) Q=TNODE(2) C C INSERT INITIAL NODE C CALL HPINS(NMAX,4,XNODES,N,T,TNODE,GREATR) C 1 IF(E .LE. EPS) RETURN CALL HPACC(NMAX,4,XNODES,N,T,TNODE,1) CALL HPDEL(NMAX,4,XNODES,N,T,GREATR) CALL QSDVD(TNODE,N1,N2,F) CALL HPINS(NMAX,4,XNODES,N,T,N1,GREATR) CALL HPINS(NMAX,4,XNODES,N,T,N2,GREATR) E=E-TNODE(1)+N1(1)+N2(1) Q=Q-TNODE(2)+N1(2)+N2(2) IFLAG=1 IF(N .GE. NMAX-1) RETURN IFLAG=0 GO TO 1 END SUBROUTINE QINIT(NODE,A,B) QINIT 1 C C INITIALIZES THE FIRST INTERVAL TO A NODE BY SETTING THE C ERROR ESTIMATE AND QUADRATURE ESTIMATE TO 1000. AND 0. RESP. C REAL NODE(4) NODE(1)=1000. NODE(2)=0.0 NODE(3)=A NODE(4)=B RETURN END SUBROUTINE QSDVD(NODE,R,L,F) QSDVD 1 C C SUBDIVIDES A NODE INTO TWO EQUAL HALVES. C THE ENDPOINTS OF THE NEW NODES ARE COMPUTED HERE. THE ERROR C AND QUADRATURE ESTIMATES FOR THE LEFT (L) AND RIGHT (R) C HALVES ARE COMPUTED BY THE SUBROUTINE QUAD. C EXTERNAL F REAL NODE(4),R(4),L(4) L(3)=NODE(3) R(4)=NODE(4) L(4)=(L(3)+R(4))/2. R(3)=L(4) CALL QUAD(L,F) CALL QUAD(R,F) RETURN END SUBROUTINE QUAD(NODE,F) QUAD 1 C C ESTIMATES INTEGRAL OF F ON NODE USING 2 AND 3 POINT GAUSS. C THE 3 POINT FORMULA GIVES ESTIMATE AND DIFFERENCE OF 2 AND 3 C GIVES ERROR ESTIMATE C REAL NODE(4) XL=(NODE(4)-NODE(3))/2. XM=(NODE(4)+NODE(3))/2. Q2=XL*(F(XL*(-.5773502692)+XM)+F(XL*(.5773502692)+XM)) Q3=XL*((F(XL*(-.7745966692)+XM)+F(XL*(.7745966692)+XM))/1.8+ 1 F(XM)/1.125) NODE(1)=ABS(Q2-Q3) NODE(2)=Q3 RETURN END C H E A P PACKAGE HPINIT 1 C A COLLECTION OF PROGRAMS WHICH MAINTAIN A HEAP DATA HPINIT 2 C STRUCTURE. BY CALLING THESE SUBROUTINES IT IS POSSIBLE TO HPINIT 3 C INSERT, DELETE, AND ACCESS AN EXISTING HEAP OR TO BUILD A HPINIT 4 C NEW HEAP FROM AN UNORDERED COLLECTION OF NODES. THE HEAP HPINIT 5 C FUNCTION IS AN ARGUMENT TO THE SUBROUTINES ALLOWING VERY HPINIT 6 C GENERAL ORGANIZATIONS. HPINIT 7 C THE USER MUST DECIDE ON THE MAXIMUM NUMBER OF NODES HPINIT 8 C ALLOWED AND DIMENSION THE REAL ARRAY DATA AND THE INTEGER HPINIT 9 C ARRAY T USED INTERNALLY BY THE PACKAGE. THESE VARIABLES ARE HPINIT10 C THEN PASSED THROUGH THE CALL SEQUENCE BETWEEN THE HEAP HPINIT11 C PROGRAMS BUT ARE NOT IN GENERAL ACCESSED BY THE USER. HE HPINIT12 C MUST ALSO PROVIDE A HEAP FUNCTION WHOSE NAME MUST BE INCLUD- HPINIT13 C ED IN AN EXTERNAL STATEMENT IN THE USER PROGRAM WHICH CALLS HPINIT14 C THE HEAP SUBROUTINES. TWO SIMPLE HEAP FUNCTIONS ARE HPINIT15 C PROVIDED WITH THE PACKAGE. HPINIT16 C HPINIT17 SUBROUTINE HPINIT(NMAX,N,T) HPINIT18 C C PURPOSE C THIS ROUTINE INITIALIZES THE HEAP PROGRAMS. C IT IS CALLED ONCE AT THE START OF EACH NEW CALCULATION C INPUT C NMAX = MAXIMUM NUMBER OF NODES ALLOWED BY USER. C OUTPUT C N = CURRENT NUMBER OF NODES IN HEAP = 0. C T = INTEGER ARRAY OF POINTERS TO POTENTIAL HEAP NODES. C INTEGER T(1) DO 1 I = 1, NMAX 1 T(I)=I N = 0 RETURN END SUBROUTINE HPINS(NMAX,NCHAR,DATA,N,T,NODE,HPFUN) HPINS 1 C C PURPOSE C THIS ROUTINE INSERTS A NODE INTO AN ALREADY EXISTING HEAP. C THE RESULTING TREE IS RE-HEAPED. C C INPUT C NMAX = MAXIMUM NUMBER OF NODES ALLOWED BY USER. C NCHAR = NUMBER OF WORDS PER NODE. C DATA = WORK AREA FOR STORING NODES. C N = CURRENT NUMBER OF NODES IN THE TREE. C T = INTEGER ARRAY OF POINTERS TO HEAP NODES. C NODE = A REAL ARRAY, NCHAR WORDS LONG, WHICH C CONTAINS THE NODAL INFORMATION TO BE INSERTED. C HPFUN = NAME OF USER WRITTEN FUNCTION TO DETERMINE C THE ROOT NODE. C OUTPUT C DATA = WORK AREA WITH NEW NODE INSERTED. C N = UPDATED NUMBER OF NODES. C T = UPDATED INTEGER POINTER ARRAY. C DIMENSION T(1),NODE(1),DATA(1) REAL NODE INTEGER T LOGICAL HPFUN IF(N .EQ. NMAX) RETURN N=N+1 J= (T(N)-1)*NCHAR DO 1 I= 1,NCHAR IPJ=I+J 1 DATA(IPJ) = NODE(I) J=N 2 CONTINUE IF(J .EQ. 1) RETURN JT=T(J) J2=J/2 JT2=T(J2) JL=(JT2-1)*NCHAR+1 JR=(JT-1)*NCHAR+1 IF(HPFUN(DATA(JL),DATA(JR),NCHAR)) RETURN T(J2)=T(J) T(J)=JT2 J=J/2 GO TO 2 END SUBROUTINE HPBLD(NMAX,NCHAR,DATA,NELTS,T,HPFUN) HPBLD 1 C C PURPOSE C BUILDS A HEAP, IN T , FROM AN ARRAY OF NELTS ELEMENTS C IN DATA, WHICH ARE SPACED NCHAR APART. C AT CONCLUSION OF CALCULATION THE ROOT SATISFIES C HPFUN(ROOT,SON) = .TRUE. FOR ANY SON. C USES SUBROUTINE HPGRO BY FEEDING IT ONE ELEMENT OF C THE ARRAY AT A TIME. C C INPUT C NMAX = MAXIMUN NUMBER OF NODES ALLOWED BY USER. C NCHAR = NUMBER OF WORDS PER NODE. C DATA = WORK AREA IN WHICH THE NODES ARE STORED. C NELTS = CURRENT NUMBER OF NODES. C T = INTEGER ARRAY OF POINTERS TO HEAP NODES. C HPFUN = NAME OF USER WRITTEN FUNCTION TO DETERMINE ROOT NODE. C OUTPUT C DATA = WORK AREA IN WHICH THE NODES ARE STORED. C T = INTEGER ARRAY OF POINTERS TO HEAP NODES. C IN PARTICULAR T(1) POINTS TO THE ROOT. C EXTERNAL HPFUN LOGICAL HPFUN DIMENSION DATA(1) INTEGER T(1) IF(NMAX .LT. NELTS) RETURN INDEX = NELTS/2 1 CONTINUE IF( INDEX .EQ. 0) RETURN CALL HPGRO(NMAX,NCHAR,DATA,NELTS,T,HPFUN,INDEX) INDEX = INDEX-1 GO TO 1 END SUBROUTINE HPDEL(NMAX,NCHAR,DATA,NCELLS,T,HPFUN) HPDEL 1 C C PURPOSE C DELETE ROOT ELEMENT OF HEAP. RESULTING TREE IS REHEAPED. C INPUT C NMAX = MAXIMUN NUMBER OF NODES ALLOWED BY USER. C NCHAR = NUMBER OF WORDS PER NODE. C DATA = WORK AREA IN WHICH THE NODES ARE STORED. C NCELLS = CURRENT NUMBER OF NODES. C T = INTEGER ARRAY OF POINTERS TO NODES. C HPFUN = NAME OF USER WRITTEN FUNCTION TO DETERMINE ROOT NODE. C OUTPUT C NCELLS = UPDATED NUMBER OF NODES. C T = UPDATED INTEGER POINTER ARRAY TO NODES. C EXTERNAL HPFUN LOGICAL HPFUN DIMENSION DATA(1) INTEGER T(1) IF(NCELLS .EQ. 0) RETURN JUNK=T(1) T(1)=T(NCELLS) T(NCELLS)=JUNK NCELLS=NCELLS-1 CALL HPGRO(NMAX,NCHAR,DATA,NCELLS,T,HPFUN,1) RETURN END SUBROUTINE HPACC(NMAX,NCHAR,DATA,N,T,NODE,K) HPACC 1 C C PURPOSE C TO ACCESS THE K-TH NODE OF THE HEAP, C 1 .LE. K .LE. N .LE. NMAX C INPUT C NMAX = MAXIMUM NUMBER OF NODES ALLOWED BY USER. C DATA = WORK AREA FOR STORING NODES. C N = CURRENT NUMBER OF NODES IN THE HEAP. C T = INTEGER ARRAY OF POINTERS TO HEAP NODES. C NODE = A REAL ARRAY, NCHAR WORDS LONG, IN WHICH NODAL IN- C FORMATION WILL BE INSERTED. C K = THE INDEX OF THE NODE TO BE FOUND AND INSERTED INTO NODE. C C OUTPUT C NODE = A REAL ARRAY. CONTAINS IN NODE(1),...,NODE(NCHAR) C THE ELEMENTS OF THE K-TH NODE. C REAL DATA(1), NODE(1) INTEGER T(1) IF (K .LT. 1 .OR. K .GT. N .OR. N .GT. NMAX) RETURN J=(T(K)-1)*NCHAR DO 1 I=1,NCHAR IPJ=I+J 1 NODE(I)=DATA(IPJ) RETURN END LOGICAL FUNCTION GREATR(A,B,NCHAR) GREATR 1 REAL A(1),B(1) GREATR= A(1) .GT. B(1) RETURN END LOGICAL FUNCTION LESS(A,B,NCHAR) LESS 1 REAL A(1),B(1) LESS= A(1) .LT. B(1) RETURN END SUBROUTINE HPGRO(NMAX,KD,DATA,NELTS,T,HPFUN,KTEMP) HPGRO 1 C C PURPOSE C FORMS A HEAP OUT OF A TREE. USED PRIVATELY BY HPBLD. C THE ROOT OF THE TREE IS STORED IN LOCATION T(KTEMP). C FIRST SON IS IN LOCATION T(2KTEMP), NEXT SON C IS IN LOCATION T(2KTEMP+1). C THIS PROGRAM ASSUMES EACH BRANCH OF THE TREE IS A HEAP. C DIMENSION T(1),DATA(1) INTEGER T LOGICAL HPFUN IF(NELTS .GT. NMAX) RETURN C K=KTEMP 1 I=2*K C C TEST IF ELEMENT IN I TH POSITION IS A LEAF. C IF( I .GT. NELTS ) RETURN C C IF THERE IS MORE THAN ONE SON, FIND WHICH SON IS SMALLEST. C IF( I .EQ. NELTS ) GO TO 2 ITEMP=T(I) ITP1=T(I+1) IL=(ITP1-1)*KD+1 IR=(ITEMP-1)*KD+1 IF(HPFUN(DATA(IL),DATA(IR),KD)) I=I+1 C C IF A SON IS LARGER THAN FATHER, INTERCHANGE C THIS DESTROYS HEAP PROPERTY, SO MUST RE-HEAP REMAINING C ELEMENTS C 2 CONTINUE KT=T(K) ITEMP=T(I) IL=(KT-1)*KD+1 IR=(ITEMP-1)*KD+1 IF(HPFUN(DATA(IL),DATA(IR),KD)) RETURN ITEMP=T(I) T(I)=T(K) T(K)=ITEMP K=I GO TO 1 END .