Annotation of rpl/lapack/lapack/dlasd3.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE DLASD3( NL, NR, SQRE, K, D, Q, LDQ, DSIGMA, U, LDU, U2,
! 2: $ LDU2, VT, LDVT, VT2, LDVT2, IDXC, CTOT, Z,
! 3: $ INFO )
! 4: *
! 5: * -- LAPACK auxiliary routine (version 3.2) --
! 6: * -- LAPACK is a software package provided by Univ. of Tennessee, --
! 7: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! 8: * November 2006
! 9: *
! 10: * .. Scalar Arguments ..
! 11: INTEGER INFO, K, LDQ, LDU, LDU2, LDVT, LDVT2, NL, NR,
! 12: $ SQRE
! 13: * ..
! 14: * .. Array Arguments ..
! 15: INTEGER CTOT( * ), IDXC( * )
! 16: DOUBLE PRECISION D( * ), DSIGMA( * ), Q( LDQ, * ), U( LDU, * ),
! 17: $ U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),
! 18: $ Z( * )
! 19: * ..
! 20: *
! 21: * Purpose
! 22: * =======
! 23: *
! 24: * DLASD3 finds all the square roots of the roots of the secular
! 25: * equation, as defined by the values in D and Z. It makes the
! 26: * appropriate calls to DLASD4 and then updates the singular
! 27: * vectors by matrix multiplication.
! 28: *
! 29: * This code makes very mild assumptions about floating point
! 30: * arithmetic. It will work on machines with a guard digit in
! 31: * add/subtract, or on those binary machines without guard digits
! 32: * which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.
! 33: * It could conceivably fail on hexadecimal or decimal machines
! 34: * without guard digits, but we know of none.
! 35: *
! 36: * DLASD3 is called from DLASD1.
! 37: *
! 38: * Arguments
! 39: * =========
! 40: *
! 41: * NL (input) INTEGER
! 42: * The row dimension of the upper block. NL >= 1.
! 43: *
! 44: * NR (input) INTEGER
! 45: * The row dimension of the lower block. NR >= 1.
! 46: *
! 47: * SQRE (input) INTEGER
! 48: * = 0: the lower block is an NR-by-NR square matrix.
! 49: * = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
! 50: *
! 51: * The bidiagonal matrix has N = NL + NR + 1 rows and
! 52: * M = N + SQRE >= N columns.
! 53: *
! 54: * K (input) INTEGER
! 55: * The size of the secular equation, 1 =< K = < N.
! 56: *
! 57: * D (output) DOUBLE PRECISION array, dimension(K)
! 58: * On exit the square roots of the roots of the secular equation,
! 59: * in ascending order.
! 60: *
! 61: * Q (workspace) DOUBLE PRECISION array,
! 62: * dimension at least (LDQ,K).
! 63: *
! 64: * LDQ (input) INTEGER
! 65: * The leading dimension of the array Q. LDQ >= K.
! 66: *
! 67: * DSIGMA (input) DOUBLE PRECISION array, dimension(K)
! 68: * The first K elements of this array contain the old roots
! 69: * of the deflated updating problem. These are the poles
! 70: * of the secular equation.
! 71: *
! 72: * U (output) DOUBLE PRECISION array, dimension (LDU, N)
! 73: * The last N - K columns of this matrix contain the deflated
! 74: * left singular vectors.
! 75: *
! 76: * LDU (input) INTEGER
! 77: * The leading dimension of the array U. LDU >= N.
! 78: *
! 79: * U2 (input/output) DOUBLE PRECISION array, dimension (LDU2, N)
! 80: * The first K columns of this matrix contain the non-deflated
! 81: * left singular vectors for the split problem.
! 82: *
! 83: * LDU2 (input) INTEGER
! 84: * The leading dimension of the array U2. LDU2 >= N.
! 85: *
! 86: * VT (output) DOUBLE PRECISION array, dimension (LDVT, M)
! 87: * The last M - K columns of VT' contain the deflated
! 88: * right singular vectors.
! 89: *
! 90: * LDVT (input) INTEGER
! 91: * The leading dimension of the array VT. LDVT >= N.
! 92: *
! 93: * VT2 (input/output) DOUBLE PRECISION array, dimension (LDVT2, N)
! 94: * The first K columns of VT2' contain the non-deflated
! 95: * right singular vectors for the split problem.
! 96: *
! 97: * LDVT2 (input) INTEGER
! 98: * The leading dimension of the array VT2. LDVT2 >= N.
! 99: *
! 100: * IDXC (input) INTEGER array, dimension ( N )
! 101: * The permutation used to arrange the columns of U (and rows of
! 102: * VT) into three groups: the first group contains non-zero
! 103: * entries only at and above (or before) NL +1; the second
! 104: * contains non-zero entries only at and below (or after) NL+2;
! 105: * and the third is dense. The first column of U and the row of
! 106: * VT are treated separately, however.
! 107: *
! 108: * The rows of the singular vectors found by DLASD4
! 109: * must be likewise permuted before the matrix multiplies can
! 110: * take place.
! 111: *
! 112: * CTOT (input) INTEGER array, dimension ( 4 )
! 113: * A count of the total number of the various types of columns
! 114: * in U (or rows in VT), as described in IDXC. The fourth column
! 115: * type is any column which has been deflated.
! 116: *
! 117: * Z (input) DOUBLE PRECISION array, dimension (K)
! 118: * The first K elements of this array contain the components
! 119: * of the deflation-adjusted updating row vector.
! 120: *
! 121: * INFO (output) INTEGER
! 122: * = 0: successful exit.
! 123: * < 0: if INFO = -i, the i-th argument had an illegal value.
! 124: * > 0: if INFO = 1, an singular value did not converge
! 125: *
! 126: * Further Details
! 127: * ===============
! 128: *
! 129: * Based on contributions by
! 130: * Ming Gu and Huan Ren, Computer Science Division, University of
! 131: * California at Berkeley, USA
! 132: *
! 133: * =====================================================================
! 134: *
! 135: * .. Parameters ..
! 136: DOUBLE PRECISION ONE, ZERO, NEGONE
! 137: PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0,
! 138: $ NEGONE = -1.0D+0 )
! 139: * ..
! 140: * .. Local Scalars ..
! 141: INTEGER CTEMP, I, J, JC, KTEMP, M, N, NLP1, NLP2, NRP1
! 142: DOUBLE PRECISION RHO, TEMP
! 143: * ..
! 144: * .. External Functions ..
! 145: DOUBLE PRECISION DLAMC3, DNRM2
! 146: EXTERNAL DLAMC3, DNRM2
! 147: * ..
! 148: * .. External Subroutines ..
! 149: EXTERNAL DCOPY, DGEMM, DLACPY, DLASCL, DLASD4, XERBLA
! 150: * ..
! 151: * .. Intrinsic Functions ..
! 152: INTRINSIC ABS, SIGN, SQRT
! 153: * ..
! 154: * .. Executable Statements ..
! 155: *
! 156: * Test the input parameters.
! 157: *
! 158: INFO = 0
! 159: *
! 160: IF( NL.LT.1 ) THEN
! 161: INFO = -1
! 162: ELSE IF( NR.LT.1 ) THEN
! 163: INFO = -2
! 164: ELSE IF( ( SQRE.NE.1 ) .AND. ( SQRE.NE.0 ) ) THEN
! 165: INFO = -3
! 166: END IF
! 167: *
! 168: N = NL + NR + 1
! 169: M = N + SQRE
! 170: NLP1 = NL + 1
! 171: NLP2 = NL + 2
! 172: *
! 173: IF( ( K.LT.1 ) .OR. ( K.GT.N ) ) THEN
! 174: INFO = -4
! 175: ELSE IF( LDQ.LT.K ) THEN
! 176: INFO = -7
! 177: ELSE IF( LDU.LT.N ) THEN
! 178: INFO = -10
! 179: ELSE IF( LDU2.LT.N ) THEN
! 180: INFO = -12
! 181: ELSE IF( LDVT.LT.M ) THEN
! 182: INFO = -14
! 183: ELSE IF( LDVT2.LT.M ) THEN
! 184: INFO = -16
! 185: END IF
! 186: IF( INFO.NE.0 ) THEN
! 187: CALL XERBLA( 'DLASD3', -INFO )
! 188: RETURN
! 189: END IF
! 190: *
! 191: * Quick return if possible
! 192: *
! 193: IF( K.EQ.1 ) THEN
! 194: D( 1 ) = ABS( Z( 1 ) )
! 195: CALL DCOPY( M, VT2( 1, 1 ), LDVT2, VT( 1, 1 ), LDVT )
! 196: IF( Z( 1 ).GT.ZERO ) THEN
! 197: CALL DCOPY( N, U2( 1, 1 ), 1, U( 1, 1 ), 1 )
! 198: ELSE
! 199: DO 10 I = 1, N
! 200: U( I, 1 ) = -U2( I, 1 )
! 201: 10 CONTINUE
! 202: END IF
! 203: RETURN
! 204: END IF
! 205: *
! 206: * Modify values DSIGMA(i) to make sure all DSIGMA(i)-DSIGMA(j) can
! 207: * be computed with high relative accuracy (barring over/underflow).
! 208: * This is a problem on machines without a guard digit in
! 209: * add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).
! 210: * The following code replaces DSIGMA(I) by 2*DSIGMA(I)-DSIGMA(I),
! 211: * which on any of these machines zeros out the bottommost
! 212: * bit of DSIGMA(I) if it is 1; this makes the subsequent
! 213: * subtractions DSIGMA(I)-DSIGMA(J) unproblematic when cancellation
! 214: * occurs. On binary machines with a guard digit (almost all
! 215: * machines) it does not change DSIGMA(I) at all. On hexadecimal
! 216: * and decimal machines with a guard digit, it slightly
! 217: * changes the bottommost bits of DSIGMA(I). It does not account
! 218: * for hexadecimal or decimal machines without guard digits
! 219: * (we know of none). We use a subroutine call to compute
! 220: * 2*DSIGMA(I) to prevent optimizing compilers from eliminating
! 221: * this code.
! 222: *
! 223: DO 20 I = 1, K
! 224: DSIGMA( I ) = DLAMC3( DSIGMA( I ), DSIGMA( I ) ) - DSIGMA( I )
! 225: 20 CONTINUE
! 226: *
! 227: * Keep a copy of Z.
! 228: *
! 229: CALL DCOPY( K, Z, 1, Q, 1 )
! 230: *
! 231: * Normalize Z.
! 232: *
! 233: RHO = DNRM2( K, Z, 1 )
! 234: CALL DLASCL( 'G', 0, 0, RHO, ONE, K, 1, Z, K, INFO )
! 235: RHO = RHO*RHO
! 236: *
! 237: * Find the new singular values.
! 238: *
! 239: DO 30 J = 1, K
! 240: CALL DLASD4( K, J, DSIGMA, Z, U( 1, J ), RHO, D( J ),
! 241: $ VT( 1, J ), INFO )
! 242: *
! 243: * If the zero finder fails, the computation is terminated.
! 244: *
! 245: IF( INFO.NE.0 ) THEN
! 246: RETURN
! 247: END IF
! 248: 30 CONTINUE
! 249: *
! 250: * Compute updated Z.
! 251: *
! 252: DO 60 I = 1, K
! 253: Z( I ) = U( I, K )*VT( I, K )
! 254: DO 40 J = 1, I - 1
! 255: Z( I ) = Z( I )*( U( I, J )*VT( I, J ) /
! 256: $ ( DSIGMA( I )-DSIGMA( J ) ) /
! 257: $ ( DSIGMA( I )+DSIGMA( J ) ) )
! 258: 40 CONTINUE
! 259: DO 50 J = I, K - 1
! 260: Z( I ) = Z( I )*( U( I, J )*VT( I, J ) /
! 261: $ ( DSIGMA( I )-DSIGMA( J+1 ) ) /
! 262: $ ( DSIGMA( I )+DSIGMA( J+1 ) ) )
! 263: 50 CONTINUE
! 264: Z( I ) = SIGN( SQRT( ABS( Z( I ) ) ), Q( I, 1 ) )
! 265: 60 CONTINUE
! 266: *
! 267: * Compute left singular vectors of the modified diagonal matrix,
! 268: * and store related information for the right singular vectors.
! 269: *
! 270: DO 90 I = 1, K
! 271: VT( 1, I ) = Z( 1 ) / U( 1, I ) / VT( 1, I )
! 272: U( 1, I ) = NEGONE
! 273: DO 70 J = 2, K
! 274: VT( J, I ) = Z( J ) / U( J, I ) / VT( J, I )
! 275: U( J, I ) = DSIGMA( J )*VT( J, I )
! 276: 70 CONTINUE
! 277: TEMP = DNRM2( K, U( 1, I ), 1 )
! 278: Q( 1, I ) = U( 1, I ) / TEMP
! 279: DO 80 J = 2, K
! 280: JC = IDXC( J )
! 281: Q( J, I ) = U( JC, I ) / TEMP
! 282: 80 CONTINUE
! 283: 90 CONTINUE
! 284: *
! 285: * Update the left singular vector matrix.
! 286: *
! 287: IF( K.EQ.2 ) THEN
! 288: CALL DGEMM( 'N', 'N', N, K, K, ONE, U2, LDU2, Q, LDQ, ZERO, U,
! 289: $ LDU )
! 290: GO TO 100
! 291: END IF
! 292: IF( CTOT( 1 ).GT.0 ) THEN
! 293: CALL DGEMM( 'N', 'N', NL, K, CTOT( 1 ), ONE, U2( 1, 2 ), LDU2,
! 294: $ Q( 2, 1 ), LDQ, ZERO, U( 1, 1 ), LDU )
! 295: IF( CTOT( 3 ).GT.0 ) THEN
! 296: KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )
! 297: CALL DGEMM( 'N', 'N', NL, K, CTOT( 3 ), ONE, U2( 1, KTEMP ),
! 298: $ LDU2, Q( KTEMP, 1 ), LDQ, ONE, U( 1, 1 ), LDU )
! 299: END IF
! 300: ELSE IF( CTOT( 3 ).GT.0 ) THEN
! 301: KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )
! 302: CALL DGEMM( 'N', 'N', NL, K, CTOT( 3 ), ONE, U2( 1, KTEMP ),
! 303: $ LDU2, Q( KTEMP, 1 ), LDQ, ZERO, U( 1, 1 ), LDU )
! 304: ELSE
! 305: CALL DLACPY( 'F', NL, K, U2, LDU2, U, LDU )
! 306: END IF
! 307: CALL DCOPY( K, Q( 1, 1 ), LDQ, U( NLP1, 1 ), LDU )
! 308: KTEMP = 2 + CTOT( 1 )
! 309: CTEMP = CTOT( 2 ) + CTOT( 3 )
! 310: CALL DGEMM( 'N', 'N', NR, K, CTEMP, ONE, U2( NLP2, KTEMP ), LDU2,
! 311: $ Q( KTEMP, 1 ), LDQ, ZERO, U( NLP2, 1 ), LDU )
! 312: *
! 313: * Generate the right singular vectors.
! 314: *
! 315: 100 CONTINUE
! 316: DO 120 I = 1, K
! 317: TEMP = DNRM2( K, VT( 1, I ), 1 )
! 318: Q( I, 1 ) = VT( 1, I ) / TEMP
! 319: DO 110 J = 2, K
! 320: JC = IDXC( J )
! 321: Q( I, J ) = VT( JC, I ) / TEMP
! 322: 110 CONTINUE
! 323: 120 CONTINUE
! 324: *
! 325: * Update the right singular vector matrix.
! 326: *
! 327: IF( K.EQ.2 ) THEN
! 328: CALL DGEMM( 'N', 'N', K, M, K, ONE, Q, LDQ, VT2, LDVT2, ZERO,
! 329: $ VT, LDVT )
! 330: RETURN
! 331: END IF
! 332: KTEMP = 1 + CTOT( 1 )
! 333: CALL DGEMM( 'N', 'N', K, NLP1, KTEMP, ONE, Q( 1, 1 ), LDQ,
! 334: $ VT2( 1, 1 ), LDVT2, ZERO, VT( 1, 1 ), LDVT )
! 335: KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )
! 336: IF( KTEMP.LE.LDVT2 )
! 337: $ CALL DGEMM( 'N', 'N', K, NLP1, CTOT( 3 ), ONE, Q( 1, KTEMP ),
! 338: $ LDQ, VT2( KTEMP, 1 ), LDVT2, ONE, VT( 1, 1 ),
! 339: $ LDVT )
! 340: *
! 341: KTEMP = CTOT( 1 ) + 1
! 342: NRP1 = NR + SQRE
! 343: IF( KTEMP.GT.1 ) THEN
! 344: DO 130 I = 1, K
! 345: Q( I, KTEMP ) = Q( I, 1 )
! 346: 130 CONTINUE
! 347: DO 140 I = NLP2, M
! 348: VT2( KTEMP, I ) = VT2( 1, I )
! 349: 140 CONTINUE
! 350: END IF
! 351: CTEMP = 1 + CTOT( 2 ) + CTOT( 3 )
! 352: CALL DGEMM( 'N', 'N', K, NRP1, CTEMP, ONE, Q( 1, KTEMP ), LDQ,
! 353: $ VT2( KTEMP, NLP2 ), LDVT2, ZERO, VT( 1, NLP2 ), LDVT )
! 354: *
! 355: RETURN
! 356: *
! 357: * End of DLASD3
! 358: *
! 359: END
CVSweb interface <joel.bertrand@systella.fr>