LAPACK 3.3.1
Linear Algebra PACKage
|
00001 SUBROUTINE ZLALSA( ICOMPQ, SMLSIZ, N, NRHS, B, LDB, BX, LDBX, U, 00002 $ LDU, VT, K, DIFL, DIFR, Z, POLES, GIVPTR, 00003 $ GIVCOL, LDGCOL, PERM, GIVNUM, C, S, RWORK, 00004 $ IWORK, INFO ) 00005 * 00006 * -- LAPACK routine (version 3.2) -- 00007 * -- LAPACK is a software package provided by Univ. of Tennessee, -- 00008 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 00009 * November 2006 00010 * 00011 * .. Scalar Arguments .. 00012 INTEGER ICOMPQ, INFO, LDB, LDBX, LDGCOL, LDU, N, NRHS, 00013 $ SMLSIZ 00014 * .. 00015 * .. Array Arguments .. 00016 INTEGER GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ), 00017 $ K( * ), PERM( LDGCOL, * ) 00018 DOUBLE PRECISION C( * ), DIFL( LDU, * ), DIFR( LDU, * ), 00019 $ GIVNUM( LDU, * ), POLES( LDU, * ), RWORK( * ), 00020 $ S( * ), U( LDU, * ), VT( LDU, * ), Z( LDU, * ) 00021 COMPLEX*16 B( LDB, * ), BX( LDBX, * ) 00022 * .. 00023 * 00024 * Purpose 00025 * ======= 00026 * 00027 * ZLALSA is an itermediate step in solving the least squares problem 00028 * by computing the SVD of the coefficient matrix in compact form (The 00029 * singular vectors are computed as products of simple orthorgonal 00030 * matrices.). 00031 * 00032 * If ICOMPQ = 0, ZLALSA applies the inverse of the left singular vector 00033 * matrix of an upper bidiagonal matrix to the right hand side; and if 00034 * ICOMPQ = 1, ZLALSA applies the right singular vector matrix to the 00035 * right hand side. The singular vector matrices were generated in 00036 * compact form by ZLALSA. 00037 * 00038 * Arguments 00039 * ========= 00040 * 00041 * ICOMPQ (input) INTEGER 00042 * Specifies whether the left or the right singular vector 00043 * matrix is involved. 00044 * = 0: Left singular vector matrix 00045 * = 1: Right singular vector matrix 00046 * 00047 * SMLSIZ (input) INTEGER 00048 * The maximum size of the subproblems at the bottom of the 00049 * computation tree. 00050 * 00051 * N (input) INTEGER 00052 * The row and column dimensions of the upper bidiagonal matrix. 00053 * 00054 * NRHS (input) INTEGER 00055 * The number of columns of B and BX. NRHS must be at least 1. 00056 * 00057 * B (input/output) COMPLEX*16 array, dimension ( LDB, NRHS ) 00058 * On input, B contains the right hand sides of the least 00059 * squares problem in rows 1 through M. 00060 * On output, B contains the solution X in rows 1 through N. 00061 * 00062 * LDB (input) INTEGER 00063 * The leading dimension of B in the calling subprogram. 00064 * LDB must be at least max(1,MAX( M, N ) ). 00065 * 00066 * BX (output) COMPLEX*16 array, dimension ( LDBX, NRHS ) 00067 * On exit, the result of applying the left or right singular 00068 * vector matrix to B. 00069 * 00070 * LDBX (input) INTEGER 00071 * The leading dimension of BX. 00072 * 00073 * U (input) DOUBLE PRECISION array, dimension ( LDU, SMLSIZ ). 00074 * On entry, U contains the left singular vector matrices of all 00075 * subproblems at the bottom level. 00076 * 00077 * LDU (input) INTEGER, LDU = > N. 00078 * The leading dimension of arrays U, VT, DIFL, DIFR, 00079 * POLES, GIVNUM, and Z. 00080 * 00081 * VT (input) DOUBLE PRECISION array, dimension ( LDU, SMLSIZ+1 ). 00082 * On entry, VT**H contains the right singular vector matrices of 00083 * all subproblems at the bottom level. 00084 * 00085 * K (input) INTEGER array, dimension ( N ). 00086 * 00087 * DIFL (input) DOUBLE PRECISION array, dimension ( LDU, NLVL ). 00088 * where NLVL = INT(log_2 (N/(SMLSIZ+1))) + 1. 00089 * 00090 * DIFR (input) DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ). 00091 * On entry, DIFL(*, I) and DIFR(*, 2 * I -1) record 00092 * distances between singular values on the I-th level and 00093 * singular values on the (I -1)-th level, and DIFR(*, 2 * I) 00094 * record the normalizing factors of the right singular vectors 00095 * matrices of subproblems on I-th level. 00096 * 00097 * Z (input) DOUBLE PRECISION array, dimension ( LDU, NLVL ). 00098 * On entry, Z(1, I) contains the components of the deflation- 00099 * adjusted updating row vector for subproblems on the I-th 00100 * level. 00101 * 00102 * POLES (input) DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ). 00103 * On entry, POLES(*, 2 * I -1: 2 * I) contains the new and old 00104 * singular values involved in the secular equations on the I-th 00105 * level. 00106 * 00107 * GIVPTR (input) INTEGER array, dimension ( N ). 00108 * On entry, GIVPTR( I ) records the number of Givens 00109 * rotations performed on the I-th problem on the computation 00110 * tree. 00111 * 00112 * GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 * NLVL ). 00113 * On entry, for each I, GIVCOL(*, 2 * I - 1: 2 * I) records the 00114 * locations of Givens rotations performed on the I-th level on 00115 * the computation tree. 00116 * 00117 * LDGCOL (input) INTEGER, LDGCOL = > N. 00118 * The leading dimension of arrays GIVCOL and PERM. 00119 * 00120 * PERM (input) INTEGER array, dimension ( LDGCOL, NLVL ). 00121 * On entry, PERM(*, I) records permutations done on the I-th 00122 * level of the computation tree. 00123 * 00124 * GIVNUM (input) DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ). 00125 * On entry, GIVNUM(*, 2 *I -1 : 2 * I) records the C- and S- 00126 * values of Givens rotations performed on the I-th level on the 00127 * computation tree. 00128 * 00129 * C (input) DOUBLE PRECISION array, dimension ( N ). 00130 * On entry, if the I-th subproblem is not square, 00131 * C( I ) contains the C-value of a Givens rotation related to 00132 * the right null space of the I-th subproblem. 00133 * 00134 * S (input) DOUBLE PRECISION array, dimension ( N ). 00135 * On entry, if the I-th subproblem is not square, 00136 * S( I ) contains the S-value of a Givens rotation related to 00137 * the right null space of the I-th subproblem. 00138 * 00139 * RWORK (workspace) DOUBLE PRECISION array, dimension at least 00140 * MAX( (SMLSZ+1)*NRHS*3, N*(1+NRHS) + 2*NRHS ). 00141 * 00142 * IWORK (workspace) INTEGER array. 00143 * The dimension must be at least 3 * N 00144 * 00145 * INFO (output) INTEGER 00146 * = 0: successful exit. 00147 * < 0: if INFO = -i, the i-th argument had an illegal value. 00148 * 00149 * Further Details 00150 * =============== 00151 * 00152 * Based on contributions by 00153 * Ming Gu and Ren-Cang Li, Computer Science Division, University of 00154 * California at Berkeley, USA 00155 * Osni Marques, LBNL/NERSC, USA 00156 * 00157 * ===================================================================== 00158 * 00159 * .. Parameters .. 00160 DOUBLE PRECISION ZERO, ONE 00161 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) 00162 * .. 00163 * .. Local Scalars .. 00164 INTEGER I, I1, IC, IM1, INODE, J, JCOL, JIMAG, JREAL, 00165 $ JROW, LF, LL, LVL, LVL2, ND, NDB1, NDIML, 00166 $ NDIMR, NL, NLF, NLP1, NLVL, NR, NRF, NRP1, SQRE 00167 * .. 00168 * .. External Subroutines .. 00169 EXTERNAL DGEMM, DLASDT, XERBLA, ZCOPY, ZLALS0 00170 * .. 00171 * .. Intrinsic Functions .. 00172 INTRINSIC DBLE, DCMPLX, DIMAG 00173 * .. 00174 * .. Executable Statements .. 00175 * 00176 * Test the input parameters. 00177 * 00178 INFO = 0 00179 * 00180 IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN 00181 INFO = -1 00182 ELSE IF( SMLSIZ.LT.3 ) THEN 00183 INFO = -2 00184 ELSE IF( N.LT.SMLSIZ ) THEN 00185 INFO = -3 00186 ELSE IF( NRHS.LT.1 ) THEN 00187 INFO = -4 00188 ELSE IF( LDB.LT.N ) THEN 00189 INFO = -6 00190 ELSE IF( LDBX.LT.N ) THEN 00191 INFO = -8 00192 ELSE IF( LDU.LT.N ) THEN 00193 INFO = -10 00194 ELSE IF( LDGCOL.LT.N ) THEN 00195 INFO = -19 00196 END IF 00197 IF( INFO.NE.0 ) THEN 00198 CALL XERBLA( 'ZLALSA', -INFO ) 00199 RETURN 00200 END IF 00201 * 00202 * Book-keeping and setting up the computation tree. 00203 * 00204 INODE = 1 00205 NDIML = INODE + N 00206 NDIMR = NDIML + N 00207 * 00208 CALL DLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ), 00209 $ IWORK( NDIMR ), SMLSIZ ) 00210 * 00211 * The following code applies back the left singular vector factors. 00212 * For applying back the right singular vector factors, go to 170. 00213 * 00214 IF( ICOMPQ.EQ.1 ) THEN 00215 GO TO 170 00216 END IF 00217 * 00218 * The nodes on the bottom level of the tree were solved 00219 * by DLASDQ. The corresponding left and right singular vector 00220 * matrices are in explicit form. First apply back the left 00221 * singular vector matrices. 00222 * 00223 NDB1 = ( ND+1 ) / 2 00224 DO 130 I = NDB1, ND 00225 * 00226 * IC : center row of each node 00227 * NL : number of rows of left subproblem 00228 * NR : number of rows of right subproblem 00229 * NLF: starting row of the left subproblem 00230 * NRF: starting row of the right subproblem 00231 * 00232 I1 = I - 1 00233 IC = IWORK( INODE+I1 ) 00234 NL = IWORK( NDIML+I1 ) 00235 NR = IWORK( NDIMR+I1 ) 00236 NLF = IC - NL 00237 NRF = IC + 1 00238 * 00239 * Since B and BX are complex, the following call to DGEMM 00240 * is performed in two steps (real and imaginary parts). 00241 * 00242 * CALL DGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU, 00243 * $ B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX ) 00244 * 00245 J = NL*NRHS*2 00246 DO 20 JCOL = 1, NRHS 00247 DO 10 JROW = NLF, NLF + NL - 1 00248 J = J + 1 00249 RWORK( J ) = DBLE( B( JROW, JCOL ) ) 00250 10 CONTINUE 00251 20 CONTINUE 00252 CALL DGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU, 00253 $ RWORK( 1+NL*NRHS*2 ), NL, ZERO, RWORK( 1 ), NL ) 00254 J = NL*NRHS*2 00255 DO 40 JCOL = 1, NRHS 00256 DO 30 JROW = NLF, NLF + NL - 1 00257 J = J + 1 00258 RWORK( J ) = DIMAG( B( JROW, JCOL ) ) 00259 30 CONTINUE 00260 40 CONTINUE 00261 CALL DGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU, 00262 $ RWORK( 1+NL*NRHS*2 ), NL, ZERO, RWORK( 1+NL*NRHS ), 00263 $ NL ) 00264 JREAL = 0 00265 JIMAG = NL*NRHS 00266 DO 60 JCOL = 1, NRHS 00267 DO 50 JROW = NLF, NLF + NL - 1 00268 JREAL = JREAL + 1 00269 JIMAG = JIMAG + 1 00270 BX( JROW, JCOL ) = DCMPLX( RWORK( JREAL ), 00271 $ RWORK( JIMAG ) ) 00272 50 CONTINUE 00273 60 CONTINUE 00274 * 00275 * Since B and BX are complex, the following call to DGEMM 00276 * is performed in two steps (real and imaginary parts). 00277 * 00278 * CALL DGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU, 00279 * $ B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX ) 00280 * 00281 J = NR*NRHS*2 00282 DO 80 JCOL = 1, NRHS 00283 DO 70 JROW = NRF, NRF + NR - 1 00284 J = J + 1 00285 RWORK( J ) = DBLE( B( JROW, JCOL ) ) 00286 70 CONTINUE 00287 80 CONTINUE 00288 CALL DGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU, 00289 $ RWORK( 1+NR*NRHS*2 ), NR, ZERO, RWORK( 1 ), NR ) 00290 J = NR*NRHS*2 00291 DO 100 JCOL = 1, NRHS 00292 DO 90 JROW = NRF, NRF + NR - 1 00293 J = J + 1 00294 RWORK( J ) = DIMAG( B( JROW, JCOL ) ) 00295 90 CONTINUE 00296 100 CONTINUE 00297 CALL DGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU, 00298 $ RWORK( 1+NR*NRHS*2 ), NR, ZERO, RWORK( 1+NR*NRHS ), 00299 $ NR ) 00300 JREAL = 0 00301 JIMAG = NR*NRHS 00302 DO 120 JCOL = 1, NRHS 00303 DO 110 JROW = NRF, NRF + NR - 1 00304 JREAL = JREAL + 1 00305 JIMAG = JIMAG + 1 00306 BX( JROW, JCOL ) = DCMPLX( RWORK( JREAL ), 00307 $ RWORK( JIMAG ) ) 00308 110 CONTINUE 00309 120 CONTINUE 00310 * 00311 130 CONTINUE 00312 * 00313 * Next copy the rows of B that correspond to unchanged rows 00314 * in the bidiagonal matrix to BX. 00315 * 00316 DO 140 I = 1, ND 00317 IC = IWORK( INODE+I-1 ) 00318 CALL ZCOPY( NRHS, B( IC, 1 ), LDB, BX( IC, 1 ), LDBX ) 00319 140 CONTINUE 00320 * 00321 * Finally go through the left singular vector matrices of all 00322 * the other subproblems bottom-up on the tree. 00323 * 00324 J = 2**NLVL 00325 SQRE = 0 00326 * 00327 DO 160 LVL = NLVL, 1, -1 00328 LVL2 = 2*LVL - 1 00329 * 00330 * find the first node LF and last node LL on 00331 * the current level LVL 00332 * 00333 IF( LVL.EQ.1 ) THEN 00334 LF = 1 00335 LL = 1 00336 ELSE 00337 LF = 2**( LVL-1 ) 00338 LL = 2*LF - 1 00339 END IF 00340 DO 150 I = LF, LL 00341 IM1 = I - 1 00342 IC = IWORK( INODE+IM1 ) 00343 NL = IWORK( NDIML+IM1 ) 00344 NR = IWORK( NDIMR+IM1 ) 00345 NLF = IC - NL 00346 NRF = IC + 1 00347 J = J - 1 00348 CALL ZLALS0( ICOMPQ, NL, NR, SQRE, NRHS, BX( NLF, 1 ), LDBX, 00349 $ B( NLF, 1 ), LDB, PERM( NLF, LVL ), 00350 $ GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL, 00351 $ GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ), 00352 $ DIFL( NLF, LVL ), DIFR( NLF, LVL2 ), 00353 $ Z( NLF, LVL ), K( J ), C( J ), S( J ), RWORK, 00354 $ INFO ) 00355 150 CONTINUE 00356 160 CONTINUE 00357 GO TO 330 00358 * 00359 * ICOMPQ = 1: applying back the right singular vector factors. 00360 * 00361 170 CONTINUE 00362 * 00363 * First now go through the right singular vector matrices of all 00364 * the tree nodes top-down. 00365 * 00366 J = 0 00367 DO 190 LVL = 1, NLVL 00368 LVL2 = 2*LVL - 1 00369 * 00370 * Find the first node LF and last node LL on 00371 * the current level LVL. 00372 * 00373 IF( LVL.EQ.1 ) THEN 00374 LF = 1 00375 LL = 1 00376 ELSE 00377 LF = 2**( LVL-1 ) 00378 LL = 2*LF - 1 00379 END IF 00380 DO 180 I = LL, LF, -1 00381 IM1 = I - 1 00382 IC = IWORK( INODE+IM1 ) 00383 NL = IWORK( NDIML+IM1 ) 00384 NR = IWORK( NDIMR+IM1 ) 00385 NLF = IC - NL 00386 NRF = IC + 1 00387 IF( I.EQ.LL ) THEN 00388 SQRE = 0 00389 ELSE 00390 SQRE = 1 00391 END IF 00392 J = J + 1 00393 CALL ZLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B( NLF, 1 ), LDB, 00394 $ BX( NLF, 1 ), LDBX, PERM( NLF, LVL ), 00395 $ GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL, 00396 $ GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ), 00397 $ DIFL( NLF, LVL ), DIFR( NLF, LVL2 ), 00398 $ Z( NLF, LVL ), K( J ), C( J ), S( J ), RWORK, 00399 $ INFO ) 00400 180 CONTINUE 00401 190 CONTINUE 00402 * 00403 * The nodes on the bottom level of the tree were solved 00404 * by DLASDQ. The corresponding right singular vector 00405 * matrices are in explicit form. Apply them back. 00406 * 00407 NDB1 = ( ND+1 ) / 2 00408 DO 320 I = NDB1, ND 00409 I1 = I - 1 00410 IC = IWORK( INODE+I1 ) 00411 NL = IWORK( NDIML+I1 ) 00412 NR = IWORK( NDIMR+I1 ) 00413 NLP1 = NL + 1 00414 IF( I.EQ.ND ) THEN 00415 NRP1 = NR 00416 ELSE 00417 NRP1 = NR + 1 00418 END IF 00419 NLF = IC - NL 00420 NRF = IC + 1 00421 * 00422 * Since B and BX are complex, the following call to DGEMM is 00423 * performed in two steps (real and imaginary parts). 00424 * 00425 * CALL DGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU, 00426 * $ B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX ) 00427 * 00428 J = NLP1*NRHS*2 00429 DO 210 JCOL = 1, NRHS 00430 DO 200 JROW = NLF, NLF + NLP1 - 1 00431 J = J + 1 00432 RWORK( J ) = DBLE( B( JROW, JCOL ) ) 00433 200 CONTINUE 00434 210 CONTINUE 00435 CALL DGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU, 00436 $ RWORK( 1+NLP1*NRHS*2 ), NLP1, ZERO, RWORK( 1 ), 00437 $ NLP1 ) 00438 J = NLP1*NRHS*2 00439 DO 230 JCOL = 1, NRHS 00440 DO 220 JROW = NLF, NLF + NLP1 - 1 00441 J = J + 1 00442 RWORK( J ) = DIMAG( B( JROW, JCOL ) ) 00443 220 CONTINUE 00444 230 CONTINUE 00445 CALL DGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU, 00446 $ RWORK( 1+NLP1*NRHS*2 ), NLP1, ZERO, 00447 $ RWORK( 1+NLP1*NRHS ), NLP1 ) 00448 JREAL = 0 00449 JIMAG = NLP1*NRHS 00450 DO 250 JCOL = 1, NRHS 00451 DO 240 JROW = NLF, NLF + NLP1 - 1 00452 JREAL = JREAL + 1 00453 JIMAG = JIMAG + 1 00454 BX( JROW, JCOL ) = DCMPLX( RWORK( JREAL ), 00455 $ RWORK( JIMAG ) ) 00456 240 CONTINUE 00457 250 CONTINUE 00458 * 00459 * Since B and BX are complex, the following call to DGEMM is 00460 * performed in two steps (real and imaginary parts). 00461 * 00462 * CALL DGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU, 00463 * $ B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX ) 00464 * 00465 J = NRP1*NRHS*2 00466 DO 270 JCOL = 1, NRHS 00467 DO 260 JROW = NRF, NRF + NRP1 - 1 00468 J = J + 1 00469 RWORK( J ) = DBLE( B( JROW, JCOL ) ) 00470 260 CONTINUE 00471 270 CONTINUE 00472 CALL DGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU, 00473 $ RWORK( 1+NRP1*NRHS*2 ), NRP1, ZERO, RWORK( 1 ), 00474 $ NRP1 ) 00475 J = NRP1*NRHS*2 00476 DO 290 JCOL = 1, NRHS 00477 DO 280 JROW = NRF, NRF + NRP1 - 1 00478 J = J + 1 00479 RWORK( J ) = DIMAG( B( JROW, JCOL ) ) 00480 280 CONTINUE 00481 290 CONTINUE 00482 CALL DGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU, 00483 $ RWORK( 1+NRP1*NRHS*2 ), NRP1, ZERO, 00484 $ RWORK( 1+NRP1*NRHS ), NRP1 ) 00485 JREAL = 0 00486 JIMAG = NRP1*NRHS 00487 DO 310 JCOL = 1, NRHS 00488 DO 300 JROW = NRF, NRF + NRP1 - 1 00489 JREAL = JREAL + 1 00490 JIMAG = JIMAG + 1 00491 BX( JROW, JCOL ) = DCMPLX( RWORK( JREAL ), 00492 $ RWORK( JIMAG ) ) 00493 300 CONTINUE 00494 310 CONTINUE 00495 * 00496 320 CONTINUE 00497 * 00498 330 CONTINUE 00499 * 00500 RETURN 00501 * 00502 * End of ZLALSA 00503 * 00504 END