* * $Id: funzer.F,v 1.1.1.1 1996/04/01 15:02:57 mclareni Exp $ * * $Log: funzer.F,v $ * Revision 1.1.1.1 1996/04/01 15:02:57 mclareni * Mathlib gen * * #include "gen/pilot.h" SUBROUTINE FUNZER(FUNC,X2LOW,X2HIGH,XLOW,XHIGH) C FIND RANGE WHERE FUNC IS NON-ZERO. C WRITTEN 1980, F. JAMES C MODIFIED, NOV. 1985, TO FIX BUG AND GENERALIZE C TO FIND SIMPLY-CONNECTED NON-ZERO REGION (XLOW,XHIGH) C ANYWHERE WITHIN THE GIVEN REGION (X2LOW,H2HIGH). C WHERE 'ANYWHERE' MEANS EITHER AT THE LOWER OR UPPER C EDGE OF THE GIVEN REGION, OR, IF IN THE MIDDLE, C COVERING AT LEAST 1% OF THE GIVEN REGION. C OTHERWISE IT IS NOT GUARANTEED TO FIND THE NON-ZERO REGION. C IF FUNCTION EVERYWHERE ZERO, FUNZER SETS XLOW=XHIGH=0. EXTERNAL FUNC XLOW = X2LOW XHIGH = X2HIGH C FIND OUT IF FUNCTION IS ZERO AT ONE END OR BOTH XMID = XLOW IF (FUNC(XLOW) .GT. 0.) GO TO 120 XMID = XHIGH IF (FUNC(XHIGH) .GT. 0.) GO TO 50 C FUNCTION IS ZERO AT BOTH ENDS, C LOOK FOR PLACE WHERE IT IS NON-ZERO. DO 30 LOGN= 1, 7 NSLICE = 2**LOGN DO 20 I= 1, NSLICE, 2 XMID = XLOW + I * (XHIGH-XLOW) / NSLICE IF (FUNC(XMID) .GT. 0.) GO TO 50 20 CONTINUE 30 CONTINUE C FALLING THROUGH LOOP MEANS CANNOT FIND NON-ZERO VALUE WRITE(6,554) WRITE(6,555) XLOW, XHIGH XLOW = 0. XHIGH = 0. GO TO 220 C 50 CONTINUE C DELETE 'LEADING' ZERO RANGE XH = XMID XL = XLOW DO 70 K= 1, 20 XNEW = 0.5*(XH+XL) IF (FUNC(XNEW) .EQ. 0.) GO TO 68 XH = XNEW GO TO 70 68 XL = XNEW 70 CONTINUE XLOW = XL WRITE(6,555) X2LOW,XLOW 120 CONTINUE IF (FUNC(XHIGH) .GT. 0.) GO TO 220 C DELETE 'TRAILING' RANGE OF ZEROES XL = XMID XH = XHIGH DO 170 K= 1, 20 XNEW = 0.5*(XH+XL) IF (FUNC(XNEW) .EQ. 0.) GO TO 168 XL = XNEW GO TO 170 168 XH = XNEW 170 CONTINUE XHIGH = XH WRITE(6,555) XHIGH, X2HIGH C 220 CONTINUE RETURN 554 FORMAT('0CANNOT FIND NON-ZERO FUNCTION VALUE') 555 FORMAT(' FUNCTION IS ZERO FROM X=',E12.5,' TO ',E12.5) END