~ubuntu-branches/ubuntu/karmic/python-scipy/karmic

« back to all changes in this revision

Viewing changes to Lib/special/cdflib/dinvr.f

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T. Chen (new)
  • Date: 2005-03-16 02:15:29 UTC
  • Revision ID: james.westby@ubuntu.com-20050316021529-xrjlowsejs0cijig
Tags: upstream-0.3.2
ImportĀ upstreamĀ versionĀ 0.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
      SUBROUTINE dinvr(status,x,fx,qleft,qhi)
 
2
C**********************************************************************
 
3
C
 
4
C     SUBROUTINE DINVR(STATUS, X, FX, QLEFT, QHI)
 
5
C          Double precision
 
6
C          bounds the zero of the function and invokes zror
 
7
C                    Reverse Communication
 
8
C
 
9
C
 
10
C                              Function
 
11
C
 
12
C
 
13
C     Bounds the    function  and  invokes  ZROR   to perform the   zero
 
14
C     finding.  STINVR  must  have   been  called  before this   routine
 
15
C     in order to set its parameters.
 
16
C
 
17
C
 
18
C                              Arguments
 
19
C
 
20
C
 
21
C     STATUS <--> At the beginning of a zero finding problem, STATUS
 
22
C                 should be set to 0 and INVR invoked.  (The value
 
23
C                 of parameters other than X will be ignored on this cal
 
24
C
 
25
C                 When INVR needs the function evaluated, it will set
 
26
C                 STATUS to 1 and return.  The value of the function
 
27
C                 should be set in FX and INVR again called without
 
28
C                 changing any of its other parameters.
 
29
C
 
30
C                 When INVR has finished without error, it will return
 
31
C                 with STATUS 0.  In that case X is approximately a root
 
32
C                 of F(X).
 
33
C
 
34
C                 If INVR cannot bound the function, it returns status
 
35
C                 -1 and sets QLEFT and QHI.
 
36
C                         INTEGER STATUS
 
37
C
 
38
C     X <-- The value of X at which F(X) is to be evaluated.
 
39
C                         DOUBLE PRECISION X
 
40
C
 
41
C     FX --> The value of F(X) calculated when INVR returns with
 
42
C            STATUS = 1.
 
43
C                         DOUBLE PRECISION FX
 
44
C
 
45
C     QLEFT <-- Defined only if QMFINV returns .FALSE.  In that
 
46
C          case it is .TRUE. If the stepping search terminated
 
47
C          unsucessfully at SMALL.  If it is .FALSE. the search
 
48
C          terminated unsucessfully at BIG.
 
49
C                    QLEFT is LOGICAL
 
50
C
 
51
C     QHI <-- Defined only if QMFINV returns .FALSE.  In that
 
52
C          case it is .TRUE. if F(X) .GT. Y at the termination
 
53
C          of the search and .FALSE. if F(X) .LT. Y at the
 
54
C          termination of the search.
 
55
C                    QHI is LOGICAL
 
56
 
 
57
C
 
58
C**********************************************************************
 
59
C     .. Scalar Arguments ..
 
60
      DOUBLE PRECISION fx,x,zabsst,zabsto,zbig,zrelst,zrelto,zsmall,
 
61
     +                 zstpmu
 
62
      INTEGER status
 
63
      LOGICAL qhi,qleft
 
64
C     ..
 
65
C     .. Local Scalars ..
 
66
      DOUBLE PRECISION absstp,abstol,big,fbig,fsmall,relstp,reltol,
 
67
     +                 small,step,stpmul,xhi,xlb,xlo,xsave,xub,yy,zx,zy,
 
68
     +                 zz
 
69
      INTEGER i99999
 
70
      LOGICAL qbdd,qcond,qdum1,qdum2,qincr,qlim,qok,qup
 
71
C     ..
 
72
C     .. External Subroutines ..
 
73
      EXTERNAL dstzr,dzror
 
74
C     ..
 
75
C     .. Intrinsic Functions ..
 
76
      INTRINSIC abs,max,min
 
77
C     ..
 
78
C     .. Statement Functions ..
 
79
      LOGICAL qxmon
 
80
C     ..
 
81
C     .. Save statement ..
 
82
      SAVE
 
83
C     ..
 
84
C     .. Statement Function definitions ..
 
85
      qxmon(zx,zy,zz) = zx .LE. zy .AND. zy .LE. zz
 
86
C     ..
 
87
C     .. Executable Statements ..
 
88
 
 
89
      IF (status.GT.0) GO TO 310
 
90
 
 
91
      qcond = .NOT. qxmon(small,x,big)
 
92
      IF (qcond) STOP ' SMALL, X, BIG not monotone in INVR'
 
93
      xsave = x
 
94
C
 
95
C     See that SMALL and BIG bound the zero and set QINCR
 
96
C
 
97
      x = small
 
98
C     GET-FUNCTION-VALUE
 
99
      ASSIGN 10 TO i99999
 
100
      GO TO 300
 
101
 
 
102
   10 fsmall = fx
 
103
      x = big
 
104
C     GET-FUNCTION-VALUE
 
105
      ASSIGN 20 TO i99999
 
106
      GO TO 300
 
107
 
 
108
   20 fbig = fx
 
109
      qincr = fbig .GT. fsmall
 
110
      IF (.NOT. (qincr)) GO TO 50
 
111
      IF (fsmall.LE.0.0D0) GO TO 30
 
112
      status = -1
 
113
      qleft = .TRUE.
 
114
      qhi = .TRUE.
 
115
      RETURN
 
116
 
 
117
   30 IF (fbig.GE.0.0D0) GO TO 40
 
118
      status = -1
 
119
      qleft = .FALSE.
 
120
      qhi = .FALSE.
 
121
      RETURN
 
122
 
 
123
   40 GO TO 80
 
124
 
 
125
   50 IF (fsmall.GE.0.0D0) GO TO 60
 
126
      status = -1
 
127
      qleft = .TRUE.
 
128
      qhi = .FALSE.
 
129
      RETURN
 
130
 
 
131
   60 IF (fbig.LE.0.0D0) GO TO 70
 
132
      status = -1
 
133
      qleft = .FALSE.
 
134
      qhi = .TRUE.
 
135
      RETURN
 
136
 
 
137
   70 CONTINUE
 
138
   80 x = xsave
 
139
      step = max(absstp,relstp*abs(x))
 
140
C      YY = F(X) - Y
 
141
C     GET-FUNCTION-VALUE
 
142
      ASSIGN 90 TO i99999
 
143
      GO TO 300
 
144
 
 
145
   90 yy = fx
 
146
      IF (.NOT. (yy.EQ.0.0D0)) GO TO 100
 
147
      status = 0
 
148
      qok = .TRUE.
 
149
      RETURN
 
150
 
 
151
  100 qup = (qincr .AND. (yy.LT.0.0D0)) .OR.
 
152
     +      (.NOT.qincr .AND. (yy.GT.0.0D0))
 
153
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
154
C
 
155
C     HANDLE CASE IN WHICH WE MUST STEP HIGHER
 
156
C
 
157
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
158
      IF (.NOT. (qup)) GO TO 170
 
159
      xlb = xsave
 
160
      xub = min(xlb+step,big)
 
161
      GO TO 120
 
162
 
 
163
  110 IF (qcond) GO TO 150
 
164
C      YY = F(XUB) - Y
 
165
  120 x = xub
 
166
C     GET-FUNCTION-VALUE
 
167
      ASSIGN 130 TO i99999
 
168
      GO TO 300
 
169
 
 
170
  130 yy = fx
 
171
      qbdd = (qincr .AND. (yy.GE.0.0D0)) .OR.
 
172
     +       (.NOT.qincr .AND. (yy.LE.0.0D0))
 
173
      qlim = xub .GE. big
 
174
      qcond = qbdd .OR. qlim
 
175
      IF (qcond) GO TO 140
 
176
      step = stpmul*step
 
177
      xlb = xub
 
178
      xub = min(xlb+step,big)
 
179
  140 GO TO 110
 
180
 
 
181
  150 IF (.NOT. (qlim.AND..NOT.qbdd)) GO TO 160
 
182
      status = -1
 
183
      qleft = .FALSE.
 
184
      qhi = .NOT. qincr
 
185
      x = big
 
186
      RETURN
 
187
 
 
188
  160 GO TO 240
 
189
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
190
C
 
191
C     HANDLE CASE IN WHICH WE MUST STEP LOWER
 
192
C
 
193
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
194
  170 xub = xsave
 
195
      xlb = max(xub-step,small)
 
196
      GO TO 190
 
197
 
 
198
  180 IF (qcond) GO TO 220
 
199
C      YY = F(XLB) - Y
 
200
  190 x = xlb
 
201
C     GET-FUNCTION-VALUE
 
202
      ASSIGN 200 TO i99999
 
203
      GO TO 300
 
204
 
 
205
  200 yy = fx
 
206
      qbdd = (qincr .AND. (yy.LE.0.0D0)) .OR.
 
207
     +       (.NOT.qincr .AND. (yy.GE.0.0D0))
 
208
      qlim = xlb .LE. small
 
209
      qcond = qbdd .OR. qlim
 
210
      IF (qcond) GO TO 210
 
211
      step = stpmul*step
 
212
      xub = xlb
 
213
      xlb = max(xub-step,small)
 
214
  210 GO TO 180
 
215
 
 
216
  220 IF (.NOT. (qlim.AND..NOT.qbdd)) GO TO 230
 
217
      status = -1
 
218
      qleft = .TRUE.
 
219
      qhi = qincr
 
220
      x = small
 
221
      RETURN
 
222
 
 
223
  230 CONTINUE
 
224
  240 CALL dstzr(xlb,xub,abstol,reltol)
 
225
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
226
C
 
227
C     IF WE REACH HERE, XLB AND XUB BOUND THE ZERO OF F.
 
228
C
 
229
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
230
      status = 0
 
231
      GO TO 260
 
232
 
 
233
  250 IF (.NOT. (status.EQ.1)) GO TO 290
 
234
  260 CALL dzror(status,x,fx,xlo,xhi,qdum1,qdum2)
 
235
      IF (.NOT. (status.EQ.1)) GO TO 280
 
236
C     GET-FUNCTION-VALUE
 
237
      ASSIGN 270 TO i99999
 
238
      GO TO 300
 
239
 
 
240
  270 CONTINUE
 
241
  280 GO TO 250
 
242
 
 
243
  290 x = xlo
 
244
      status = 0
 
245
      RETURN
 
246
 
 
247
      ENTRY dstinv(zsmall,zbig,zabsst,zrelst,zstpmu,zabsto,zrelto)
 
248
C**********************************************************************
 
249
C
 
250
C      SUBROUTINE DSTINV( SMALL, BIG, ABSSTP, RELSTP, STPMUL,
 
251
C     +                   ABSTOL, RELTOL )
 
252
C      Double Precision - SeT INverse finder - Reverse Communication
 
253
C
 
254
C
 
255
C                              Function
 
256
C
 
257
C
 
258
C     Concise Description - Given a monotone function F finds X
 
259
C     such that F(X) = Y.  Uses Reverse communication -- see invr.
 
260
C     This routine sets quantities needed by INVR.
 
261
C
 
262
C          More Precise Description of INVR -
 
263
C
 
264
C     F must be a monotone function, the results of QMFINV are
 
265
C     otherwise undefined.  QINCR must be .TRUE. if F is non-
 
266
C     decreasing and .FALSE. if F is non-increasing.
 
267
C
 
268
C     QMFINV will return .TRUE. if and only if F(SMALL) and
 
269
C     F(BIG) bracket Y, i. e.,
 
270
C          QINCR is .TRUE. and F(SMALL).LE.Y.LE.F(BIG) or
 
271
C          QINCR is .FALSE. and F(BIG).LE.Y.LE.F(SMALL)
 
272
C
 
273
C     if QMFINV returns .TRUE., then the X returned satisfies
 
274
C     the following condition.  let
 
275
C               TOL(X) = MAX(ABSTOL,RELTOL*ABS(X))
 
276
C     then if QINCR is .TRUE.,
 
277
C          F(X-TOL(X)) .LE. Y .LE. F(X+TOL(X))
 
278
C     and if QINCR is .FALSE.
 
279
C          F(X-TOL(X)) .GE. Y .GE. F(X+TOL(X))
 
280
C
 
281
C
 
282
C                              Arguments
 
283
C
 
284
C
 
285
C     SMALL --> The left endpoint of the interval to be
 
286
C          searched for a solution.
 
287
C                    SMALL is DOUBLE PRECISION
 
288
C
 
289
C     BIG --> The right endpoint of the interval to be
 
290
C          searched for a solution.
 
291
C                    BIG is DOUBLE PRECISION
 
292
C
 
293
C     ABSSTP, RELSTP --> The initial step size in the search
 
294
C          is MAX(ABSSTP,RELSTP*ABS(X)). See algorithm.
 
295
C                    ABSSTP is DOUBLE PRECISION
 
296
C                    RELSTP is DOUBLE PRECISION
 
297
C
 
298
C     STPMUL --> When a step doesn't bound the zero, the step
 
299
C                size is multiplied by STPMUL and another step
 
300
C                taken.  A popular value is 2.0
 
301
C                    DOUBLE PRECISION STPMUL
 
302
C
 
303
C     ABSTOL, RELTOL --> Two numbers that determine the accuracy
 
304
C          of the solution.  See function for a precise definition.
 
305
C                    ABSTOL is DOUBLE PRECISION
 
306
C                    RELTOL is DOUBLE PRECISION
 
307
C
 
308
C
 
309
C                              Method
 
310
C
 
311
C
 
312
C     Compares F(X) with Y for the input value of X then uses QINCR
 
313
C     to determine whether to step left or right to bound the
 
314
C     desired x.  the initial step size is
 
315
C          MAX(ABSSTP,RELSTP*ABS(S)) for the input value of X.
 
316
C     Iteratively steps right or left until it bounds X.
 
317
C     At each step which doesn't bound X, the step size is doubled.
 
318
C     The routine is careful never to step beyond SMALL or BIG.  If
 
319
C     it hasn't bounded X at SMALL or BIG, QMFINV returns .FALSE.
 
320
C     after setting QLEFT and QHI.
 
321
C
 
322
C     If X is successfully bounded then Algorithm R of the paper
 
323
C     'Two Efficient Algorithms with Guaranteed Convergence for
 
324
C     Finding a Zero of a Function' by J. C. P. Bus and
 
325
C     T. J. Dekker in ACM Transactions on Mathematical
 
326
C     Software, Volume 1, No. 4 page 330 (DEC. '75) is employed
 
327
C     to find the zero of the function F(X)-Y. This is routine
 
328
C     QRZERO.
 
329
C
 
330
C**********************************************************************
 
331
      small = zsmall
 
332
      big = zbig
 
333
      absstp = zabsst
 
334
      relstp = zrelst
 
335
      stpmul = zstpmu
 
336
      abstol = zabsto
 
337
      reltol = zrelto
 
338
      RETURN
 
339
 
 
340
      STOP '*** EXECUTION FLOWING INTO FLECS PROCEDURES ***'
 
341
C     TO GET-FUNCTION-VALUE
 
342
  300 status = 1
 
343
      RETURN
 
344
 
 
345
  310 CONTINUE
 
346
      GO TO i99999
 
347
 
 
348
      END