1 *> \brief \b DLASQ3 checks for deflation, computes a shift and calls dqds. Used by sbdsqr.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download DLASQ3 + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasq3.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasq3.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasq3.f">
21 * SUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
22 * ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
25 * .. Scalar Arguments ..
27 * INTEGER I0, ITER, N0, NDIV, NFAIL, PP
28 * DOUBLE PRECISION DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, G,
31 * .. Array Arguments ..
32 * DOUBLE PRECISION Z( * )
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
63 *> Z is DOUBLE PRECISION array, dimension ( 4*N )
64 *> Z holds the qd array.
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
78 *> DMIN is DOUBLE PRECISION
79 *> Minimum value of d.
84 *> SIGMA is DOUBLE PRECISION
85 *> Sum of shifts used in current segment.
88 *> \param[in,out] DESIG
90 *> DESIG is DOUBLE PRECISION
91 *> Lower order part of SIGMA
96 *> QMAX is DOUBLE PRECISION
97 *> Maximum value of q.
103 *> Number of times shift was too big.
109 *> Number of iterations.
115 *> Number of divisions.
121 *> Flag for IEEE or non IEEE arithmetic (passed to DLASQ5).
124 *> \param[in,out] TTYPE
130 *> \param[in,out] DMIN1
132 *> DMIN1 is DOUBLE PRECISION
135 *> \param[in,out] DMIN2
137 *> DMIN2 is DOUBLE PRECISION
142 *> DN is DOUBLE PRECISION
145 *> \param[in,out] DN1
147 *> DN1 is DOUBLE PRECISION
150 *> \param[in,out] DN2
152 *> DN2 is DOUBLE PRECISION
157 *> G is DOUBLE PRECISION
160 *> \param[in,out] TAU
162 *> TAU is DOUBLE PRECISION
164 *> These are passed as arguments in order to save their values
165 *> between calls to DLASQ3.
171 *> \author Univ. of Tennessee
172 *> \author Univ. of California Berkeley
173 *> \author Univ. of Colorado Denver
176 *> \date September 2012
178 *> \ingroup auxOTHERcomputational
180 * =====================================================================
181 SUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
182 $ ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
185 * -- LAPACK computational routine (version 3.4.2) --
186 * -- LAPACK is a software package provided by Univ. of Tennessee, --
187 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
190 * .. Scalar Arguments ..
192 INTEGER I0, ITER, N0, NDIV, NFAIL, PP
193 DOUBLE PRECISION DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, G,
196 * .. Array Arguments ..
197 DOUBLE PRECISION Z( * )
200 * =====================================================================
203 DOUBLE PRECISION CBIAS
204 PARAMETER ( CBIAS = 1.50D0 )
205 DOUBLE PRECISION ZERO, QURTR, HALF, ONE, TWO, HUNDRD
206 PARAMETER ( ZERO = 0.0D0, QURTR = 0.250D0, HALF = 0.5D0,
207 $ ONE = 1.0D0, TWO = 2.0D0, HUNDRD = 100.0D0 )
209 * .. Local Scalars ..
210 INTEGER IPN4, J4, N0IN, NN, TTYPE
211 DOUBLE PRECISION EPS, S, T, TEMP, TOL, TOL2
213 * .. External Subroutines ..
214 EXTERNAL DLASQ4, DLASQ5, DLASQ6
216 * .. External Function ..
217 DOUBLE PRECISION DLAMCH
219 EXTERNAL DISNAN, DLAMCH
221 * .. Intrinsic Functions ..
222 INTRINSIC ABS, MAX, MIN, SQRT
224 * .. Executable Statements ..
228 EPS = DLAMCH( 'Precision' )
232 * Check for deflation.
244 * Check whether E(N0-1) is negligible, 1 eigenvalue.
246 IF( Z( NN-5 ).GT.TOL2*( SIGMA+Z( NN-3 ) ) .AND.
247 $ Z( NN-2*PP-4 ).GT.TOL2*Z( NN-7 ) )
252 Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMA
256 * Check whether E(N0-2) is negligible, 2 eigenvalues.
260 IF( Z( NN-9 ).GT.TOL2*SIGMA .AND.
261 $ Z( NN-2*PP-8 ).GT.TOL2*Z( NN-11 ) )
266 IF( Z( NN-3 ).GT.Z( NN-7 ) ) THEN
268 Z( NN-3 ) = Z( NN-7 )
271 T = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) )
272 IF( Z( NN-5 ).GT.Z( NN-3 )*TOL2.AND.T.NE.ZERO ) THEN
273 S = Z( NN-3 )*( Z( NN-5 ) / T )
275 S = Z( NN-3 )*( Z( NN-5 ) /
276 $ ( T*( ONE+SQRT( ONE+S / T ) ) ) )
278 S = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) )
280 T = Z( NN-7 ) + ( S+Z( NN-5 ) )
281 Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T )
284 Z( 4*N0-7 ) = Z( NN-7 ) + SIGMA
285 Z( 4*N0-3 ) = Z( NN-3 ) + SIGMA
293 * Reverse the qd-array, if warranted.
296 IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THEN
297 IF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THEN
299 DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4
301 Z( J4-3 ) = Z( IPN4-J4-3 )
302 Z( IPN4-J4-3 ) = TEMP
304 Z( J4-2 ) = Z( IPN4-J4-2 )
305 Z( IPN4-J4-2 ) = TEMP
307 Z( J4-1 ) = Z( IPN4-J4-5 )
308 Z( IPN4-J4-5 ) = TEMP
310 Z( J4 ) = Z( IPN4-J4-4 )
311 Z( IPN4-J4-4 ) = TEMP
313 IF( N0-I0.LE.4 ) THEN
314 Z( 4*N0+PP-1 ) = Z( 4*I0+PP-1 )
315 Z( 4*N0-PP ) = Z( 4*I0-PP )
317 DMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) )
318 Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ),
320 Z( 4*N0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ),
322 QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) )
329 ! Print out DLASQ4 test cases
331 write(4,'(9999(g0))',advance="no") "z: []float64{"
333 write (4,'(99999(e24.16,a))',advance="no") z(i), ","
336 write (4,*) "i0: ", I0, ","
337 write (4,*) "n0: ", N0, ","
338 write (4,*) "pp: ", PP, ","
339 write (4,*) "n0in: ", N0IN, ","
340 write (4,*) "dmin: ", DMIN, ","
341 write (4,*) "dmin1:", DMIN1, ","
342 write (4,*) "dmin2:", DMIN2, ","
343 write (4,*) "dn: ", DN, ","
344 write (4,*) "dn1: ", DN1, ","
345 write (4,*) "dn2: ", DN2, ","
346 write (4,*) "tau: ", TAU, ","
347 write (4,*) "ttype: ", TTYPE, ","
348 write (4,*) "g: ", G, ","
349 CALL DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1,
350 $ DN2, TAU, TTYPE, G )
352 write(4,'(9999(g0))',advance="no") "zOut: []float64{"
354 write (4,'(99999(e24.16,a))',advance="no") z(i), ","
357 write (4,*) "tauOut: ", TAU, ","
358 write (4,*) "ttypeOut: ", TTYPE, ","
359 write (4,*) "gOut: ", G, ","
363 * Call dqds until DMIN > 0.
369 write(5,'(9999(g0))',advance="no") "z: []float64{"
371 write (5,'(99999(e24.16,a))',advance="no") z(i), ","
374 write (5,*) "i0: ", I0, ","
375 write (5,*) "n0: ", N0, ","
376 write (5,*) "pp: ", PP, ","
377 write (5,*) "tau: ", TAU, ","
378 write (5,*) "sigma: ", SIGMA, ","
379 write (5,*) "dmin: ", DMIN, ","
380 write (5,*) "dmin1:", DMIN1, ","
381 write (5,*) "dmin2:", DMIN2, ","
382 write (5,*) "dn: ", DN, ","
383 write (5,*) "dnm1: ", DN1, ","
384 write (5,*) "dnm2: ", DN2, ","
387 CALL DLASQ5( I0, N0, Z, PP, TAU, SIGMA, DMIN, DMIN1, DMIN2, DN,
388 $ DN1, DN2, IEEE, EPS )
392 write (5,*) "i0Out: ", I0, ","
393 write (5,*) "n0Out: ", N0, ","
394 write (5,*) "ppOut: ", PP, ","
395 write (5,*) "tauOut: ", TAU, ","
396 write (5,*) "sigmaOut: ", SIGMA, ","
397 write (5,*) "dminOut: ", DMIN, ","
398 write (5,*) "dmin1Out:", DMIN1, ","
399 write (5,*) "dmin2Out:", DMIN2, ","
400 write (5,*) "dnOut: ", DN, ","
401 write (5,*) "dnm1Out: ", DN1, ","
402 write (5,*) "dnm2Out: ", DN2, ","
406 NDIV = NDIV + ( N0-I0+2 )
413 IF( DMIN.GE.ZERO .AND. DMIN1.GE.ZERO ) THEN
419 ELSE IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND.
420 $ Z( 4*( N0-1 )-PP ).LT.TOL*( SIGMA+DN1 ) .AND.
421 $ ABS( DN ).LT.TOL*SIGMA ) THEN
424 * Convergence hidden by negative DN.
426 Z( 4*( N0-1 )-PP+2 ) = ZERO
429 ELSE IF( DMIN.LT.ZERO ) THEN
432 * TAU too big. Select new TAU and try again.
435 IF( TTYPE.LT.-22 ) THEN
437 * Failed twice. Play it safe.
440 ELSE IF( DMIN1.GT.ZERO ) THEN
442 * Late failure. Gives excellent shift.
444 TAU = ( TAU+DMIN )*( ONE-TWO*EPS )
448 * Early failure. Divide by 4.
454 ELSE IF( DISNAN( DMIN ) ) THEN
458 IF( TAU.EQ.ZERO ) THEN
466 * Possible underflow. Play it safe.
475 CALL DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 )
478 NDIV = NDIV + ( N0-I0+2 )
484 IF( TAU.LT.SIGMA ) THEN
487 DESIG = DESIG - ( T-SIGMA )
490 DESIG = SIGMA - ( T-TAU ) + DESIG