4
5 IMPLICIT NONE
6
7
8
9
10
11
12 LOGICAL WANTNC
13 INTEGER B1, BN, N, NEGCNT, R
14 REAL GAPTOL, LAMBDA, MINGMA, NRMINV, PIVMIN, RESID,
15 $ RQCORR, ZTZ
16
17
18 INTEGER ISUPPZ( * )
19 REAL D( * ), L( * ), LD( * ), LLD( * ),
20 $ WORK( * )
21 REAL Z( * )
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 INTEGER BLKLEN
139 parameter( blklen = 16 )
140 REAL ZERO, ONE
141 parameter( zero = 0.0e0, one = 1.0e0 )
142
143
144
145 LOGICAL SAWNAN1, SAWNAN2
146 INTEGER BI, I, INDLPL, INDP, INDS, INDUMN, NB, NEG1,
147 $ NEG2, NX, R1, R2, TO
148 REAL ABSZCUR, ABSZPREV, DMINUS, DPLUS, EPS,
149 $ S, TMP, ZPREV
150
151
152 LOGICAL SISNAN
153 REAL SLAMCH
155
156
157 INTRINSIC abs,
max,
min, real
158
159
160
161 eps =
slamch(
'Precision' )
162
163
164 IF( r.EQ.0 ) THEN
165 r1 = b1
166 r2 = bn
167 ELSE
168 r1 = r
169 r2 = r
170 END IF
171
172
173 indlpl = 0
174
175 indumn = n
176 inds = 2*n + 1
177 indp = 3*n + 1
178
179 IF( b1.EQ.1 ) THEN
180 work( inds ) = zero
181 ELSE
182 work( inds+b1-1 ) = lld( b1-1 )
183 END IF
184
185
186
187
188
189 sawnan1 = .false.
190 neg1 = 0
191 s = work( inds+b1-1 ) - lambda
192 DO 50 i = b1, r1 - 1
193 dplus = d( i ) + s
194 work( indlpl+i ) = ld( i ) / dplus
195 IF(dplus.LT.zero) neg1 = neg1 + 1
196 work( inds+i ) = s*work( indlpl+i )*l( i )
197 s = work( inds+i ) - lambda
198 50 CONTINUE
199 sawnan1 = sisnan( s )
200 IF( sawnan1 ) GOTO 60
201 DO 51 i = r1, r2 - 1
202 dplus = d( i ) + s
203 work( indlpl+i ) = ld( i ) / dplus
204 work( inds+i ) = s*work( indlpl+i )*l( i )
205 s = work( inds+i ) - lambda
206 51 CONTINUE
207 sawnan1 = sisnan( s )
208
209 60 CONTINUE
210 IF( sawnan1 ) THEN
211
212 neg1 = 0
213 s = work( inds+b1-1 ) - lambda
214 DO 70 i = b1, r1 - 1
215 dplus = d( i ) + s
216 IF(abs(dplus).LT.pivmin) dplus = -pivmin
217 work( indlpl+i ) = ld( i ) / dplus
218 IF(dplus.LT.zero) neg1 = neg1 + 1
219 work( inds+i ) = s*work( indlpl+i )*l( i )
220 IF( work( indlpl+i ).EQ.zero )
221 $ work( inds+i ) = lld( i )
222 s = work( inds+i ) - lambda
223 70 CONTINUE
224 DO 71 i = r1, r2 - 1
225 dplus = d( i ) + s
226 IF(abs(dplus).LT.pivmin) dplus = -pivmin
227 work( indlpl+i ) = ld( i ) / dplus
228 work( inds+i ) = s*work( indlpl+i )*l( i )
229 IF( work( indlpl+i ).EQ.zero )
230 $ work( inds+i ) = lld( i )
231 s = work( inds+i ) - lambda
232 71 CONTINUE
233 END IF
234
235
236
237
238 sawnan2 = .false.
239 neg2 = 0
240 work( indp+bn-1 ) = d( bn ) - lambda
241 DO 80 i = bn - 1, r1, -1
242 dminus = lld( i ) + work( indp+i )
243 tmp = d( i ) / dminus
244 IF(dminus.LT.zero) neg2 = neg2 + 1
245 work( indumn+i ) = l( i )*tmp
246 work( indp+i-1 ) = work( indp+i )*tmp - lambda
247 80 CONTINUE
248 tmp = work( indp+r1-1 )
249 sawnan2 = sisnan( tmp )
250 IF( sawnan2 ) THEN
251
252 neg2 = 0
253 DO 100 i = bn-1, r1, -1
254 dminus = lld( i ) + work( indp+i )
255 IF(abs(dminus).LT.pivmin) dminus = -pivmin
256 tmp = d( i ) / dminus
257 IF(dminus.LT.zero) neg2 = neg2 + 1
258 work( indumn+i ) = l( i )*tmp
259 work( indp+i-1 ) = work( indp+i )*tmp - lambda
260 IF( tmp.EQ.zero )
261 $ work( indp+i-1 ) = d( i ) - lambda
262 100 CONTINUE
263 END IF
264
265
266
267
268 mingma = work( inds+r1-1 ) + work( indp+r1-1 )
269 IF( mingma.LT.zero ) neg1 = neg1 + 1
270 IF( wantnc ) THEN
271 negcnt = neg1 + neg2
272 ELSE
273 negcnt = -1
274 ENDIF
275 IF( abs(mingma).EQ.zero )
276 $ mingma = eps*work( inds+r1-1 )
277 r = r1
278 DO 110 i = r1, r2 - 1
279 tmp = work( inds+i ) + work( indp+i )
280 IF( tmp.EQ.zero )
281 $ tmp = eps*work( inds+i )
282 IF( abs( tmp ).LE.abs( mingma ) ) THEN
283 mingma = tmp
284 r = i + 1
285 END IF
286 110 CONTINUE
287
288
289
290 isuppz( 1 ) = b1
291 isuppz( 2 ) = bn
292 z( r ) = one
293 ztz = one
294
295
296
297 nb = int((r-b1)/blklen)
298 nx = r-nb*blklen
299 IF( .NOT.sawnan1 ) THEN
300 DO 210 bi = r-1, nx, -blklen
301 to = bi-blklen+1
302 DO 205 i = bi, to, -1
303 z( i ) = -( work(indlpl+i)*z(i+1) )
304 ztz = ztz + z( i )*z( i )
305 205 CONTINUE
306 IF( abs(z(to)).LT.eps .AND.
307 $ abs(z(to+1)).LT.eps ) THEN
308 isuppz(1) = to
309 GOTO 220
310 ENDIF
311 210 CONTINUE
312 DO 215 i = nx-1, b1, -1
313 z( i ) = -( work(indlpl+i)*z(i+1) )
314 ztz = ztz + z( i )*z( i )
315 215 CONTINUE
316 220 CONTINUE
317 ELSE
318
319 DO 230 bi = r-1, nx, -blklen
320 to = bi-blklen+1
321 DO 225 i = bi, to, -1
322 IF( z( i+1 ).EQ.zero ) THEN
323 z( i ) = -( ld( i+1 ) / ld( i ) )*z( i+2 )
324 ELSE
325 z( i ) = -( work( indlpl+i )*z( i+1 ) )
326 END IF
327 ztz = ztz + z( i )*z( i )
328 225 CONTINUE
329 IF( abs(z(to)).LT.eps .AND.
330 $ abs(z(to+1)).LT.eps ) THEN
331 isuppz(1) = to
332 GOTO 240
333 ENDIF
334 230 CONTINUE
335 DO 235 i = nx-1, b1, -1
336 IF( z( i+1 ).EQ.zero ) THEN
337 z( i ) = -( ld( i+1 ) / ld( i ) )*z( i+2 )
338 ELSE
339 z( i ) = -( work( indlpl+i )*z( i+1 ) )
340 END IF
341 ztz = ztz + z( i )*z( i )
342 235 CONTINUE
343 240 CONTINUE
344 ENDIF
345 DO 245 i= b1, (isuppz(1)-1)
346 z(i) = zero
347 245 CONTINUE
348
349
350 IF( .NOT.sawnan2 ) THEN
351 DO 260 bi = r+1, bn, blklen
352 to = bi+blklen-1
353 IF ( to.LE.bn ) THEN
354 DO 250 i = bi, to
355 z(i) = -(work(indumn+i-1)*z(i-1))
356 ztz = ztz + z( i )*z( i )
357 250 CONTINUE
358 IF( abs(z(to)).LE.eps .AND.
359 $ abs(z(to-1)).LE.eps ) THEN
360 isuppz(2) = to
361 GOTO 265
362 ENDIF
363 ELSE
364 DO 255 i = bi, bn
365 z(i) = -(work(indumn+i-1)*z(i-1))
366 ztz = ztz + z( i )*z( i )
367 255 CONTINUE
368 ENDIF
369 260 CONTINUE
370 265 CONTINUE
371 ELSE
372
373 DO 280 bi = r+1, bn, blklen
374 to = bi+blklen-1
375 IF ( to.LE.bn ) THEN
376 DO 270 i = bi, to
377 zprev = z(i-1)
378 abszprev = abs(zprev)
379 IF( zprev.NE.zero ) THEN
380 z(i)= -(work(indumn+i-1)*zprev)
381 ELSE
382 z(i)= -(ld(i-2)/ld(i-1))*z(i-2)
383 END IF
384 abszcur = abs(z(i))
385 ztz = ztz + abszcur**2
386 270 CONTINUE
387 IF( abszcur.LT.eps .AND.
388 $ abszprev.LT.eps ) THEN
389 isuppz(2) = i
390 GOTO 285
391 ENDIF
392 ELSE
393 DO 275 i = bi, bn
394 zprev = z(i-1)
395 abszprev = abs(zprev)
396 IF( zprev.NE.zero ) THEN
397 z(i)= -(work(indumn+i-1)*zprev)
398 ELSE
399 z(i)= -(ld(i-2)/ld(i-1))*z(i-2)
400 END IF
401 abszcur = abs(z(i))
402 ztz = ztz + abszcur**2
403 275 CONTINUE
404 ENDIF
405 280 CONTINUE
406 285 CONTINUE
407 END IF
408 DO 290 i= isuppz(2)+1,bn
409 z(i) = zero
410 290 CONTINUE
411
412
413
414 tmp = one / ztz
415 nrminv = sqrt( tmp )
416 resid = abs( mingma )*nrminv
417 rqcorr = mingma*tmp
418
419 RETURN
420
421
422