LAPACK 3.3.0
|
00001 SUBROUTINE CBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U, 00002 $ LDU, C, LDC, RWORK, INFO ) 00003 * 00004 * -- LAPACK routine (version 3.2) -- 00005 * -- LAPACK is a software package provided by Univ. of Tennessee, -- 00006 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 00007 * November 2006 00008 * 00009 * .. Scalar Arguments .. 00010 CHARACTER UPLO 00011 INTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU 00012 * .. 00013 * .. Array Arguments .. 00014 REAL D( * ), E( * ), RWORK( * ) 00015 COMPLEX C( LDC, * ), U( LDU, * ), VT( LDVT, * ) 00016 * .. 00017 * 00018 * Purpose 00019 * ======= 00020 * 00021 * CBDSQR computes the singular values and, optionally, the right and/or 00022 * left singular vectors from the singular value decomposition (SVD) of 00023 * a real N-by-N (upper or lower) bidiagonal matrix B using the implicit 00024 * zero-shift QR algorithm. The SVD of B has the form 00025 * 00026 * B = Q * S * P**H 00027 * 00028 * where S is the diagonal matrix of singular values, Q is an orthogonal 00029 * matrix of left singular vectors, and P is an orthogonal matrix of 00030 * right singular vectors. If left singular vectors are requested, this 00031 * subroutine actually returns U*Q instead of Q, and, if right singular 00032 * vectors are requested, this subroutine returns P**H*VT instead of 00033 * P**H, for given complex input matrices U and VT. When U and VT are 00034 * the unitary matrices that reduce a general matrix A to bidiagonal 00035 * form: A = U*B*VT, as computed by CGEBRD, then 00036 * 00037 * A = (U*Q) * S * (P**H*VT) 00038 * 00039 * is the SVD of A. Optionally, the subroutine may also compute Q**H*C 00040 * for a given complex input matrix C. 00041 * 00042 * See "Computing Small Singular Values of Bidiagonal Matrices With 00043 * Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan, 00044 * LAPACK Working Note #3 (or SIAM J. Sci. Statist. Comput. vol. 11, 00045 * no. 5, pp. 873-912, Sept 1990) and 00046 * "Accurate singular values and differential qd algorithms," by 00047 * B. Parlett and V. Fernando, Technical Report CPAM-554, Mathematics 00048 * Department, University of California at Berkeley, July 1992 00049 * for a detailed description of the algorithm. 00050 * 00051 * Arguments 00052 * ========= 00053 * 00054 * UPLO (input) CHARACTER*1 00055 * = 'U': B is upper bidiagonal; 00056 * = 'L': B is lower bidiagonal. 00057 * 00058 * N (input) INTEGER 00059 * The order of the matrix B. N >= 0. 00060 * 00061 * NCVT (input) INTEGER 00062 * The number of columns of the matrix VT. NCVT >= 0. 00063 * 00064 * NRU (input) INTEGER 00065 * The number of rows of the matrix U. NRU >= 0. 00066 * 00067 * NCC (input) INTEGER 00068 * The number of columns of the matrix C. NCC >= 0. 00069 * 00070 * D (input/output) REAL array, dimension (N) 00071 * On entry, the n diagonal elements of the bidiagonal matrix B. 00072 * On exit, if INFO=0, the singular values of B in decreasing 00073 * order. 00074 * 00075 * E (input/output) REAL array, dimension (N-1) 00076 * On entry, the N-1 offdiagonal elements of the bidiagonal 00077 * matrix B. 00078 * On exit, if INFO = 0, E is destroyed; if INFO > 0, D and E 00079 * will contain the diagonal and superdiagonal elements of a 00080 * bidiagonal matrix orthogonally equivalent to the one given 00081 * as input. 00082 * 00083 * VT (input/output) COMPLEX array, dimension (LDVT, NCVT) 00084 * On entry, an N-by-NCVT matrix VT. 00085 * On exit, VT is overwritten by P**H * VT. 00086 * Not referenced if NCVT = 0. 00087 * 00088 * LDVT (input) INTEGER 00089 * The leading dimension of the array VT. 00090 * LDVT >= max(1,N) if NCVT > 0; LDVT >= 1 if NCVT = 0. 00091 * 00092 * U (input/output) COMPLEX array, dimension (LDU, N) 00093 * On entry, an NRU-by-N matrix U. 00094 * On exit, U is overwritten by U * Q. 00095 * Not referenced if NRU = 0. 00096 * 00097 * LDU (input) INTEGER 00098 * The leading dimension of the array U. LDU >= max(1,NRU). 00099 * 00100 * C (input/output) COMPLEX array, dimension (LDC, NCC) 00101 * On entry, an N-by-NCC matrix C. 00102 * On exit, C is overwritten by Q**H * C. 00103 * Not referenced if NCC = 0. 00104 * 00105 * LDC (input) INTEGER 00106 * The leading dimension of the array C. 00107 * LDC >= max(1,N) if NCC > 0; LDC >=1 if NCC = 0. 00108 * 00109 * RWORK (workspace) REAL array, dimension (2*N) 00110 * if NCVT = NRU = NCC = 0, (max(1, 4*N-4)) otherwise 00111 * 00112 * INFO (output) INTEGER 00113 * = 0: successful exit 00114 * < 0: If INFO = -i, the i-th argument had an illegal value 00115 * > 0: the algorithm did not converge; D and E contain the 00116 * elements of a bidiagonal matrix which is orthogonally 00117 * similar to the input matrix B; if INFO = i, i 00118 * elements of E have not converged to zero. 00119 * 00120 * Internal Parameters 00121 * =================== 00122 * 00123 * TOLMUL REAL, default = max(10,min(100,EPS**(-1/8))) 00124 * TOLMUL controls the convergence criterion of the QR loop. 00125 * If it is positive, TOLMUL*EPS is the desired relative 00126 * precision in the computed singular values. 00127 * If it is negative, abs(TOLMUL*EPS*sigma_max) is the 00128 * desired absolute accuracy in the computed singular 00129 * values (corresponds to relative accuracy 00130 * abs(TOLMUL*EPS) in the largest singular value. 00131 * abs(TOLMUL) should be between 1 and 1/EPS, and preferably 00132 * between 10 (for fast convergence) and .1/EPS 00133 * (for there to be some accuracy in the results). 00134 * Default is to lose at either one eighth or 2 of the 00135 * available decimal digits in each computed singular value 00136 * (whichever is smaller). 00137 * 00138 * MAXITR INTEGER, default = 6 00139 * MAXITR controls the maximum number of passes of the 00140 * algorithm through its inner loop. The algorithms stops 00141 * (and so fails to converge) if the number of passes 00142 * through the inner loop exceeds MAXITR*N**2. 00143 * 00144 * ===================================================================== 00145 * 00146 * .. Parameters .. 00147 REAL ZERO 00148 PARAMETER ( ZERO = 0.0E0 ) 00149 REAL ONE 00150 PARAMETER ( ONE = 1.0E0 ) 00151 REAL NEGONE 00152 PARAMETER ( NEGONE = -1.0E0 ) 00153 REAL HNDRTH 00154 PARAMETER ( HNDRTH = 0.01E0 ) 00155 REAL TEN 00156 PARAMETER ( TEN = 10.0E0 ) 00157 REAL HNDRD 00158 PARAMETER ( HNDRD = 100.0E0 ) 00159 REAL MEIGTH 00160 PARAMETER ( MEIGTH = -0.125E0 ) 00161 INTEGER MAXITR 00162 PARAMETER ( MAXITR = 6 ) 00163 * .. 00164 * .. Local Scalars .. 00165 LOGICAL LOWER, ROTATE 00166 INTEGER I, IDIR, ISUB, ITER, J, LL, LLL, M, MAXIT, NM1, 00167 $ NM12, NM13, OLDLL, OLDM 00168 REAL ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU, 00169 $ OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL, 00170 $ SINR, SLL, SMAX, SMIN, SMINL, SMINOA, 00171 $ SN, THRESH, TOL, TOLMUL, UNFL 00172 * .. 00173 * .. External Functions .. 00174 LOGICAL LSAME 00175 REAL SLAMCH 00176 EXTERNAL LSAME, SLAMCH 00177 * .. 00178 * .. External Subroutines .. 00179 EXTERNAL CLASR, CSROT, CSSCAL, CSWAP, SLARTG, SLAS2, 00180 $ SLASQ1, SLASV2, XERBLA 00181 * .. 00182 * .. Intrinsic Functions .. 00183 INTRINSIC ABS, MAX, MIN, REAL, SIGN, SQRT 00184 * .. 00185 * .. Executable Statements .. 00186 * 00187 * Test the input parameters. 00188 * 00189 INFO = 0 00190 LOWER = LSAME( UPLO, 'L' ) 00191 IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LOWER ) THEN 00192 INFO = -1 00193 ELSE IF( N.LT.0 ) THEN 00194 INFO = -2 00195 ELSE IF( NCVT.LT.0 ) THEN 00196 INFO = -3 00197 ELSE IF( NRU.LT.0 ) THEN 00198 INFO = -4 00199 ELSE IF( NCC.LT.0 ) THEN 00200 INFO = -5 00201 ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR. 00202 $ ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN 00203 INFO = -9 00204 ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN 00205 INFO = -11 00206 ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR. 00207 $ ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN 00208 INFO = -13 00209 END IF 00210 IF( INFO.NE.0 ) THEN 00211 CALL XERBLA( 'CBDSQR', -INFO ) 00212 RETURN 00213 END IF 00214 IF( N.EQ.0 ) 00215 $ RETURN 00216 IF( N.EQ.1 ) 00217 $ GO TO 160 00218 * 00219 * ROTATE is true if any singular vectors desired, false otherwise 00220 * 00221 ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 ) 00222 * 00223 * If no singular vectors desired, use qd algorithm 00224 * 00225 IF( .NOT.ROTATE ) THEN 00226 CALL SLASQ1( N, D, E, RWORK, INFO ) 00227 RETURN 00228 END IF 00229 * 00230 NM1 = N - 1 00231 NM12 = NM1 + NM1 00232 NM13 = NM12 + NM1 00233 IDIR = 0 00234 * 00235 * Get machine constants 00236 * 00237 EPS = SLAMCH( 'Epsilon' ) 00238 UNFL = SLAMCH( 'Safe minimum' ) 00239 * 00240 * If matrix lower bidiagonal, rotate to be upper bidiagonal 00241 * by applying Givens rotations on the left 00242 * 00243 IF( LOWER ) THEN 00244 DO 10 I = 1, N - 1 00245 CALL SLARTG( D( I ), E( I ), CS, SN, R ) 00246 D( I ) = R 00247 E( I ) = SN*D( I+1 ) 00248 D( I+1 ) = CS*D( I+1 ) 00249 RWORK( I ) = CS 00250 RWORK( NM1+I ) = SN 00251 10 CONTINUE 00252 * 00253 * Update singular vectors if desired 00254 * 00255 IF( NRU.GT.0 ) 00256 $ CALL CLASR( 'R', 'V', 'F', NRU, N, RWORK( 1 ), RWORK( N ), 00257 $ U, LDU ) 00258 IF( NCC.GT.0 ) 00259 $ CALL CLASR( 'L', 'V', 'F', N, NCC, RWORK( 1 ), RWORK( N ), 00260 $ C, LDC ) 00261 END IF 00262 * 00263 * Compute singular values to relative accuracy TOL 00264 * (By setting TOL to be negative, algorithm will compute 00265 * singular values to absolute accuracy ABS(TOL)*norm(input matrix)) 00266 * 00267 TOLMUL = MAX( TEN, MIN( HNDRD, EPS**MEIGTH ) ) 00268 TOL = TOLMUL*EPS 00269 * 00270 * Compute approximate maximum, minimum singular values 00271 * 00272 SMAX = ZERO 00273 DO 20 I = 1, N 00274 SMAX = MAX( SMAX, ABS( D( I ) ) ) 00275 20 CONTINUE 00276 DO 30 I = 1, N - 1 00277 SMAX = MAX( SMAX, ABS( E( I ) ) ) 00278 30 CONTINUE 00279 SMINL = ZERO 00280 IF( TOL.GE.ZERO ) THEN 00281 * 00282 * Relative accuracy desired 00283 * 00284 SMINOA = ABS( D( 1 ) ) 00285 IF( SMINOA.EQ.ZERO ) 00286 $ GO TO 50 00287 MU = SMINOA 00288 DO 40 I = 2, N 00289 MU = ABS( D( I ) )*( MU / ( MU+ABS( E( I-1 ) ) ) ) 00290 SMINOA = MIN( SMINOA, MU ) 00291 IF( SMINOA.EQ.ZERO ) 00292 $ GO TO 50 00293 40 CONTINUE 00294 50 CONTINUE 00295 SMINOA = SMINOA / SQRT( REAL( N ) ) 00296 THRESH = MAX( TOL*SMINOA, MAXITR*N*N*UNFL ) 00297 ELSE 00298 * 00299 * Absolute accuracy desired 00300 * 00301 THRESH = MAX( ABS( TOL )*SMAX, MAXITR*N*N*UNFL ) 00302 END IF 00303 * 00304 * Prepare for main iteration loop for the singular values 00305 * (MAXIT is the maximum number of passes through the inner 00306 * loop permitted before nonconvergence signalled.) 00307 * 00308 MAXIT = MAXITR*N*N 00309 ITER = 0 00310 OLDLL = -1 00311 OLDM = -1 00312 * 00313 * M points to last element of unconverged part of matrix 00314 * 00315 M = N 00316 * 00317 * Begin main iteration loop 00318 * 00319 60 CONTINUE 00320 * 00321 * Check for convergence or exceeding iteration count 00322 * 00323 IF( M.LE.1 ) 00324 $ GO TO 160 00325 IF( ITER.GT.MAXIT ) 00326 $ GO TO 200 00327 * 00328 * Find diagonal block of matrix to work on 00329 * 00330 IF( TOL.LT.ZERO .AND. ABS( D( M ) ).LE.THRESH ) 00331 $ D( M ) = ZERO 00332 SMAX = ABS( D( M ) ) 00333 SMIN = SMAX 00334 DO 70 LLL = 1, M - 1 00335 LL = M - LLL 00336 ABSS = ABS( D( LL ) ) 00337 ABSE = ABS( E( LL ) ) 00338 IF( TOL.LT.ZERO .AND. ABSS.LE.THRESH ) 00339 $ D( LL ) = ZERO 00340 IF( ABSE.LE.THRESH ) 00341 $ GO TO 80 00342 SMIN = MIN( SMIN, ABSS ) 00343 SMAX = MAX( SMAX, ABSS, ABSE ) 00344 70 CONTINUE 00345 LL = 0 00346 GO TO 90 00347 80 CONTINUE 00348 E( LL ) = ZERO 00349 * 00350 * Matrix splits since E(LL) = 0 00351 * 00352 IF( LL.EQ.M-1 ) THEN 00353 * 00354 * Convergence of bottom singular value, return to top of loop 00355 * 00356 M = M - 1 00357 GO TO 60 00358 END IF 00359 90 CONTINUE 00360 LL = LL + 1 00361 * 00362 * E(LL) through E(M-1) are nonzero, E(LL-1) is zero 00363 * 00364 IF( LL.EQ.M-1 ) THEN 00365 * 00366 * 2 by 2 block, handle separately 00367 * 00368 CALL SLASV2( D( M-1 ), E( M-1 ), D( M ), SIGMN, SIGMX, SINR, 00369 $ COSR, SINL, COSL ) 00370 D( M-1 ) = SIGMX 00371 E( M-1 ) = ZERO 00372 D( M ) = SIGMN 00373 * 00374 * Compute singular vectors, if desired 00375 * 00376 IF( NCVT.GT.0 ) 00377 $ CALL CSROT( NCVT, VT( M-1, 1 ), LDVT, VT( M, 1 ), LDVT, 00378 $ COSR, SINR ) 00379 IF( NRU.GT.0 ) 00380 $ CALL CSROT( NRU, U( 1, M-1 ), 1, U( 1, M ), 1, COSL, SINL ) 00381 IF( NCC.GT.0 ) 00382 $ CALL CSROT( NCC, C( M-1, 1 ), LDC, C( M, 1 ), LDC, COSL, 00383 $ SINL ) 00384 M = M - 2 00385 GO TO 60 00386 END IF 00387 * 00388 * If working on new submatrix, choose shift direction 00389 * (from larger end diagonal element towards smaller) 00390 * 00391 IF( LL.GT.OLDM .OR. M.LT.OLDLL ) THEN 00392 IF( ABS( D( LL ) ).GE.ABS( D( M ) ) ) THEN 00393 * 00394 * Chase bulge from top (big end) to bottom (small end) 00395 * 00396 IDIR = 1 00397 ELSE 00398 * 00399 * Chase bulge from bottom (big end) to top (small end) 00400 * 00401 IDIR = 2 00402 END IF 00403 END IF 00404 * 00405 * Apply convergence tests 00406 * 00407 IF( IDIR.EQ.1 ) THEN 00408 * 00409 * Run convergence test in forward direction 00410 * First apply standard test to bottom of matrix 00411 * 00412 IF( ABS( E( M-1 ) ).LE.ABS( TOL )*ABS( D( M ) ) .OR. 00413 $ ( TOL.LT.ZERO .AND. ABS( E( M-1 ) ).LE.THRESH ) ) THEN 00414 E( M-1 ) = ZERO 00415 GO TO 60 00416 END IF 00417 * 00418 IF( TOL.GE.ZERO ) THEN 00419 * 00420 * If relative accuracy desired, 00421 * apply convergence criterion forward 00422 * 00423 MU = ABS( D( LL ) ) 00424 SMINL = MU 00425 DO 100 LLL = LL, M - 1 00426 IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN 00427 E( LLL ) = ZERO 00428 GO TO 60 00429 END IF 00430 MU = ABS( D( LLL+1 ) )*( MU / ( MU+ABS( E( LLL ) ) ) ) 00431 SMINL = MIN( SMINL, MU ) 00432 100 CONTINUE 00433 END IF 00434 * 00435 ELSE 00436 * 00437 * Run convergence test in backward direction 00438 * First apply standard test to top of matrix 00439 * 00440 IF( ABS( E( LL ) ).LE.ABS( TOL )*ABS( D( LL ) ) .OR. 00441 $ ( TOL.LT.ZERO .AND. ABS( E( LL ) ).LE.THRESH ) ) THEN 00442 E( LL ) = ZERO 00443 GO TO 60 00444 END IF 00445 * 00446 IF( TOL.GE.ZERO ) THEN 00447 * 00448 * If relative accuracy desired, 00449 * apply convergence criterion backward 00450 * 00451 MU = ABS( D( M ) ) 00452 SMINL = MU 00453 DO 110 LLL = M - 1, LL, -1 00454 IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN 00455 E( LLL ) = ZERO 00456 GO TO 60 00457 END IF 00458 MU = ABS( D( LLL ) )*( MU / ( MU+ABS( E( LLL ) ) ) ) 00459 SMINL = MIN( SMINL, MU ) 00460 110 CONTINUE 00461 END IF 00462 END IF 00463 OLDLL = LL 00464 OLDM = M 00465 * 00466 * Compute shift. First, test if shifting would ruin relative 00467 * accuracy, and if so set the shift to zero. 00468 * 00469 IF( TOL.GE.ZERO .AND. N*TOL*( SMINL / SMAX ).LE. 00470 $ MAX( EPS, HNDRTH*TOL ) ) THEN 00471 * 00472 * Use a zero shift to avoid loss of relative accuracy 00473 * 00474 SHIFT = ZERO 00475 ELSE 00476 * 00477 * Compute the shift from 2-by-2 block at end of matrix 00478 * 00479 IF( IDIR.EQ.1 ) THEN 00480 SLL = ABS( D( LL ) ) 00481 CALL SLAS2( D( M-1 ), E( M-1 ), D( M ), SHIFT, R ) 00482 ELSE 00483 SLL = ABS( D( M ) ) 00484 CALL SLAS2( D( LL ), E( LL ), D( LL+1 ), SHIFT, R ) 00485 END IF 00486 * 00487 * Test if shift negligible, and if so set to zero 00488 * 00489 IF( SLL.GT.ZERO ) THEN 00490 IF( ( SHIFT / SLL )**2.LT.EPS ) 00491 $ SHIFT = ZERO 00492 END IF 00493 END IF 00494 * 00495 * Increment iteration count 00496 * 00497 ITER = ITER + M - LL 00498 * 00499 * If SHIFT = 0, do simplified QR iteration 00500 * 00501 IF( SHIFT.EQ.ZERO ) THEN 00502 IF( IDIR.EQ.1 ) THEN 00503 * 00504 * Chase bulge from top to bottom 00505 * Save cosines and sines for later singular vector updates 00506 * 00507 CS = ONE 00508 OLDCS = ONE 00509 DO 120 I = LL, M - 1 00510 CALL SLARTG( D( I )*CS, E( I ), CS, SN, R ) 00511 IF( I.GT.LL ) 00512 $ E( I-1 ) = OLDSN*R 00513 CALL SLARTG( OLDCS*R, D( I+1 )*SN, OLDCS, OLDSN, D( I ) ) 00514 RWORK( I-LL+1 ) = CS 00515 RWORK( I-LL+1+NM1 ) = SN 00516 RWORK( I-LL+1+NM12 ) = OLDCS 00517 RWORK( I-LL+1+NM13 ) = OLDSN 00518 120 CONTINUE 00519 H = D( M )*CS 00520 D( M ) = H*OLDCS 00521 E( M-1 ) = H*OLDSN 00522 * 00523 * Update singular vectors 00524 * 00525 IF( NCVT.GT.0 ) 00526 $ CALL CLASR( 'L', 'V', 'F', M-LL+1, NCVT, RWORK( 1 ), 00527 $ RWORK( N ), VT( LL, 1 ), LDVT ) 00528 IF( NRU.GT.0 ) 00529 $ CALL CLASR( 'R', 'V', 'F', NRU, M-LL+1, RWORK( NM12+1 ), 00530 $ RWORK( NM13+1 ), U( 1, LL ), LDU ) 00531 IF( NCC.GT.0 ) 00532 $ CALL CLASR( 'L', 'V', 'F', M-LL+1, NCC, RWORK( NM12+1 ), 00533 $ RWORK( NM13+1 ), C( LL, 1 ), LDC ) 00534 * 00535 * Test convergence 00536 * 00537 IF( ABS( E( M-1 ) ).LE.THRESH ) 00538 $ E( M-1 ) = ZERO 00539 * 00540 ELSE 00541 * 00542 * Chase bulge from bottom to top 00543 * Save cosines and sines for later singular vector updates 00544 * 00545 CS = ONE 00546 OLDCS = ONE 00547 DO 130 I = M, LL + 1, -1 00548 CALL SLARTG( D( I )*CS, E( I-1 ), CS, SN, R ) 00549 IF( I.LT.M ) 00550 $ E( I ) = OLDSN*R 00551 CALL SLARTG( OLDCS*R, D( I-1 )*SN, OLDCS, OLDSN, D( I ) ) 00552 RWORK( I-LL ) = CS 00553 RWORK( I-LL+NM1 ) = -SN 00554 RWORK( I-LL+NM12 ) = OLDCS 00555 RWORK( I-LL+NM13 ) = -OLDSN 00556 130 CONTINUE 00557 H = D( LL )*CS 00558 D( LL ) = H*OLDCS 00559 E( LL ) = H*OLDSN 00560 * 00561 * Update singular vectors 00562 * 00563 IF( NCVT.GT.0 ) 00564 $ CALL CLASR( 'L', 'V', 'B', M-LL+1, NCVT, RWORK( NM12+1 ), 00565 $ RWORK( NM13+1 ), VT( LL, 1 ), LDVT ) 00566 IF( NRU.GT.0 ) 00567 $ CALL CLASR( 'R', 'V', 'B', NRU, M-LL+1, RWORK( 1 ), 00568 $ RWORK( N ), U( 1, LL ), LDU ) 00569 IF( NCC.GT.0 ) 00570 $ CALL CLASR( 'L', 'V', 'B', M-LL+1, NCC, RWORK( 1 ), 00571 $ RWORK( N ), C( LL, 1 ), LDC ) 00572 * 00573 * Test convergence 00574 * 00575 IF( ABS( E( LL ) ).LE.THRESH ) 00576 $ E( LL ) = ZERO 00577 END IF 00578 ELSE 00579 * 00580 * Use nonzero shift 00581 * 00582 IF( IDIR.EQ.1 ) THEN 00583 * 00584 * Chase bulge from top to bottom 00585 * Save cosines and sines for later singular vector updates 00586 * 00587 F = ( ABS( D( LL ) )-SHIFT )* 00588 $ ( SIGN( ONE, D( LL ) )+SHIFT / D( LL ) ) 00589 G = E( LL ) 00590 DO 140 I = LL, M - 1 00591 CALL SLARTG( F, G, COSR, SINR, R ) 00592 IF( I.GT.LL ) 00593 $ E( I-1 ) = R 00594 F = COSR*D( I ) + SINR*E( I ) 00595 E( I ) = COSR*E( I ) - SINR*D( I ) 00596 G = SINR*D( I+1 ) 00597 D( I+1 ) = COSR*D( I+1 ) 00598 CALL SLARTG( F, G, COSL, SINL, R ) 00599 D( I ) = R 00600 F = COSL*E( I ) + SINL*D( I+1 ) 00601 D( I+1 ) = COSL*D( I+1 ) - SINL*E( I ) 00602 IF( I.LT.M-1 ) THEN 00603 G = SINL*E( I+1 ) 00604 E( I+1 ) = COSL*E( I+1 ) 00605 END IF 00606 RWORK( I-LL+1 ) = COSR 00607 RWORK( I-LL+1+NM1 ) = SINR 00608 RWORK( I-LL+1+NM12 ) = COSL 00609 RWORK( I-LL+1+NM13 ) = SINL 00610 140 CONTINUE 00611 E( M-1 ) = F 00612 * 00613 * Update singular vectors 00614 * 00615 IF( NCVT.GT.0 ) 00616 $ CALL CLASR( 'L', 'V', 'F', M-LL+1, NCVT, RWORK( 1 ), 00617 $ RWORK( N ), VT( LL, 1 ), LDVT ) 00618 IF( NRU.GT.0 ) 00619 $ CALL CLASR( 'R', 'V', 'F', NRU, M-LL+1, RWORK( NM12+1 ), 00620 $ RWORK( NM13+1 ), U( 1, LL ), LDU ) 00621 IF( NCC.GT.0 ) 00622 $ CALL CLASR( 'L', 'V', 'F', M-LL+1, NCC, RWORK( NM12+1 ), 00623 $ RWORK( NM13+1 ), C( LL, 1 ), LDC ) 00624 * 00625 * Test convergence 00626 * 00627 IF( ABS( E( M-1 ) ).LE.THRESH ) 00628 $ E( M-1 ) = ZERO 00629 * 00630 ELSE 00631 * 00632 * Chase bulge from bottom to top 00633 * Save cosines and sines for later singular vector updates 00634 * 00635 F = ( ABS( D( M ) )-SHIFT )*( SIGN( ONE, D( M ) )+SHIFT / 00636 $ D( M ) ) 00637 G = E( M-1 ) 00638 DO 150 I = M, LL + 1, -1 00639 CALL SLARTG( F, G, COSR, SINR, R ) 00640 IF( I.LT.M ) 00641 $ E( I ) = R 00642 F = COSR*D( I ) + SINR*E( I-1 ) 00643 E( I-1 ) = COSR*E( I-1 ) - SINR*D( I ) 00644 G = SINR*D( I-1 ) 00645 D( I-1 ) = COSR*D( I-1 ) 00646 CALL SLARTG( F, G, COSL, SINL, R ) 00647 D( I ) = R 00648 F = COSL*E( I-1 ) + SINL*D( I-1 ) 00649 D( I-1 ) = COSL*D( I-1 ) - SINL*E( I-1 ) 00650 IF( I.GT.LL+1 ) THEN 00651 G = SINL*E( I-2 ) 00652 E( I-2 ) = COSL*E( I-2 ) 00653 END IF 00654 RWORK( I-LL ) = COSR 00655 RWORK( I-LL+NM1 ) = -SINR 00656 RWORK( I-LL+NM12 ) = COSL 00657 RWORK( I-LL+NM13 ) = -SINL 00658 150 CONTINUE 00659 E( LL ) = F 00660 * 00661 * Test convergence 00662 * 00663 IF( ABS( E( LL ) ).LE.THRESH ) 00664 $ E( LL ) = ZERO 00665 * 00666 * Update singular vectors if desired 00667 * 00668 IF( NCVT.GT.0 ) 00669 $ CALL CLASR( 'L', 'V', 'B', M-LL+1, NCVT, RWORK( NM12+1 ), 00670 $ RWORK( NM13+1 ), VT( LL, 1 ), LDVT ) 00671 IF( NRU.GT.0 ) 00672 $ CALL CLASR( 'R', 'V', 'B', NRU, M-LL+1, RWORK( 1 ), 00673 $ RWORK( N ), U( 1, LL ), LDU ) 00674 IF( NCC.GT.0 ) 00675 $ CALL CLASR( 'L', 'V', 'B', M-LL+1, NCC, RWORK( 1 ), 00676 $ RWORK( N ), C( LL, 1 ), LDC ) 00677 END IF 00678 END IF 00679 * 00680 * QR iteration finished, go back and check convergence 00681 * 00682 GO TO 60 00683 * 00684 * All singular values converged, so make them positive 00685 * 00686 160 CONTINUE 00687 DO 170 I = 1, N 00688 IF( D( I ).LT.ZERO ) THEN 00689 D( I ) = -D( I ) 00690 * 00691 * Change sign of singular vectors, if desired 00692 * 00693 IF( NCVT.GT.0 ) 00694 $ CALL CSSCAL( NCVT, NEGONE, VT( I, 1 ), LDVT ) 00695 END IF 00696 170 CONTINUE 00697 * 00698 * Sort the singular values into decreasing order (insertion sort on 00699 * singular values, but only one transposition per singular vector) 00700 * 00701 DO 190 I = 1, N - 1 00702 * 00703 * Scan for smallest D(I) 00704 * 00705 ISUB = 1 00706 SMIN = D( 1 ) 00707 DO 180 J = 2, N + 1 - I 00708 IF( D( J ).LE.SMIN ) THEN 00709 ISUB = J 00710 SMIN = D( J ) 00711 END IF 00712 180 CONTINUE 00713 IF( ISUB.NE.N+1-I ) THEN 00714 * 00715 * Swap singular values and vectors 00716 * 00717 D( ISUB ) = D( N+1-I ) 00718 D( N+1-I ) = SMIN 00719 IF( NCVT.GT.0 ) 00720 $ CALL CSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( N+1-I, 1 ), 00721 $ LDVT ) 00722 IF( NRU.GT.0 ) 00723 $ CALL CSWAP( NRU, U( 1, ISUB ), 1, U( 1, N+1-I ), 1 ) 00724 IF( NCC.GT.0 ) 00725 $ CALL CSWAP( NCC, C( ISUB, 1 ), LDC, C( N+1-I, 1 ), LDC ) 00726 END IF 00727 190 CONTINUE 00728 GO TO 220 00729 * 00730 * Maximum number of iterations exceeded, failure to converge 00731 * 00732 200 CONTINUE 00733 INFO = 0 00734 DO 210 I = 1, N - 1 00735 IF( E( I ).NE.ZERO ) 00736 $ INFO = INFO + 1 00737 210 CONTINUE 00738 220 CONTINUE 00739 RETURN 00740 * 00741 * End of CBDSQR 00742 * 00743 END