File:
[local] /
rpl /
lapack /
lapack /
zbdsqr.f
Revision
1.7:
download - view:
text,
annotated -
select for diffs -
revision graph
Tue Dec 21 13:53:42 2010 UTC (13 years, 6 months ago) by
bertrand
Branches:
MAIN
CVS tags:
rpl-4_1_3,
rpl-4_1_2,
rpl-4_1_1,
rpl-4_1_0,
rpl-4_0_24,
rpl-4_0_22,
rpl-4_0_21,
rpl-4_0_20,
rpl-4_0,
HEAD
Mise à jour de lapack vers la version 3.3.0.
1: SUBROUTINE ZBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
2: $ LDU, C, LDC, RWORK, INFO )
3: *
4: * -- LAPACK routine (version 3.2) --
5: * -- LAPACK is a software package provided by Univ. of Tennessee, --
6: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
7: * November 2006
8: *
9: * .. Scalar Arguments ..
10: CHARACTER UPLO
11: INTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU
12: * ..
13: * .. Array Arguments ..
14: DOUBLE PRECISION D( * ), E( * ), RWORK( * )
15: COMPLEX*16 C( LDC, * ), U( LDU, * ), VT( LDVT, * )
16: * ..
17: *
18: * Purpose
19: * =======
20: *
21: * ZBDSQR computes the singular values and, optionally, the right and/or
22: * left singular vectors from the singular value decomposition (SVD) of
23: * a real N-by-N (upper or lower) bidiagonal matrix B using the implicit
24: * zero-shift QR algorithm. The SVD of B has the form
25: *
26: * B = Q * S * P**H
27: *
28: * where S is the diagonal matrix of singular values, Q is an orthogonal
29: * matrix of left singular vectors, and P is an orthogonal matrix of
30: * right singular vectors. If left singular vectors are requested, this
31: * subroutine actually returns U*Q instead of Q, and, if right singular
32: * vectors are requested, this subroutine returns P**H*VT instead of
33: * P**H, for given complex input matrices U and VT. When U and VT are
34: * the unitary matrices that reduce a general matrix A to bidiagonal
35: * form: A = U*B*VT, as computed by ZGEBRD, then
36: *
37: * A = (U*Q) * S * (P**H*VT)
38: *
39: * is the SVD of A. Optionally, the subroutine may also compute Q**H*C
40: * for a given complex input matrix C.
41: *
42: * See "Computing Small Singular Values of Bidiagonal Matrices With
43: * Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
44: * LAPACK Working Note #3 (or SIAM J. Sci. Statist. Comput. vol. 11,
45: * no. 5, pp. 873-912, Sept 1990) and
46: * "Accurate singular values and differential qd algorithms," by
47: * B. Parlett and V. Fernando, Technical Report CPAM-554, Mathematics
48: * Department, University of California at Berkeley, July 1992
49: * for a detailed description of the algorithm.
50: *
51: * Arguments
52: * =========
53: *
54: * UPLO (input) CHARACTER*1
55: * = 'U': B is upper bidiagonal;
56: * = 'L': B is lower bidiagonal.
57: *
58: * N (input) INTEGER
59: * The order of the matrix B. N >= 0.
60: *
61: * NCVT (input) INTEGER
62: * The number of columns of the matrix VT. NCVT >= 0.
63: *
64: * NRU (input) INTEGER
65: * The number of rows of the matrix U. NRU >= 0.
66: *
67: * NCC (input) INTEGER
68: * The number of columns of the matrix C. NCC >= 0.
69: *
70: * D (input/output) DOUBLE PRECISION array, dimension (N)
71: * On entry, the n diagonal elements of the bidiagonal matrix B.
72: * On exit, if INFO=0, the singular values of B in decreasing
73: * order.
74: *
75: * E (input/output) DOUBLE PRECISION array, dimension (N-1)
76: * On entry, the N-1 offdiagonal elements of the bidiagonal
77: * matrix B.
78: * On exit, if INFO = 0, E is destroyed; if INFO > 0, D and E
79: * will contain the diagonal and superdiagonal elements of a
80: * bidiagonal matrix orthogonally equivalent to the one given
81: * as input.
82: *
83: * VT (input/output) COMPLEX*16 array, dimension (LDVT, NCVT)
84: * On entry, an N-by-NCVT matrix VT.
85: * On exit, VT is overwritten by P**H * VT.
86: * Not referenced if NCVT = 0.
87: *
88: * LDVT (input) INTEGER
89: * The leading dimension of the array VT.
90: * LDVT >= max(1,N) if NCVT > 0; LDVT >= 1 if NCVT = 0.
91: *
92: * U (input/output) COMPLEX*16 array, dimension (LDU, N)
93: * On entry, an NRU-by-N matrix U.
94: * On exit, U is overwritten by U * Q.
95: * Not referenced if NRU = 0.
96: *
97: * LDU (input) INTEGER
98: * The leading dimension of the array U. LDU >= max(1,NRU).
99: *
100: * C (input/output) COMPLEX*16 array, dimension (LDC, NCC)
101: * On entry, an N-by-NCC matrix C.
102: * On exit, C is overwritten by Q**H * C.
103: * Not referenced if NCC = 0.
104: *
105: * LDC (input) INTEGER
106: * The leading dimension of the array C.
107: * LDC >= max(1,N) if NCC > 0; LDC >=1 if NCC = 0.
108: *
109: * RWORK (workspace) DOUBLE PRECISION array, dimension (2*N)
110: * if NCVT = NRU = NCC = 0, (max(1, 4*N-4)) otherwise
111: *
112: * INFO (output) INTEGER
113: * = 0: successful exit
114: * < 0: If INFO = -i, the i-th argument had an illegal value
115: * > 0: the algorithm did not converge; D and E contain the
116: * elements of a bidiagonal matrix which is orthogonally
117: * similar to the input matrix B; if INFO = i, i
118: * elements of E have not converged to zero.
119: *
120: * Internal Parameters
121: * ===================
122: *
123: * TOLMUL DOUBLE PRECISION, default = max(10,min(100,EPS**(-1/8)))
124: * TOLMUL controls the convergence criterion of the QR loop.
125: * If it is positive, TOLMUL*EPS is the desired relative
126: * precision in the computed singular values.
127: * If it is negative, abs(TOLMUL*EPS*sigma_max) is the
128: * desired absolute accuracy in the computed singular
129: * values (corresponds to relative accuracy
130: * abs(TOLMUL*EPS) in the largest singular value.
131: * abs(TOLMUL) should be between 1 and 1/EPS, and preferably
132: * between 10 (for fast convergence) and .1/EPS
133: * (for there to be some accuracy in the results).
134: * Default is to lose at either one eighth or 2 of the
135: * available decimal digits in each computed singular value
136: * (whichever is smaller).
137: *
138: * MAXITR INTEGER, default = 6
139: * MAXITR controls the maximum number of passes of the
140: * algorithm through its inner loop. The algorithms stops
141: * (and so fails to converge) if the number of passes
142: * through the inner loop exceeds MAXITR*N**2.
143: *
144: * =====================================================================
145: *
146: * .. Parameters ..
147: DOUBLE PRECISION ZERO
148: PARAMETER ( ZERO = 0.0D0 )
149: DOUBLE PRECISION ONE
150: PARAMETER ( ONE = 1.0D0 )
151: DOUBLE PRECISION NEGONE
152: PARAMETER ( NEGONE = -1.0D0 )
153: DOUBLE PRECISION HNDRTH
154: PARAMETER ( HNDRTH = 0.01D0 )
155: DOUBLE PRECISION TEN
156: PARAMETER ( TEN = 10.0D0 )
157: DOUBLE PRECISION HNDRD
158: PARAMETER ( HNDRD = 100.0D0 )
159: DOUBLE PRECISION MEIGTH
160: PARAMETER ( MEIGTH = -0.125D0 )
161: INTEGER MAXITR
162: PARAMETER ( MAXITR = 6 )
163: * ..
164: * .. Local Scalars ..
165: LOGICAL LOWER, ROTATE
166: INTEGER I, IDIR, ISUB, ITER, J, LL, LLL, M, MAXIT, NM1,
167: $ NM12, NM13, OLDLL, OLDM
168: DOUBLE PRECISION ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU,
169: $ OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL,
170: $ SINR, SLL, SMAX, SMIN, SMINL, SMINOA,
171: $ SN, THRESH, TOL, TOLMUL, UNFL
172: * ..
173: * .. External Functions ..
174: LOGICAL LSAME
175: DOUBLE PRECISION DLAMCH
176: EXTERNAL LSAME, DLAMCH
177: * ..
178: * .. External Subroutines ..
179: EXTERNAL DLARTG, DLAS2, DLASQ1, DLASV2, XERBLA, ZDROT,
180: $ ZDSCAL, ZLASR, ZSWAP
181: * ..
182: * .. Intrinsic Functions ..
183: INTRINSIC ABS, DBLE, MAX, MIN, SIGN, SQRT
184: * ..
185: * .. Executable Statements ..
186: *
187: * Test the input parameters.
188: *
189: INFO = 0
190: LOWER = LSAME( UPLO, 'L' )
191: IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LOWER ) THEN
192: INFO = -1
193: ELSE IF( N.LT.0 ) THEN
194: INFO = -2
195: ELSE IF( NCVT.LT.0 ) THEN
196: INFO = -3
197: ELSE IF( NRU.LT.0 ) THEN
198: INFO = -4
199: ELSE IF( NCC.LT.0 ) THEN
200: INFO = -5
201: ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
202: $ ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
203: INFO = -9
204: ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN
205: INFO = -11
206: ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.
207: $ ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN
208: INFO = -13
209: END IF
210: IF( INFO.NE.0 ) THEN
211: CALL XERBLA( 'ZBDSQR', -INFO )
212: RETURN
213: END IF
214: IF( N.EQ.0 )
215: $ RETURN
216: IF( N.EQ.1 )
217: $ GO TO 160
218: *
219: * ROTATE is true if any singular vectors desired, false otherwise
220: *
221: ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )
222: *
223: * If no singular vectors desired, use qd algorithm
224: *
225: IF( .NOT.ROTATE ) THEN
226: CALL DLASQ1( N, D, E, RWORK, INFO )
227: RETURN
228: END IF
229: *
230: NM1 = N - 1
231: NM12 = NM1 + NM1
232: NM13 = NM12 + NM1
233: IDIR = 0
234: *
235: * Get machine constants
236: *
237: EPS = DLAMCH( 'Epsilon' )
238: UNFL = DLAMCH( 'Safe minimum' )
239: *
240: * If matrix lower bidiagonal, rotate to be upper bidiagonal
241: * by applying Givens rotations on the left
242: *
243: IF( LOWER ) THEN
244: DO 10 I = 1, N - 1
245: CALL DLARTG( D( I ), E( I ), CS, SN, R )
246: D( I ) = R
247: E( I ) = SN*D( I+1 )
248: D( I+1 ) = CS*D( I+1 )
249: RWORK( I ) = CS
250: RWORK( NM1+I ) = SN
251: 10 CONTINUE
252: *
253: * Update singular vectors if desired
254: *
255: IF( NRU.GT.0 )
256: $ CALL ZLASR( 'R', 'V', 'F', NRU, N, RWORK( 1 ), RWORK( N ),
257: $ U, LDU )
258: IF( NCC.GT.0 )
259: $ CALL ZLASR( 'L', 'V', 'F', N, NCC, RWORK( 1 ), RWORK( N ),
260: $ C, LDC )
261: END IF
262: *
263: * Compute singular values to relative accuracy TOL
264: * (By setting TOL to be negative, algorithm will compute
265: * singular values to absolute accuracy ABS(TOL)*norm(input matrix))
266: *
267: TOLMUL = MAX( TEN, MIN( HNDRD, EPS**MEIGTH ) )
268: TOL = TOLMUL*EPS
269: *
270: * Compute approximate maximum, minimum singular values
271: *
272: SMAX = ZERO
273: DO 20 I = 1, N
274: SMAX = MAX( SMAX, ABS( D( I ) ) )
275: 20 CONTINUE
276: DO 30 I = 1, N - 1
277: SMAX = MAX( SMAX, ABS( E( I ) ) )
278: 30 CONTINUE
279: SMINL = ZERO
280: IF( TOL.GE.ZERO ) THEN
281: *
282: * Relative accuracy desired
283: *
284: SMINOA = ABS( D( 1 ) )
285: IF( SMINOA.EQ.ZERO )
286: $ GO TO 50
287: MU = SMINOA
288: DO 40 I = 2, N
289: MU = ABS( D( I ) )*( MU / ( MU+ABS( E( I-1 ) ) ) )
290: SMINOA = MIN( SMINOA, MU )
291: IF( SMINOA.EQ.ZERO )
292: $ GO TO 50
293: 40 CONTINUE
294: 50 CONTINUE
295: SMINOA = SMINOA / SQRT( DBLE( N ) )
296: THRESH = MAX( TOL*SMINOA, MAXITR*N*N*UNFL )
297: ELSE
298: *
299: * Absolute accuracy desired
300: *
301: THRESH = MAX( ABS( TOL )*SMAX, MAXITR*N*N*UNFL )
302: END IF
303: *
304: * Prepare for main iteration loop for the singular values
305: * (MAXIT is the maximum number of passes through the inner
306: * loop permitted before nonconvergence signalled.)
307: *
308: MAXIT = MAXITR*N*N
309: ITER = 0
310: OLDLL = -1
311: OLDM = -1
312: *
313: * M points to last element of unconverged part of matrix
314: *
315: M = N
316: *
317: * Begin main iteration loop
318: *
319: 60 CONTINUE
320: *
321: * Check for convergence or exceeding iteration count
322: *
323: IF( M.LE.1 )
324: $ GO TO 160
325: IF( ITER.GT.MAXIT )
326: $ GO TO 200
327: *
328: * Find diagonal block of matrix to work on
329: *
330: IF( TOL.LT.ZERO .AND. ABS( D( M ) ).LE.THRESH )
331: $ D( M ) = ZERO
332: SMAX = ABS( D( M ) )
333: SMIN = SMAX
334: DO 70 LLL = 1, M - 1
335: LL = M - LLL
336: ABSS = ABS( D( LL ) )
337: ABSE = ABS( E( LL ) )
338: IF( TOL.LT.ZERO .AND. ABSS.LE.THRESH )
339: $ D( LL ) = ZERO
340: IF( ABSE.LE.THRESH )
341: $ GO TO 80
342: SMIN = MIN( SMIN, ABSS )
343: SMAX = MAX( SMAX, ABSS, ABSE )
344: 70 CONTINUE
345: LL = 0
346: GO TO 90
347: 80 CONTINUE
348: E( LL ) = ZERO
349: *
350: * Matrix splits since E(LL) = 0
351: *
352: IF( LL.EQ.M-1 ) THEN
353: *
354: * Convergence of bottom singular value, return to top of loop
355: *
356: M = M - 1
357: GO TO 60
358: END IF
359: 90 CONTINUE
360: LL = LL + 1
361: *
362: * E(LL) through E(M-1) are nonzero, E(LL-1) is zero
363: *
364: IF( LL.EQ.M-1 ) THEN
365: *
366: * 2 by 2 block, handle separately
367: *
368: CALL DLASV2( D( M-1 ), E( M-1 ), D( M ), SIGMN, SIGMX, SINR,
369: $ COSR, SINL, COSL )
370: D( M-1 ) = SIGMX
371: E( M-1 ) = ZERO
372: D( M ) = SIGMN
373: *
374: * Compute singular vectors, if desired
375: *
376: IF( NCVT.GT.0 )
377: $ CALL ZDROT( NCVT, VT( M-1, 1 ), LDVT, VT( M, 1 ), LDVT,
378: $ COSR, SINR )
379: IF( NRU.GT.0 )
380: $ CALL ZDROT( NRU, U( 1, M-1 ), 1, U( 1, M ), 1, COSL, SINL )
381: IF( NCC.GT.0 )
382: $ CALL ZDROT( NCC, C( M-1, 1 ), LDC, C( M, 1 ), LDC, COSL,
383: $ SINL )
384: M = M - 2
385: GO TO 60
386: END IF
387: *
388: * If working on new submatrix, choose shift direction
389: * (from larger end diagonal element towards smaller)
390: *
391: IF( LL.GT.OLDM .OR. M.LT.OLDLL ) THEN
392: IF( ABS( D( LL ) ).GE.ABS( D( M ) ) ) THEN
393: *
394: * Chase bulge from top (big end) to bottom (small end)
395: *
396: IDIR = 1
397: ELSE
398: *
399: * Chase bulge from bottom (big end) to top (small end)
400: *
401: IDIR = 2
402: END IF
403: END IF
404: *
405: * Apply convergence tests
406: *
407: IF( IDIR.EQ.1 ) THEN
408: *
409: * Run convergence test in forward direction
410: * First apply standard test to bottom of matrix
411: *
412: IF( ABS( E( M-1 ) ).LE.ABS( TOL )*ABS( D( M ) ) .OR.
413: $ ( TOL.LT.ZERO .AND. ABS( E( M-1 ) ).LE.THRESH ) ) THEN
414: E( M-1 ) = ZERO
415: GO TO 60
416: END IF
417: *
418: IF( TOL.GE.ZERO ) THEN
419: *
420: * If relative accuracy desired,
421: * apply convergence criterion forward
422: *
423: MU = ABS( D( LL ) )
424: SMINL = MU
425: DO 100 LLL = LL, M - 1
426: IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
427: E( LLL ) = ZERO
428: GO TO 60
429: END IF
430: MU = ABS( D( LLL+1 ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
431: SMINL = MIN( SMINL, MU )
432: 100 CONTINUE
433: END IF
434: *
435: ELSE
436: *
437: * Run convergence test in backward direction
438: * First apply standard test to top of matrix
439: *
440: IF( ABS( E( LL ) ).LE.ABS( TOL )*ABS( D( LL ) ) .OR.
441: $ ( TOL.LT.ZERO .AND. ABS( E( LL ) ).LE.THRESH ) ) THEN
442: E( LL ) = ZERO
443: GO TO 60
444: END IF
445: *
446: IF( TOL.GE.ZERO ) THEN
447: *
448: * If relative accuracy desired,
449: * apply convergence criterion backward
450: *
451: MU = ABS( D( M ) )
452: SMINL = MU
453: DO 110 LLL = M - 1, LL, -1
454: IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
455: E( LLL ) = ZERO
456: GO TO 60
457: END IF
458: MU = ABS( D( LLL ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
459: SMINL = MIN( SMINL, MU )
460: 110 CONTINUE
461: END IF
462: END IF
463: OLDLL = LL
464: OLDM = M
465: *
466: * Compute shift. First, test if shifting would ruin relative
467: * accuracy, and if so set the shift to zero.
468: *
469: IF( TOL.GE.ZERO .AND. N*TOL*( SMINL / SMAX ).LE.
470: $ MAX( EPS, HNDRTH*TOL ) ) THEN
471: *
472: * Use a zero shift to avoid loss of relative accuracy
473: *
474: SHIFT = ZERO
475: ELSE
476: *
477: * Compute the shift from 2-by-2 block at end of matrix
478: *
479: IF( IDIR.EQ.1 ) THEN
480: SLL = ABS( D( LL ) )
481: CALL DLAS2( D( M-1 ), E( M-1 ), D( M ), SHIFT, R )
482: ELSE
483: SLL = ABS( D( M ) )
484: CALL DLAS2( D( LL ), E( LL ), D( LL+1 ), SHIFT, R )
485: END IF
486: *
487: * Test if shift negligible, and if so set to zero
488: *
489: IF( SLL.GT.ZERO ) THEN
490: IF( ( SHIFT / SLL )**2.LT.EPS )
491: $ SHIFT = ZERO
492: END IF
493: END IF
494: *
495: * Increment iteration count
496: *
497: ITER = ITER + M - LL
498: *
499: * If SHIFT = 0, do simplified QR iteration
500: *
501: IF( SHIFT.EQ.ZERO ) THEN
502: IF( IDIR.EQ.1 ) THEN
503: *
504: * Chase bulge from top to bottom
505: * Save cosines and sines for later singular vector updates
506: *
507: CS = ONE
508: OLDCS = ONE
509: DO 120 I = LL, M - 1
510: CALL DLARTG( D( I )*CS, E( I ), CS, SN, R )
511: IF( I.GT.LL )
512: $ E( I-1 ) = OLDSN*R
513: CALL DLARTG( OLDCS*R, D( I+1 )*SN, OLDCS, OLDSN, D( I ) )
514: RWORK( I-LL+1 ) = CS
515: RWORK( I-LL+1+NM1 ) = SN
516: RWORK( I-LL+1+NM12 ) = OLDCS
517: RWORK( I-LL+1+NM13 ) = OLDSN
518: 120 CONTINUE
519: H = D( M )*CS
520: D( M ) = H*OLDCS
521: E( M-1 ) = H*OLDSN
522: *
523: * Update singular vectors
524: *
525: IF( NCVT.GT.0 )
526: $ CALL ZLASR( 'L', 'V', 'F', M-LL+1, NCVT, RWORK( 1 ),
527: $ RWORK( N ), VT( LL, 1 ), LDVT )
528: IF( NRU.GT.0 )
529: $ CALL ZLASR( 'R', 'V', 'F', NRU, M-LL+1, RWORK( NM12+1 ),
530: $ RWORK( NM13+1 ), U( 1, LL ), LDU )
531: IF( NCC.GT.0 )
532: $ CALL ZLASR( 'L', 'V', 'F', M-LL+1, NCC, RWORK( NM12+1 ),
533: $ RWORK( NM13+1 ), C( LL, 1 ), LDC )
534: *
535: * Test convergence
536: *
537: IF( ABS( E( M-1 ) ).LE.THRESH )
538: $ E( M-1 ) = ZERO
539: *
540: ELSE
541: *
542: * Chase bulge from bottom to top
543: * Save cosines and sines for later singular vector updates
544: *
545: CS = ONE
546: OLDCS = ONE
547: DO 130 I = M, LL + 1, -1
548: CALL DLARTG( D( I )*CS, E( I-1 ), CS, SN, R )
549: IF( I.LT.M )
550: $ E( I ) = OLDSN*R
551: CALL DLARTG( OLDCS*R, D( I-1 )*SN, OLDCS, OLDSN, D( I ) )
552: RWORK( I-LL ) = CS
553: RWORK( I-LL+NM1 ) = -SN
554: RWORK( I-LL+NM12 ) = OLDCS
555: RWORK( I-LL+NM13 ) = -OLDSN
556: 130 CONTINUE
557: H = D( LL )*CS
558: D( LL ) = H*OLDCS
559: E( LL ) = H*OLDSN
560: *
561: * Update singular vectors
562: *
563: IF( NCVT.GT.0 )
564: $ CALL ZLASR( 'L', 'V', 'B', M-LL+1, NCVT, RWORK( NM12+1 ),
565: $ RWORK( NM13+1 ), VT( LL, 1 ), LDVT )
566: IF( NRU.GT.0 )
567: $ CALL ZLASR( 'R', 'V', 'B', NRU, M-LL+1, RWORK( 1 ),
568: $ RWORK( N ), U( 1, LL ), LDU )
569: IF( NCC.GT.0 )
570: $ CALL ZLASR( 'L', 'V', 'B', M-LL+1, NCC, RWORK( 1 ),
571: $ RWORK( N ), C( LL, 1 ), LDC )
572: *
573: * Test convergence
574: *
575: IF( ABS( E( LL ) ).LE.THRESH )
576: $ E( LL ) = ZERO
577: END IF
578: ELSE
579: *
580: * Use nonzero shift
581: *
582: IF( IDIR.EQ.1 ) THEN
583: *
584: * Chase bulge from top to bottom
585: * Save cosines and sines for later singular vector updates
586: *
587: F = ( ABS( D( LL ) )-SHIFT )*
588: $ ( SIGN( ONE, D( LL ) )+SHIFT / D( LL ) )
589: G = E( LL )
590: DO 140 I = LL, M - 1
591: CALL DLARTG( F, G, COSR, SINR, R )
592: IF( I.GT.LL )
593: $ E( I-1 ) = R
594: F = COSR*D( I ) + SINR*E( I )
595: E( I ) = COSR*E( I ) - SINR*D( I )
596: G = SINR*D( I+1 )
597: D( I+1 ) = COSR*D( I+1 )
598: CALL DLARTG( F, G, COSL, SINL, R )
599: D( I ) = R
600: F = COSL*E( I ) + SINL*D( I+1 )
601: D( I+1 ) = COSL*D( I+1 ) - SINL*E( I )
602: IF( I.LT.M-1 ) THEN
603: G = SINL*E( I+1 )
604: E( I+1 ) = COSL*E( I+1 )
605: END IF
606: RWORK( I-LL+1 ) = COSR
607: RWORK( I-LL+1+NM1 ) = SINR
608: RWORK( I-LL+1+NM12 ) = COSL
609: RWORK( I-LL+1+NM13 ) = SINL
610: 140 CONTINUE
611: E( M-1 ) = F
612: *
613: * Update singular vectors
614: *
615: IF( NCVT.GT.0 )
616: $ CALL ZLASR( 'L', 'V', 'F', M-LL+1, NCVT, RWORK( 1 ),
617: $ RWORK( N ), VT( LL, 1 ), LDVT )
618: IF( NRU.GT.0 )
619: $ CALL ZLASR( 'R', 'V', 'F', NRU, M-LL+1, RWORK( NM12+1 ),
620: $ RWORK( NM13+1 ), U( 1, LL ), LDU )
621: IF( NCC.GT.0 )
622: $ CALL ZLASR( 'L', 'V', 'F', M-LL+1, NCC, RWORK( NM12+1 ),
623: $ RWORK( NM13+1 ), C( LL, 1 ), LDC )
624: *
625: * Test convergence
626: *
627: IF( ABS( E( M-1 ) ).LE.THRESH )
628: $ E( M-1 ) = ZERO
629: *
630: ELSE
631: *
632: * Chase bulge from bottom to top
633: * Save cosines and sines for later singular vector updates
634: *
635: F = ( ABS( D( M ) )-SHIFT )*( SIGN( ONE, D( M ) )+SHIFT /
636: $ D( M ) )
637: G = E( M-1 )
638: DO 150 I = M, LL + 1, -1
639: CALL DLARTG( F, G, COSR, SINR, R )
640: IF( I.LT.M )
641: $ E( I ) = R
642: F = COSR*D( I ) + SINR*E( I-1 )
643: E( I-1 ) = COSR*E( I-1 ) - SINR*D( I )
644: G = SINR*D( I-1 )
645: D( I-1 ) = COSR*D( I-1 )
646: CALL DLARTG( F, G, COSL, SINL, R )
647: D( I ) = R
648: F = COSL*E( I-1 ) + SINL*D( I-1 )
649: D( I-1 ) = COSL*D( I-1 ) - SINL*E( I-1 )
650: IF( I.GT.LL+1 ) THEN
651: G = SINL*E( I-2 )
652: E( I-2 ) = COSL*E( I-2 )
653: END IF
654: RWORK( I-LL ) = COSR
655: RWORK( I-LL+NM1 ) = -SINR
656: RWORK( I-LL+NM12 ) = COSL
657: RWORK( I-LL+NM13 ) = -SINL
658: 150 CONTINUE
659: E( LL ) = F
660: *
661: * Test convergence
662: *
663: IF( ABS( E( LL ) ).LE.THRESH )
664: $ E( LL ) = ZERO
665: *
666: * Update singular vectors if desired
667: *
668: IF( NCVT.GT.0 )
669: $ CALL ZLASR( 'L', 'V', 'B', M-LL+1, NCVT, RWORK( NM12+1 ),
670: $ RWORK( NM13+1 ), VT( LL, 1 ), LDVT )
671: IF( NRU.GT.0 )
672: $ CALL ZLASR( 'R', 'V', 'B', NRU, M-LL+1, RWORK( 1 ),
673: $ RWORK( N ), U( 1, LL ), LDU )
674: IF( NCC.GT.0 )
675: $ CALL ZLASR( 'L', 'V', 'B', M-LL+1, NCC, RWORK( 1 ),
676: $ RWORK( N ), C( LL, 1 ), LDC )
677: END IF
678: END IF
679: *
680: * QR iteration finished, go back and check convergence
681: *
682: GO TO 60
683: *
684: * All singular values converged, so make them positive
685: *
686: 160 CONTINUE
687: DO 170 I = 1, N
688: IF( D( I ).LT.ZERO ) THEN
689: D( I ) = -D( I )
690: *
691: * Change sign of singular vectors, if desired
692: *
693: IF( NCVT.GT.0 )
694: $ CALL ZDSCAL( NCVT, NEGONE, VT( I, 1 ), LDVT )
695: END IF
696: 170 CONTINUE
697: *
698: * Sort the singular values into decreasing order (insertion sort on
699: * singular values, but only one transposition per singular vector)
700: *
701: DO 190 I = 1, N - 1
702: *
703: * Scan for smallest D(I)
704: *
705: ISUB = 1
706: SMIN = D( 1 )
707: DO 180 J = 2, N + 1 - I
708: IF( D( J ).LE.SMIN ) THEN
709: ISUB = J
710: SMIN = D( J )
711: END IF
712: 180 CONTINUE
713: IF( ISUB.NE.N+1-I ) THEN
714: *
715: * Swap singular values and vectors
716: *
717: D( ISUB ) = D( N+1-I )
718: D( N+1-I ) = SMIN
719: IF( NCVT.GT.0 )
720: $ CALL ZSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( N+1-I, 1 ),
721: $ LDVT )
722: IF( NRU.GT.0 )
723: $ CALL ZSWAP( NRU, U( 1, ISUB ), 1, U( 1, N+1-I ), 1 )
724: IF( NCC.GT.0 )
725: $ CALL ZSWAP( NCC, C( ISUB, 1 ), LDC, C( N+1-I, 1 ), LDC )
726: END IF
727: 190 CONTINUE
728: GO TO 220
729: *
730: * Maximum number of iterations exceeded, failure to converge
731: *
732: 200 CONTINUE
733: INFO = 0
734: DO 210 I = 1, N - 1
735: IF( E( I ).NE.ZERO )
736: $ INFO = INFO + 1
737: 210 CONTINUE
738: 220 CONTINUE
739: RETURN
740: *
741: * End of ZBDSQR
742: *
743: END
CVSweb interface <joel.bertrand@systella.fr>