1: *> \brief \b DLASQ3 checks for deflation, computes a shift and calls dqds. Used by sbdsqr.
2: *
3: * =========== DOCUMENTATION ===========
4: *
5: * Online html documentation available at
6: * http://www.netlib.org/lapack/explore-html/
7: *
8: *> \htmlonly
9: *> Download DLASQ3 + dependencies
10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasq3.f">
11: *> [TGZ]</a>
12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasq3.f">
13: *> [ZIP]</a>
14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasq3.f">
15: *> [TXT]</a>
16: *> \endhtmlonly
17: *
18: * Definition:
19: * ===========
20: *
21: * SUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
22: * ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
23: * DN2, G, TAU )
24: *
25: * .. Scalar Arguments ..
26: * LOGICAL IEEE
27: * INTEGER I0, ITER, N0, NDIV, NFAIL, PP
28: * DOUBLE PRECISION DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, G,
29: * $ QMAX, SIGMA, TAU
30: * ..
31: * .. Array Arguments ..
32: * DOUBLE PRECISION Z( * )
33: * ..
34: *
35: *
36: *> \par Purpose:
37: * =============
38: *>
39: *> \verbatim
40: *>
41: *> DLASQ3 checks for deflation, computes a shift (TAU) and calls dqds.
42: *> In case of failure it changes shifts, and tries again until output
43: *> is positive.
44: *> \endverbatim
45: *
46: * Arguments:
47: * ==========
48: *
49: *> \param[in] I0
50: *> \verbatim
51: *> I0 is INTEGER
52: *> First index.
53: *> \endverbatim
54: *>
55: *> \param[in,out] N0
56: *> \verbatim
57: *> N0 is INTEGER
58: *> Last index.
59: *> \endverbatim
60: *>
61: *> \param[in,out] Z
62: *> \verbatim
63: *> Z is DOUBLE PRECISION array, dimension ( 4*N0 )
64: *> Z holds the qd array.
65: *> \endverbatim
66: *>
67: *> \param[in,out] PP
68: *> \verbatim
69: *> PP is INTEGER
70: *> PP=0 for ping, PP=1 for pong.
71: *> PP=2 indicates that flipping was applied to the Z array
72: *> and that the initial tests for deflation should not be
73: *> performed.
74: *> \endverbatim
75: *>
76: *> \param[out] DMIN
77: *> \verbatim
78: *> DMIN is DOUBLE PRECISION
79: *> Minimum value of d.
80: *> \endverbatim
81: *>
82: *> \param[out] SIGMA
83: *> \verbatim
84: *> SIGMA is DOUBLE PRECISION
85: *> Sum of shifts used in current segment.
86: *> \endverbatim
87: *>
88: *> \param[in,out] DESIG
89: *> \verbatim
90: *> DESIG is DOUBLE PRECISION
91: *> Lower order part of SIGMA
92: *> \endverbatim
93: *>
94: *> \param[in] QMAX
95: *> \verbatim
96: *> QMAX is DOUBLE PRECISION
97: *> Maximum value of q.
98: *> \endverbatim
99: *>
100: *> \param[in,out] NFAIL
101: *> \verbatim
102: *> NFAIL is INTEGER
103: *> Increment NFAIL by 1 each time the shift was too big.
104: *> \endverbatim
105: *>
106: *> \param[in,out] ITER
107: *> \verbatim
108: *> ITER is INTEGER
109: *> Increment ITER by 1 for each iteration.
110: *> \endverbatim
111: *>
112: *> \param[in,out] NDIV
113: *> \verbatim
114: *> NDIV is INTEGER
115: *> Increment NDIV by 1 for each division.
116: *> \endverbatim
117: *>
118: *> \param[in] IEEE
119: *> \verbatim
120: *> IEEE is LOGICAL
121: *> Flag for IEEE or non IEEE arithmetic (passed to DLASQ5).
122: *> \endverbatim
123: *>
124: *> \param[in,out] TTYPE
125: *> \verbatim
126: *> TTYPE is INTEGER
127: *> Shift type.
128: *> \endverbatim
129: *>
130: *> \param[in,out] DMIN1
131: *> \verbatim
132: *> DMIN1 is DOUBLE PRECISION
133: *> \endverbatim
134: *>
135: *> \param[in,out] DMIN2
136: *> \verbatim
137: *> DMIN2 is DOUBLE PRECISION
138: *> \endverbatim
139: *>
140: *> \param[in,out] DN
141: *> \verbatim
142: *> DN is DOUBLE PRECISION
143: *> \endverbatim
144: *>
145: *> \param[in,out] DN1
146: *> \verbatim
147: *> DN1 is DOUBLE PRECISION
148: *> \endverbatim
149: *>
150: *> \param[in,out] DN2
151: *> \verbatim
152: *> DN2 is DOUBLE PRECISION
153: *> \endverbatim
154: *>
155: *> \param[in,out] G
156: *> \verbatim
157: *> G is DOUBLE PRECISION
158: *> \endverbatim
159: *>
160: *> \param[in,out] TAU
161: *> \verbatim
162: *> TAU is DOUBLE PRECISION
163: *>
164: *> These are passed as arguments in order to save their values
165: *> between calls to DLASQ3.
166: *> \endverbatim
167: *
168: * Authors:
169: * ========
170: *
171: *> \author Univ. of Tennessee
172: *> \author Univ. of California Berkeley
173: *> \author Univ. of Colorado Denver
174: *> \author NAG Ltd.
175: *
176: *> \ingroup auxOTHERcomputational
177: *
178: * =====================================================================
179: SUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
180: $ ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
181: $ DN2, G, TAU )
182: *
183: * -- LAPACK computational routine --
184: * -- LAPACK is a software package provided by Univ. of Tennessee, --
185: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
186: *
187: * .. Scalar Arguments ..
188: LOGICAL IEEE
189: INTEGER I0, ITER, N0, NDIV, NFAIL, PP
190: DOUBLE PRECISION DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, G,
191: $ QMAX, SIGMA, TAU
192: * ..
193: * .. Array Arguments ..
194: DOUBLE PRECISION Z( * )
195: * ..
196: *
197: * =====================================================================
198: *
199: * .. Parameters ..
200: DOUBLE PRECISION CBIAS
201: PARAMETER ( CBIAS = 1.50D0 )
202: DOUBLE PRECISION ZERO, QURTR, HALF, ONE, TWO, HUNDRD
203: PARAMETER ( ZERO = 0.0D0, QURTR = 0.250D0, HALF = 0.5D0,
204: $ ONE = 1.0D0, TWO = 2.0D0, HUNDRD = 100.0D0 )
205: * ..
206: * .. Local Scalars ..
207: INTEGER IPN4, J4, N0IN, NN, TTYPE
208: DOUBLE PRECISION EPS, S, T, TEMP, TOL, TOL2
209: * ..
210: * .. External Subroutines ..
211: EXTERNAL DLASQ4, DLASQ5, DLASQ6
212: * ..
213: * .. External Function ..
214: DOUBLE PRECISION DLAMCH
215: LOGICAL DISNAN
216: EXTERNAL DISNAN, DLAMCH
217: * ..
218: * .. Intrinsic Functions ..
219: INTRINSIC ABS, MAX, MIN, SQRT
220: * ..
221: * .. Executable Statements ..
222: *
223: N0IN = N0
224: EPS = DLAMCH( 'Precision' )
225: TOL = EPS*HUNDRD
226: TOL2 = TOL**2
227: *
228: * Check for deflation.
229: *
230: 10 CONTINUE
231: *
232: IF( N0.LT.I0 )
233: $ RETURN
234: IF( N0.EQ.I0 )
235: $ GO TO 20
236: NN = 4*N0 + PP
237: IF( N0.EQ.( I0+1 ) )
238: $ GO TO 40
239: *
240: * Check whether E(N0-1) is negligible, 1 eigenvalue.
241: *
242: IF( Z( NN-5 ).GT.TOL2*( SIGMA+Z( NN-3 ) ) .AND.
243: $ Z( NN-2*PP-4 ).GT.TOL2*Z( NN-7 ) )
244: $ GO TO 30
245: *
246: 20 CONTINUE
247: *
248: Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMA
249: N0 = N0 - 1
250: GO TO 10
251: *
252: * Check whether E(N0-2) is negligible, 2 eigenvalues.
253: *
254: 30 CONTINUE
255: *
256: IF( Z( NN-9 ).GT.TOL2*SIGMA .AND.
257: $ Z( NN-2*PP-8 ).GT.TOL2*Z( NN-11 ) )
258: $ GO TO 50
259: *
260: 40 CONTINUE
261: *
262: IF( Z( NN-3 ).GT.Z( NN-7 ) ) THEN
263: S = Z( NN-3 )
264: Z( NN-3 ) = Z( NN-7 )
265: Z( NN-7 ) = S
266: END IF
267: T = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) )
268: IF( Z( NN-5 ).GT.Z( NN-3 )*TOL2.AND.T.NE.ZERO ) THEN
269: S = Z( NN-3 )*( Z( NN-5 ) / T )
270: IF( S.LE.T ) THEN
271: S = Z( NN-3 )*( Z( NN-5 ) /
272: $ ( T*( ONE+SQRT( ONE+S / T ) ) ) )
273: ELSE
274: S = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) )
275: END IF
276: T = Z( NN-7 ) + ( S+Z( NN-5 ) )
277: Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T )
278: Z( NN-7 ) = T
279: END IF
280: Z( 4*N0-7 ) = Z( NN-7 ) + SIGMA
281: Z( 4*N0-3 ) = Z( NN-3 ) + SIGMA
282: N0 = N0 - 2
283: GO TO 10
284: *
285: 50 CONTINUE
286: IF( PP.EQ.2 )
287: $ PP = 0
288: *
289: * Reverse the qd-array, if warranted.
290: *
291: IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THEN
292: IF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THEN
293: IPN4 = 4*( I0+N0 )
294: DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4
295: TEMP = Z( J4-3 )
296: Z( J4-3 ) = Z( IPN4-J4-3 )
297: Z( IPN4-J4-3 ) = TEMP
298: TEMP = Z( J4-2 )
299: Z( J4-2 ) = Z( IPN4-J4-2 )
300: Z( IPN4-J4-2 ) = TEMP
301: TEMP = Z( J4-1 )
302: Z( J4-1 ) = Z( IPN4-J4-5 )
303: Z( IPN4-J4-5 ) = TEMP
304: TEMP = Z( J4 )
305: Z( J4 ) = Z( IPN4-J4-4 )
306: Z( IPN4-J4-4 ) = TEMP
307: 60 CONTINUE
308: IF( N0-I0.LE.4 ) THEN
309: Z( 4*N0+PP-1 ) = Z( 4*I0+PP-1 )
310: Z( 4*N0-PP ) = Z( 4*I0-PP )
311: END IF
312: DMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) )
313: Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ),
314: $ Z( 4*I0+PP+3 ) )
315: Z( 4*N0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ),
316: $ Z( 4*I0-PP+4 ) )
317: QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) )
318: DMIN = -ZERO
319: END IF
320: END IF
321: *
322: * Choose a shift.
323: *
324: CALL DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1,
325: $ DN2, TAU, TTYPE, G )
326: *
327: * Call dqds until DMIN > 0.
328: *
329: 70 CONTINUE
330: *
331: CALL DLASQ5( I0, N0, Z, PP, TAU, SIGMA, DMIN, DMIN1, DMIN2, DN,
332: $ DN1, DN2, IEEE, EPS )
333: *
334: NDIV = NDIV + ( N0-I0+2 )
335: ITER = ITER + 1
336: *
337: * Check status.
338: *
339: IF( DMIN.GE.ZERO .AND. DMIN1.GE.ZERO ) THEN
340: *
341: * Success.
342: *
343: GO TO 90
344: *
345: ELSE IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND.
346: $ Z( 4*( N0-1 )-PP ).LT.TOL*( SIGMA+DN1 ) .AND.
347: $ ABS( DN ).LT.TOL*SIGMA ) THEN
348: *
349: * Convergence hidden by negative DN.
350: *
351: Z( 4*( N0-1 )-PP+2 ) = ZERO
352: DMIN = ZERO
353: GO TO 90
354: ELSE IF( DMIN.LT.ZERO ) THEN
355: *
356: * TAU too big. Select new TAU and try again.
357: *
358: NFAIL = NFAIL + 1
359: IF( TTYPE.LT.-22 ) THEN
360: *
361: * Failed twice. Play it safe.
362: *
363: TAU = ZERO
364: ELSE IF( DMIN1.GT.ZERO ) THEN
365: *
366: * Late failure. Gives excellent shift.
367: *
368: TAU = ( TAU+DMIN )*( ONE-TWO*EPS )
369: TTYPE = TTYPE - 11
370: ELSE
371: *
372: * Early failure. Divide by 4.
373: *
374: TAU = QURTR*TAU
375: TTYPE = TTYPE - 12
376: END IF
377: GO TO 70
378: ELSE IF( DISNAN( DMIN ) ) THEN
379: *
380: * NaN.
381: *
382: IF( TAU.EQ.ZERO ) THEN
383: GO TO 80
384: ELSE
385: TAU = ZERO
386: GO TO 70
387: END IF
388: ELSE
389: *
390: * Possible underflow. Play it safe.
391: *
392: GO TO 80
393: END IF
394: *
395: * Risk of underflow.
396: *
397: 80 CONTINUE
398: CALL DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 )
399: NDIV = NDIV + ( N0-I0+2 )
400: ITER = ITER + 1
401: TAU = ZERO
402: *
403: 90 CONTINUE
404: IF( TAU.LT.SIGMA ) THEN
405: DESIG = DESIG + TAU
406: T = SIGMA + DESIG
407: DESIG = DESIG - ( T-SIGMA )
408: ELSE
409: T = SIGMA + TAU
410: DESIG = SIGMA - ( T-TAU ) + DESIG
411: END IF
412: SIGMA = T
413: *
414: RETURN
415: *
416: * End of DLASQ3
417: *
418: END
CVSweb interface <joel.bertrand@systella.fr>