2 SUBROUTINE DROOTS
(NG
, HMIN
, JFLAG
, X0
, X1
, G0
, G1
, GX
, X
, JROOT
)
3 INTEGER NG
, JFLAG
, JROOT
4 DOUBLE PRECISION HMIN
, X0
, X1
, G0
, G1
, GX
, X
5 DIMENSION G0
(NG
), G1
(NG
), GX
(NG
), JROOT
(NG
)
6 INTEGER IOWND3
, IMAX
, LAST
, IDUM3
7 DOUBLE PRECISION ALPHA
, X2
, RDUM3
8 COMMON /DLSR01
/ ALPHA
, X2
, RDUM3
(3),
9 1 IOWND3
(3), IMAX
, LAST
, IDUM3
(4)
10 C-----------------------------------------------------------------------
11 C This subroutine finds the leftmost root of a set of arbitrary
12 C functions gi(x) (i = 1,...,NG) in an interval (X0,X1). Only roots
13 C of odd multiplicity (i.e. changes of sign of the gi) are found.
14 C Here the sign of X1 - X0 is arbitrary, but is constant for a given
15 C problem, and -leftmost- means nearest to X0.
16 C The values of the vector-valued function g(x) = (gi, i=1...NG)
17 C are communicated through the call sequence of DROOTS.
18 C The method used is the Illinois algorithm.
21 C Kathie L. Hiebert and Lawrence F. Shampine, Implicitly Defined
22 C Output Points for Solutions of ODEs, Sandia Report SAND80-0180,
25 C Description of parameters.
27 C NG = number of functions gi, or the number of components of
28 C the vector valued function g(x). Input only.
30 C HMIN = resolution parameter in X. Input only. When a root is
31 C found, it is located only to within an error of HMIN in X.
32 C Typically, HMIN should be set to something on the order of
33 C 100 * UROUND * MAX(ABS(X0),ABS(X1)),
34 C where UROUND is the unit roundoff of the machine.
36 C JFLAG = integer flag for input and output communication.
38 C On input, set JFLAG = 0 on the first call for the problem,
39 C and leave it unchanged until the problem is completed.
40 C (The problem is completed when JFLAG .ge. 2 on return.)
42 C On output, JFLAG has the following values and meanings:
43 C JFLAG = 1 means DROOTS needs a value of g(x). Set GX = g(X)
44 C and call DROOTS again.
45 C JFLAG = 2 means a root has been found. The root is
46 C at X, and GX contains g(X). (Actually, X is the
47 C rightmost approximation to the root on an interval
48 C (X0,X1) of size HMIN or less.)
49 C JFLAG = 3 means X = X1 is a root, with one or more of the gi
50 C being zero at X1 and no sign changes in (X0,X1).
51 C GX contains g(X) on output.
52 C JFLAG = 4 means no roots (of odd multiplicity) were
53 C found in (X0,X1) (no sign changes).
55 C X0,X1 = endpoints of the interval where roots are sought.
56 C X1 and X0 are input when JFLAG = 0 (first call), and
57 C must be left unchanged between calls until the problem is
58 C completed. X0 and X1 must be distinct, but X1 - X0 may be
59 C of either sign. However, the notion of -left- and -right-
60 C will be used to mean nearer to X0 or X1, respectively.
61 C When JFLAG .ge. 2 on return, X0 and X1 are output, and
62 C are the endpoints of the relevant interval.
64 C G0,G1 = arrays of length NG containing the vectors g(X0) and g(X1),
65 C respectively. When JFLAG = 0, G0 and G1 are input and
66 C none of the G0(i) should be zero.
67 C When JFLAG .ge. 2 on return, G0 and G1 are output.
69 C GX = array of length NG containing g(X). GX is input
70 C when JFLAG = 1, and output when JFLAG .ge. 2.
72 C X = independent variable value. Output only.
73 C When JFLAG = 1 on output, X is the point at which g(x)
74 C is to be evaluated and loaded into GX.
75 C When JFLAG = 2 or 3, X is the root.
76 C When JFLAG = 4, X is the right endpoint of the interval, X1.
78 C JROOT = integer array of length NG. Output only.
79 C When JFLAG = 2 or 3, JROOT indicates which components
80 C of g(x) have a root at X. JROOT(i) is 1 if the i-th
81 C component has a root, and JROOT(i) = 0 otherwise.
82 C-----------------------------------------------------------------------
83 INTEGER I
, IMXOLD
, NXLAST
84 DOUBLE PRECISION T2
, TMAX
, ZERO
85 LOGICAL ZROOT
, SGNCHG
, XROOT
89 IF (JFLAG
.EQ
. 1) GO TO 200
90 C JFLAG .ne. 1. Check for change in sign of g or zero at X1. ----------
95 IF (ABS
(G1
(I
)) .GT
. ZERO
) GO TO 110
98 C At this point, G0(i) has been checked and cannot be zero. ------------
99 110 IF (SIGN
(1.0D0
,G0
(I
)) .EQ
. SIGN
(1.0D0
,G1
(I
))) GO TO 120
100 T2
= ABS
(G1
(I
)/(G1
(I
)-G0
(I
)))
101 IF (T2
.LE
. TMAX
) GO TO 120
105 IF (IMAX
.GT
. 0) GO TO 130
109 140 IF (.NOT
. SGNCHG
) GO TO 400
110 C There is a sign change. Find the first root in the interval. --------
115 C Repeat until the first root in the interval is found. Loop point. ---
118 IF (NXLAST
.EQ
. LAST
) GO TO 160
121 160 IF (LAST
.EQ
. 0) GO TO 170
124 170 ALPHA
= 2.0D0*ALPHA
125 180 X2
= X1
- (X1
-X0
)*G1
(IMAX
)/(G1
(IMAX
) - ALPHA*G0
(IMAX
))
126 IF ((ABS
(X2
-X0
) .LT
. HMIN
) .AND
.
127 1 (ABS
(X1
-X0
) .GT
. 10.0D0*HMIN
)) X2
= X0
+ 0.1D0*
(X1
-X0
)
130 C Return to the calling routine to get a value of GX = g(X). -----------
132 C Check to see in which interval g changes sign. -----------------------
138 IF (ABS
(GX
(I
)) .GT
. ZERO
) GO TO 210
141 C Neither G0(i) nor GX(i) can be zero at this point. -------------------
142 210 IF (SIGN
(1.0D0
,G0
(I
)) .EQ
. SIGN
(1.0D0
,GX
(I
))) GO TO 220
143 T2
= ABS
(GX
(I
)/(GX
(I
) - G0
(I
)))
144 IF (T2
.LE
. TMAX
) GO TO 220
148 IF (IMAX
.GT
. 0) GO TO 230
154 IF (.NOT
. SGNCHG
) GO TO 250
155 C Sign change between X0 and X2, so replace X1 with X2. ----------------
157 CALL DCOPY
(NG
, GX
, 1, G1
, 1)
161 250 IF (.NOT
. ZROOT
) GO TO 260
162 C Zero value at X2 and no sign change in (X0,X2), so X2 is a root. -----
164 CALL DCOPY
(NG
, GX
, 1, G1
, 1)
167 C No sign change between X0 and X2. Replace X0 with X2. ---------------
169 CALL DCOPY
(NG
, GX
, 1, G0
, 1)
173 270 IF (ABS
(X1
-X0
) .LE
. HMIN
) XROOT
= .TRUE
.
176 C Return with X1 as the root. Set JROOT. Set X = X1 and GX = G1. -----
179 CALL DCOPY
(NG
, G1
, 1, GX
, 1)
182 IF (ABS
(G1
(I
)) .GT
. ZERO
) GO TO 310
185 310 IF (SIGN
(1.0D0
,G0
(I
)) .NE
. SIGN
(1.0D0
,G1
(I
))) JROOT
(I
) = 1
189 C No sign change in the interval. Check for zero at right endpoint. ---
190 400 IF (.NOT
. ZROOT
) GO TO 420
192 C Zero value at X1 and no sign change in (X0,X1). Return JFLAG = 3. ---
194 CALL DCOPY
(NG
, G1
, 1, GX
, 1)
197 IF (ABS
(G1
(I
)) .LE
. ZERO
) JROOT
(I
) = 1
202 C No sign changes in this interval. Set X = X1, return JFLAG = 4. -----
203 420 CALL DCOPY
(NG
, G1
, 1, GX
, 1)
207 C----------------------- End of Subroutine DROOTS ----------------------