GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
droots.f
Go to the documentation of this file.
1 SUBROUTINE droots (NG, HMIN, JFLAG, X0, X1, G0, G1, GX, X, JROOT,
2 * IMAX, LAST, ALPHA, X2)
3C
4C***BEGIN PROLOGUE DROOTS
5C***REFER TO DDASRT
6C***ROUTINES CALLED DCOPY
7C***DATE WRITTEN 821001 (YYMMDD)
8C***REVISION DATE 900926 (YYMMDD)
9C***END PROLOGUE DROOTS
10C
11 IMPLICIT DOUBLE PRECISION(a-h,o-z)
12 INTEGER NG, JFLAG, JROOT, IMAX, LAST
13 DOUBLE PRECISION HMIN, X0, X1, G0, G1, GX, X, ALPHA, X2
14 dimension g0(ng), g1(ng), gx(ng), jroot(ng)
15C-----------------------------------------------------------------------
16C THIS SUBROUTINE FINDS THE LEFTMOST ROOT OF A SET OF ARBITRARY
17C FUNCTIONS GI(X) (I = 1,...,NG) IN AN INTERVAL (X0,X1). ONLY ROOTS
18C OF ODD MULTIPLICITY (I.E. CHANGES OF SIGN OF THE GI) ARE FOUND.
19C HERE THE SIGN OF X1 - X0 IS ARBITRARY, BUT IS CONSTANT FOR A GIVEN
20C PROBLEM, AND -LEFTMOST- MEANS NEAREST TO X0.
21C THE VALUES OF THE VECTOR-VALUED FUNCTION G(X) = (GI, I=1...NG)
22C ARE COMMUNICATED THROUGH THE CALL SEQUENCE OF DROOTS.
23C THE METHOD USED IS THE ILLINOIS ALGORITHM.
24C
25C REFERENCE..
26C KATHIE L. HIEBERT AND LAWRENCE F. SHAMPINE, IMPLICITLY DEFINED
27C OUTPUT POINTS FOR SOLUTIONS OF ODE-S, SANDIA REPORT SAND80-0180,
28C FEBRUARY, 1980.
29C
30C DESCRIPTION OF PARAMETERS.
31C
32C NG = NUMBER OF FUNCTIONS GI, OR THE NUMBER OF COMPONENTS OF
33C THE VECTOR VALUED FUNCTION G(X). INPUT ONLY.
34C
35C HMIN = RESOLUTION PARAMETER IN X. INPUT ONLY. WHEN A ROOT IS
36C FOUND, IT IS LOCATED ONLY TO WITHIN AN ERROR OF HMIN IN X.
37C TYPICALLY, HMIN SHOULD BE SET TO SOMETHING ON THE ORDER OF
38C 100 * UROUND * MAX(ABS(X0),ABS(X1)),
39C WHERE UROUND IS THE UNIT ROUNDOFF OF THE MACHINE.
40C
41C JFLAG = INTEGER FLAG FOR INPUT AND OUTPUT COMMUNICATION.
42C
43C ON INPUT, SET JFLAG = 0 ON THE FIRST CALL FOR THE PROBLEM,
44C AND LEAVE IT UNCHANGED UNTIL THE PROBLEM IS COMPLETED.
45C (THE PROBLEM IS COMPLETED WHEN JFLAG .GE. 2 ON RETURN.)
46C
47C ON OUTPUT, JFLAG HAS THE FOLLOWING VALUES AND MEANINGS..
48C JFLAG = 1 MEANS DROOTS NEEDS A VALUE OF G(X). SET GX = G(X)
49C AND CALL DROOTS AGAIN.
50C JFLAG = 2 MEANS A ROOT HAS BEEN FOUND. THE ROOT IS
51C AT X, AND GX CONTAINS G(X). (ACTUALLY, X IS THE
52C RIGHTMOST APPROXIMATION TO THE ROOT ON AN INTERVAL
53C (X0,X1) OF SIZE HMIN OR LESS.)
54C JFLAG = 3 MEANS X = X1 IS A ROOT, WITH ONE OR MORE OF THE GI
55C BEING ZERO AT X1 AND NO SIGN CHANGES IN (X0,X1).
56C GX CONTAINS G(X) ON OUTPUT.
57C JFLAG = 4 MEANS NO ROOTS (OF ODD MULTIPLICITY) WERE
58C FOUND IN (X0,X1) (NO SIGN CHANGES).
59C
60C X0,X1 = ENDPOINTS OF THE INTERVAL WHERE ROOTS ARE SOUGHT.
61C X1 AND X0 ARE INPUT WHEN JFLAG = 0 (FIRST CALL), AND
62C MUST BE LEFT UNCHANGED BETWEEN CALLS UNTIL THE PROBLEM IS
63C COMPLETED. X0 AND X1 MUST BE DISTINCT, BUT X1 - X0 MAY BE
64C OF EITHER SIGN. HOWEVER, THE NOTION OF -LEFT- AND -RIGHT-
65C WILL BE USED TO MEAN NEARER TO X0 OR X1, RESPECTIVELY.
66C WHEN JFLAG .GE. 2 ON RETURN, X0 AND X1 ARE OUTPUT, AND
67C ARE THE ENDPOINTS OF THE RELEVANT INTERVAL.
68C
69C G0,G1 = ARRAYS OF LENGTH NG CONTAINING THE VECTORS G(X0) AND G(X1),
70C RESPECTIVELY. WHEN JFLAG = 0, G0 AND G1 ARE INPUT AND
71C NONE OF THE G0(I) SHOULD BE BE ZERO.
72C WHEN JFLAG .GE. 2 ON RETURN, G0 AND G1 ARE OUTPUT.
73C
74C GX = ARRAY OF LENGTH NG CONTAINING G(X). GX IS INPUT
75C WHEN JFLAG = 1, AND OUTPUT WHEN JFLAG .GE. 2.
76C
77C X = INDEPENDENT VARIABLE VALUE. OUTPUT ONLY.
78C WHEN JFLAG = 1 ON OUTPUT, X IS THE POINT AT WHICH G(X)
79C IS TO BE EVALUATED AND LOADED INTO GX.
80C WHEN JFLAG = 2 OR 3, X IS THE ROOT.
81C WHEN JFLAG = 4, X IS THE RIGHT ENDPOINT OF THE INTERVAL, X1.
82C
83C JROOT = INTEGER ARRAY OF LENGTH NG. OUTPUT ONLY.
84C WHEN JFLAG = 2 OR 3, JROOT INDICATES WHICH COMPONENTS
85C OF G(X) HAVE A ROOT AT X. JROOT(I) IS 1 IF THE I-TH
86C COMPONENT HAS A ROOT, AND JROOT(I) = 0 OTHERWISE.
87C
88C IMAX, LAST, ALPHA, X2 =
89C BOOKKEEPING VARIABLES WHICH MUST BE SAVED FROM CALL
90C TO CALL. THEY ARE SAVED INSIDE THE CALLING ROUTINE,
91C BUT THEY ARE USED ONLY WITHIN THIS ROUTINE.
92C-----------------------------------------------------------------------
93 INTEGER I, IMXOLD, NXLAST
94 DOUBLE PRECISION T2, TMAX, ZERO
95 LOGICAL ZROOT, SGNCHG, XROOT
96 DATA zero/0.0d0/
97C
98 IF (jflag .EQ. 1) GO TO 200
99C JFLAG .NE. 1. CHECK FOR CHANGE IN SIGN OF G OR ZERO AT X1. ----------
100 imax = 0
101 tmax = zero
102 zroot = .false.
103 DO 120 i = 1,ng
104 IF (dabs(g1(i)) .GT. zero) GO TO 110
105 zroot = .true.
106 GO TO 120
107C AT THIS POINT, G0(I) HAS BEEN CHECKED AND CANNOT BE ZERO. ------------
108 110 IF (dsign(1.0d0,g0(i)) .EQ. dsign(1.0d0,g1(i))) GO TO 120
109 t2 = dabs(g1(i)/(g1(i)-g0(i)))
110 IF (t2 .LE. tmax) GO TO 120
111 tmax = t2
112 imax = i
113 120 CONTINUE
114 IF (imax .GT. 0) GO TO 130
115 sgnchg = .false.
116 GO TO 140
117 130 sgnchg = .true.
118 140 IF (.NOT. sgnchg) GO TO 400
119C THERE IS A SIGN CHANGE. FIND THE FIRST ROOT IN THE INTERVAL. --------
120 xroot = .false.
121 nxlast = 0
122 last = 1
123C
124C REPEAT UNTIL THE FIRST ROOT IN THE INTERVAL IS FOUND. LOOP POINT. ---
125 150 CONTINUE
126 IF (xroot) GO TO 300
127 IF (nxlast .EQ. last) GO TO 160
128 alpha = 1.0d0
129 GO TO 180
130 160 IF (last .EQ. 0) GO TO 170
131 alpha = 0.5d0*alpha
132 GO TO 180
133 170 alpha = 2.0d0*alpha
134 180 x2 = x1 - (x1-x0)*g1(imax)/(g1(imax) - alpha*g0(imax))
135 IF ((dabs(x2-x0) .LT. hmin) .AND.
136 1 (dabs(x1-x0) .GT. 10.0d0*hmin)) x2 = x0 + 0.1d0*(x1-x0)
137 jflag = 1
138 x = x2
139C RETURN TO THE CALLING ROUTINE TO GET A VALUE OF GX = G(X). -----------
140 RETURN
141C CHECK TO SEE IN WHICH INTERVAL G CHANGES SIGN. -----------------------
142 200 imxold = imax
143 imax = 0
144 tmax = zero
145 zroot = .false.
146 DO 220 i = 1,ng
147 IF (dabs(gx(i)) .GT. zero) GO TO 210
148 zroot = .true.
149 GO TO 220
150C NEITHER G0(I) NOR GX(I) CAN BE ZERO AT THIS POINT. -------------------
151 210 IF (dsign(1.0d0,g0(i)) .EQ. dsign(1.0d0,gx(i))) GO TO 220
152 t2 = dabs(gx(i)/(gx(i) - g0(i)))
153 IF (t2 .LE. tmax) GO TO 220
154 tmax = t2
155 imax = i
156 220 CONTINUE
157 IF (imax .GT. 0) GO TO 230
158 sgnchg = .false.
159 imax = imxold
160 GO TO 240
161 230 sgnchg = .true.
162 240 nxlast = last
163 IF (.NOT. sgnchg) GO TO 250
164C SIGN CHANGE BETWEEN X0 AND X2, SO REPLACE X1 WITH X2. ----------------
165 x1 = x2
166 CALL dcopy (ng, gx, 1, g1, 1)
167 last = 1
168 xroot = .false.
169 GO TO 270
170 250 IF (.NOT. zroot) GO TO 260
171C ZERO VALUE AT X2 AND NO SIGN CHANGE IN (X0,X2), SO X2 IS A ROOT. -----
172 x1 = x2
173 CALL dcopy (ng, gx, 1, g1, 1)
174 xroot = .true.
175 GO TO 270
176C NO SIGN CHANGE BETWEEN X0 AND X2. REPLACE X0 WITH X2. ---------------
177 260 CONTINUE
178 CALL dcopy (ng, gx, 1, g0, 1)
179 x0 = x2
180 last = 0
181 xroot = .false.
182 270 IF (dabs(x1-x0) .LE. hmin) xroot = .true.
183 GO TO 150
184C
185C RETURN WITH X1 AS THE ROOT. SET JROOT. SET X = X1 AND GX = G1. -----
186 300 jflag = 2
187 x = x1
188 CALL dcopy (ng, g1, 1, gx, 1)
189 DO 320 i = 1,ng
190 jroot(i) = 0
191 IF (dabs(g1(i)) .GT. zero) GO TO 310
192 jroot(i) = 1
193 GO TO 320
194 310 IF (dsign(1.0d0,g0(i)) .NE. dsign(1.0d0,g1(i))) jroot(i) = 1
195 320 CONTINUE
196 RETURN
197C
198C NO SIGN CHANGE IN THE INTERVAL. CHECK FOR ZERO AT RIGHT ENDPOINT. ---
199 400 IF (.NOT. zroot) GO TO 420
200C
201C ZERO VALUE AT X1 AND NO SIGN CHANGE IN (X0,X1). RETURN JFLAG = 3. ---
202 x = x1
203 CALL dcopy (ng, g1, 1, gx, 1)
204 DO 410 i = 1,ng
205 jroot(i) = 0
206 IF (dabs(g1(i)) .LE. zero) jroot(i) = 1
207 410 CONTINUE
208 jflag = 3
209 RETURN
210C
211C NO SIGN CHANGES IN THIS INTERVAL. SET X = X1, RETURN JFLAG = 4. -----
212 420 CALL dcopy (ng, g1, 1, gx, 1)
213 x = x1
214 jflag = 4
215 RETURN
216C---------------------- END OF SUBROUTINE DROOTS -----------------------
217 END
subroutine droots(ng, hmin, jflag, x0, x1, g0, g1, gx, x, jroot, imax, last, alpha, x2)
Definition droots.f:3