00001 SUBROUTINE ZGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK,
00002 $ LWORK, RWORK, IWORK, INFO )
00003
00004
00005
00006
00007
00008
00009
00010
00011 CHARACTER JOBZ
00012 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
00013
00014
00015 INTEGER IWORK( * )
00016 DOUBLE PRECISION RWORK( * ), S( * )
00017 COMPLEX*16 A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
00018 $ WORK( * )
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 INTEGER LQUERV
00151 PARAMETER ( LQUERV = -1 )
00152 COMPLEX*16 CZERO, CONE
00153 PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ),
00154 $ CONE = ( 1.0D+0, 0.0D+0 ) )
00155 DOUBLE PRECISION ZERO, ONE
00156 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
00157
00158
00159 LOGICAL WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
00160 INTEGER BLK, CHUNK, I, IE, IERR, IL, IR, IRU, IRVT,
00161 $ ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,
00162 $ LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,
00163 $ MNTHR1, MNTHR2, NRWORK, NWORK, WRKBL
00164 DOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM
00165
00166
00167 INTEGER IDUM( 1 )
00168 DOUBLE PRECISION DUM( 1 )
00169
00170
00171 EXTERNAL DBDSDC, DLASCL, XERBLA, ZGEBRD, ZGELQF, ZGEMM,
00172 $ ZGEQRF, ZLACP2, ZLACPY, ZLACRM, ZLARCM, ZLASCL,
00173 $ ZLASET, ZUNGBR, ZUNGLQ, ZUNGQR, ZUNMBR
00174
00175
00176 LOGICAL LSAME
00177 INTEGER ILAENV
00178 DOUBLE PRECISION DLAMCH, ZLANGE
00179 EXTERNAL LSAME, ILAENV, DLAMCH, ZLANGE
00180
00181
00182 INTRINSIC INT, MAX, MIN, SQRT
00183
00184
00185
00186
00187
00188 INFO = 0
00189 MINMN = MIN( M, N )
00190 MNTHR1 = INT( MINMN*17.0D0 / 9.0D0 )
00191 MNTHR2 = INT( MINMN*5.0D0 / 3.0D0 )
00192 WNTQA = LSAME( JOBZ, 'A' )
00193 WNTQS = LSAME( JOBZ, 'S' )
00194 WNTQAS = WNTQA .OR. WNTQS
00195 WNTQO = LSAME( JOBZ, 'O' )
00196 WNTQN = LSAME( JOBZ, 'N' )
00197 MINWRK = 1
00198 MAXWRK = 1
00199
00200 IF( .NOT.( WNTQA .OR. WNTQS .OR. WNTQO .OR. WNTQN ) ) THEN
00201 INFO = -1
00202 ELSE IF( M.LT.0 ) THEN
00203 INFO = -2
00204 ELSE IF( N.LT.0 ) THEN
00205 INFO = -3
00206 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
00207 INFO = -5
00208 ELSE IF( LDU.LT.1 .OR. ( WNTQAS .AND. LDU.LT.M ) .OR.
00209 $ ( WNTQO .AND. M.LT.N .AND. LDU.LT.M ) ) THEN
00210 INFO = -8
00211 ELSE IF( LDVT.LT.1 .OR. ( WNTQA .AND. LDVT.LT.N ) .OR.
00212 $ ( WNTQS .AND. LDVT.LT.MINMN ) .OR.
00213 $ ( WNTQO .AND. M.GE.N .AND. LDVT.LT.N ) ) THEN
00214 INFO = -10
00215 END IF
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 IF( INFO.EQ.0 .AND. M.GT.0 .AND. N.GT.0 ) THEN
00226 IF( M.GE.N ) THEN
00227
00228
00229
00230
00231
00232
00233
00234
00235 IF( M.GE.MNTHR1 ) THEN
00236 IF( WNTQN ) THEN
00237
00238
00239
00240 MAXWRK = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1,
00241 $ -1 )
00242 MAXWRK = MAX( MAXWRK, 2*N+2*N*
00243 $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
00244 MINWRK = 3*N
00245 ELSE IF( WNTQO ) THEN
00246
00247
00248
00249 WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
00250 WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
00251 $ N, N, -1 ) )
00252 WRKBL = MAX( WRKBL, 2*N+2*N*
00253 $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
00254 WRKBL = MAX( WRKBL, 2*N+N*
00255 $ ILAENV( 1, 'ZUNMBR', 'QLN', N, N, N, -1 ) )
00256 WRKBL = MAX( WRKBL, 2*N+N*
00257 $ ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
00258 MAXWRK = M*N + N*N + WRKBL
00259 MINWRK = 2*N*N + 3*N
00260 ELSE IF( WNTQS ) THEN
00261
00262
00263
00264 WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
00265 WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
00266 $ N, N, -1 ) )
00267 WRKBL = MAX( WRKBL, 2*N+2*N*
00268 $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
00269 WRKBL = MAX( WRKBL, 2*N+N*
00270 $ ILAENV( 1, 'ZUNMBR', 'QLN', N, N, N, -1 ) )
00271 WRKBL = MAX( WRKBL, 2*N+N*
00272 $ ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
00273 MAXWRK = N*N + WRKBL
00274 MINWRK = N*N + 3*N
00275 ELSE IF( WNTQA ) THEN
00276
00277
00278
00279 WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
00280 WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'ZUNGQR', ' ', M,
00281 $ M, N, -1 ) )
00282 WRKBL = MAX( WRKBL, 2*N+2*N*
00283 $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
00284 WRKBL = MAX( WRKBL, 2*N+N*
00285 $ ILAENV( 1, 'ZUNMBR', 'QLN', N, N, N, -1 ) )
00286 WRKBL = MAX( WRKBL, 2*N+N*
00287 $ ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
00288 MAXWRK = N*N + WRKBL
00289 MINWRK = N*N + 2*N + M
00290 END IF
00291 ELSE IF( M.GE.MNTHR2 ) THEN
00292
00293
00294
00295 MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
00296 $ -1, -1 )
00297 MINWRK = 2*N + M
00298 IF( WNTQO ) THEN
00299 MAXWRK = MAX( MAXWRK, 2*N+N*
00300 $ ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
00301 MAXWRK = MAX( MAXWRK, 2*N+N*
00302 $ ILAENV( 1, 'ZUNGBR', 'Q', M, N, N, -1 ) )
00303 MAXWRK = MAXWRK + M*N
00304 MINWRK = MINWRK + N*N
00305 ELSE IF( WNTQS ) THEN
00306 MAXWRK = MAX( MAXWRK, 2*N+N*
00307 $ ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
00308 MAXWRK = MAX( MAXWRK, 2*N+N*
00309 $ ILAENV( 1, 'ZUNGBR', 'Q', M, N, N, -1 ) )
00310 ELSE IF( WNTQA ) THEN
00311 MAXWRK = MAX( MAXWRK, 2*N+N*
00312 $ ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
00313 MAXWRK = MAX( MAXWRK, 2*N+M*
00314 $ ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
00315 END IF
00316 ELSE
00317
00318
00319
00320 MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
00321 $ -1, -1 )
00322 MINWRK = 2*N + M
00323 IF( WNTQO ) THEN
00324 MAXWRK = MAX( MAXWRK, 2*N+N*
00325 $ ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
00326 MAXWRK = MAX( MAXWRK, 2*N+N*
00327 $ ILAENV( 1, 'ZUNMBR', 'QLN', M, N, N, -1 ) )
00328 MAXWRK = MAXWRK + M*N
00329 MINWRK = MINWRK + N*N
00330 ELSE IF( WNTQS ) THEN
00331 MAXWRK = MAX( MAXWRK, 2*N+N*
00332 $ ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
00333 MAXWRK = MAX( MAXWRK, 2*N+N*
00334 $ ILAENV( 1, 'ZUNMBR', 'QLN', M, N, N, -1 ) )
00335 ELSE IF( WNTQA ) THEN
00336 MAXWRK = MAX( MAXWRK, 2*N+N*
00337 $ ILAENV( 1, 'ZUNGBR', 'PRC', N, N, N, -1 ) )
00338 MAXWRK = MAX( MAXWRK, 2*N+M*
00339 $ ILAENV( 1, 'ZUNGBR', 'QLN', M, M, N, -1 ) )
00340 END IF
00341 END IF
00342 ELSE
00343
00344
00345
00346
00347
00348
00349
00350
00351 IF( N.GE.MNTHR1 ) THEN
00352 IF( WNTQN ) THEN
00353
00354
00355
00356 MAXWRK = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1,
00357 $ -1 )
00358 MAXWRK = MAX( MAXWRK, 2*M+2*M*
00359 $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
00360 MINWRK = 3*M
00361 ELSE IF( WNTQO ) THEN
00362
00363
00364
00365 WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
00366 WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
00367 $ N, M, -1 ) )
00368 WRKBL = MAX( WRKBL, 2*M+2*M*
00369 $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
00370 WRKBL = MAX( WRKBL, 2*M+M*
00371 $ ILAENV( 1, 'ZUNMBR', 'PRC', M, M, M, -1 ) )
00372 WRKBL = MAX( WRKBL, 2*M+M*
00373 $ ILAENV( 1, 'ZUNMBR', 'QLN', M, M, M, -1 ) )
00374 MAXWRK = M*N + M*M + WRKBL
00375 MINWRK = 2*M*M + 3*M
00376 ELSE IF( WNTQS ) THEN
00377
00378
00379
00380 WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
00381 WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
00382 $ N, M, -1 ) )
00383 WRKBL = MAX( WRKBL, 2*M+2*M*
00384 $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
00385 WRKBL = MAX( WRKBL, 2*M+M*
00386 $ ILAENV( 1, 'ZUNMBR', 'PRC', M, M, M, -1 ) )
00387 WRKBL = MAX( WRKBL, 2*M+M*
00388 $ ILAENV( 1, 'ZUNMBR', 'QLN', M, M, M, -1 ) )
00389 MAXWRK = M*M + WRKBL
00390 MINWRK = M*M + 3*M
00391 ELSE IF( WNTQA ) THEN
00392
00393
00394
00395 WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
00396 WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'ZUNGLQ', ' ', N,
00397 $ N, M, -1 ) )
00398 WRKBL = MAX( WRKBL, 2*M+2*M*
00399 $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
00400 WRKBL = MAX( WRKBL, 2*M+M*
00401 $ ILAENV( 1, 'ZUNMBR', 'PRC', M, M, M, -1 ) )
00402 WRKBL = MAX( WRKBL, 2*M+M*
00403 $ ILAENV( 1, 'ZUNMBR', 'QLN', M, M, M, -1 ) )
00404 MAXWRK = M*M + WRKBL
00405 MINWRK = M*M + 2*M + N
00406 END IF
00407 ELSE IF( N.GE.MNTHR2 ) THEN
00408
00409
00410
00411 MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
00412 $ -1, -1 )
00413 MINWRK = 2*M + N
00414 IF( WNTQO ) THEN
00415 MAXWRK = MAX( MAXWRK, 2*M+M*
00416 $ ILAENV( 1, 'ZUNGBR', 'P', M, N, M, -1 ) )
00417 MAXWRK = MAX( MAXWRK, 2*M+M*
00418 $ ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
00419 MAXWRK = MAXWRK + M*N
00420 MINWRK = MINWRK + M*M
00421 ELSE IF( WNTQS ) THEN
00422 MAXWRK = MAX( MAXWRK, 2*M+M*
00423 $ ILAENV( 1, 'ZUNGBR', 'P', M, N, M, -1 ) )
00424 MAXWRK = MAX( MAXWRK, 2*M+M*
00425 $ ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
00426 ELSE IF( WNTQA ) THEN
00427 MAXWRK = MAX( MAXWRK, 2*M+N*
00428 $ ILAENV( 1, 'ZUNGBR', 'P', N, N, M, -1 ) )
00429 MAXWRK = MAX( MAXWRK, 2*M+M*
00430 $ ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
00431 END IF
00432 ELSE
00433
00434
00435
00436 MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
00437 $ -1, -1 )
00438 MINWRK = 2*M + N
00439 IF( WNTQO ) THEN
00440 MAXWRK = MAX( MAXWRK, 2*M+M*
00441 $ ILAENV( 1, 'ZUNMBR', 'PRC', M, N, M, -1 ) )
00442 MAXWRK = MAX( MAXWRK, 2*M+M*
00443 $ ILAENV( 1, 'ZUNMBR', 'QLN', M, M, N, -1 ) )
00444 MAXWRK = MAXWRK + M*N
00445 MINWRK = MINWRK + M*M
00446 ELSE IF( WNTQS ) THEN
00447 MAXWRK = MAX( MAXWRK, 2*M+M*
00448 $ ILAENV( 1, 'ZUNGBR', 'PRC', M, N, M, -1 ) )
00449 MAXWRK = MAX( MAXWRK, 2*M+M*
00450 $ ILAENV( 1, 'ZUNGBR', 'QLN', M, M, N, -1 ) )
00451 ELSE IF( WNTQA ) THEN
00452 MAXWRK = MAX( MAXWRK, 2*M+N*
00453 $ ILAENV( 1, 'ZUNGBR', 'PRC', N, N, M, -1 ) )
00454 MAXWRK = MAX( MAXWRK, 2*M+M*
00455 $ ILAENV( 1, 'ZUNGBR', 'QLN', M, M, N, -1 ) )
00456 END IF
00457 END IF
00458 END IF
00459 MAXWRK = MAX( MAXWRK, MINWRK )
00460 END IF
00461 IF( INFO.EQ.0 ) THEN
00462 WORK( 1 ) = MAXWRK
00463 IF( LWORK.LT.MINWRK .AND. LWORK.NE.LQUERV )
00464 $ INFO = -13
00465 END IF
00466
00467
00468
00469 IF( INFO.NE.0 ) THEN
00470 CALL XERBLA( 'ZGESDD', -INFO )
00471 RETURN
00472 END IF
00473 IF( LWORK.EQ.LQUERV )
00474 $ RETURN
00475 IF( M.EQ.0 .OR. N.EQ.0 ) THEN
00476 RETURN
00477 END IF
00478
00479
00480
00481 EPS = DLAMCH( 'P' )
00482 SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS
00483 BIGNUM = ONE / SMLNUM
00484
00485
00486
00487 ANRM = ZLANGE( 'M', M, N, A, LDA, DUM )
00488 ISCL = 0
00489 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
00490 ISCL = 1
00491 CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
00492 ELSE IF( ANRM.GT.BIGNUM ) THEN
00493 ISCL = 1
00494 CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
00495 END IF
00496
00497 IF( M.GE.N ) THEN
00498
00499
00500
00501
00502
00503 IF( M.GE.MNTHR1 ) THEN
00504
00505 IF( WNTQN ) THEN
00506
00507
00508
00509
00510 ITAU = 1
00511 NWORK = ITAU + N
00512
00513
00514
00515
00516
00517 CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
00518 $ LWORK-NWORK+1, IERR )
00519
00520
00521
00522 CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
00523 $ LDA )
00524 IE = 1
00525 ITAUQ = 1
00526 ITAUP = ITAUQ + N
00527 NWORK = ITAUP + N
00528
00529
00530
00531
00532
00533 CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
00534 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
00535 $ IERR )
00536 NRWORK = IE + N
00537
00538
00539
00540
00541
00542 CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1, DUM, 1,
00543 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
00544
00545 ELSE IF( WNTQO ) THEN
00546
00547
00548
00549
00550
00551 IU = 1
00552
00553
00554
00555 LDWRKU = N
00556 IR = IU + LDWRKU*N
00557 IF( LWORK.GE.M*N+N*N+3*N ) THEN
00558
00559
00560
00561 LDWRKR = M
00562 ELSE
00563 LDWRKR = ( LWORK-N*N-3*N ) / N
00564 END IF
00565 ITAU = IR + LDWRKR*N
00566 NWORK = ITAU + N
00567
00568
00569
00570
00571
00572 CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
00573 $ LWORK-NWORK+1, IERR )
00574
00575
00576
00577 CALL ZLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
00578 CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, WORK( IR+1 ),
00579 $ LDWRKR )
00580
00581
00582
00583
00584
00585 CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
00586 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
00587 IE = 1
00588 ITAUQ = ITAU
00589 ITAUP = ITAUQ + N
00590 NWORK = ITAUP + N
00591
00592
00593
00594
00595
00596 CALL ZGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
00597 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
00598 $ LWORK-NWORK+1, IERR )
00599
00600
00601
00602
00603
00604
00605
00606 IRU = IE + N
00607 IRVT = IRU + N*N
00608 NRWORK = IRVT + N*N
00609 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
00610 $ N, RWORK( IRVT ), N, DUM, IDUM,
00611 $ RWORK( NRWORK ), IWORK, INFO )
00612
00613
00614
00615
00616
00617
00618 CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
00619 $ LDWRKU )
00620 CALL ZUNMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
00621 $ WORK( ITAUQ ), WORK( IU ), LDWRKU,
00622 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
00623
00624
00625
00626
00627
00628
00629 CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
00630 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, WORK( IR ), LDWRKR,
00631 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
00632 $ LWORK-NWORK+1, IERR )
00633
00634
00635
00636
00637
00638
00639 DO 10 I = 1, M, LDWRKR
00640 CHUNK = MIN( M-I+1, LDWRKR )
00641 CALL ZGEMM( 'N', 'N', CHUNK, N, N, CONE, A( I, 1 ),
00642 $ LDA, WORK( IU ), LDWRKU, CZERO,
00643 $ WORK( IR ), LDWRKR )
00644 CALL ZLACPY( 'F', CHUNK, N, WORK( IR ), LDWRKR,
00645 $ A( I, 1 ), LDA )
00646 10 CONTINUE
00647
00648 ELSE IF( WNTQS ) THEN
00649
00650
00651
00652
00653
00654 IR = 1
00655
00656
00657
00658 LDWRKR = N
00659 ITAU = IR + LDWRKR*N
00660 NWORK = ITAU + N
00661
00662
00663
00664
00665
00666 CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
00667 $ LWORK-NWORK+1, IERR )
00668
00669
00670
00671 CALL ZLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
00672 CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, WORK( IR+1 ),
00673 $ LDWRKR )
00674
00675
00676
00677
00678
00679 CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
00680 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
00681 IE = 1
00682 ITAUQ = ITAU
00683 ITAUP = ITAUQ + N
00684 NWORK = ITAUP + N
00685
00686
00687
00688
00689
00690 CALL ZGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
00691 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
00692 $ LWORK-NWORK+1, IERR )
00693
00694
00695
00696
00697
00698
00699
00700 IRU = IE + N
00701 IRVT = IRU + N*N
00702 NRWORK = IRVT + N*N
00703 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
00704 $ N, RWORK( IRVT ), N, DUM, IDUM,
00705 $ RWORK( NRWORK ), IWORK, INFO )
00706
00707
00708
00709
00710
00711
00712 CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
00713 CALL ZUNMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
00714 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
00715 $ LWORK-NWORK+1, IERR )
00716
00717
00718
00719
00720
00721
00722 CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
00723 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, WORK( IR ), LDWRKR,
00724 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
00725 $ LWORK-NWORK+1, IERR )
00726
00727
00728
00729
00730
00731
00732 CALL ZLACPY( 'F', N, N, U, LDU, WORK( IR ), LDWRKR )
00733 CALL ZGEMM( 'N', 'N', M, N, N, CONE, A, LDA, WORK( IR ),
00734 $ LDWRKR, CZERO, U, LDU )
00735
00736 ELSE IF( WNTQA ) THEN
00737
00738
00739
00740
00741
00742 IU = 1
00743
00744
00745
00746 LDWRKU = N
00747 ITAU = IU + LDWRKU*N
00748 NWORK = ITAU + N
00749
00750
00751
00752
00753
00754 CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
00755 $ LWORK-NWORK+1, IERR )
00756 CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
00757
00758
00759
00760
00761
00762 CALL ZUNGQR( M, M, N, U, LDU, WORK( ITAU ),
00763 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
00764
00765
00766
00767 CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
00768 $ LDA )
00769 IE = 1
00770 ITAUQ = ITAU
00771 ITAUP = ITAUQ + N
00772 NWORK = ITAUP + N
00773
00774
00775
00776
00777
00778 CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
00779 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
00780 $ IERR )
00781 IRU = IE + N
00782 IRVT = IRU + N*N
00783 NRWORK = IRVT + N*N
00784
00785
00786
00787
00788
00789
00790
00791 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
00792 $ N, RWORK( IRVT ), N, DUM, IDUM,
00793 $ RWORK( NRWORK ), IWORK, INFO )
00794
00795
00796
00797
00798
00799
00800 CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
00801 $ LDWRKU )
00802 CALL ZUNMBR( 'Q', 'L', 'N', N, N, N, A, LDA,
00803 $ WORK( ITAUQ ), WORK( IU ), LDWRKU,
00804 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
00805
00806
00807
00808
00809
00810
00811 CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
00812 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
00813 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
00814 $ LWORK-NWORK+1, IERR )
00815
00816
00817
00818
00819
00820
00821 CALL ZGEMM( 'N', 'N', M, N, N, CONE, U, LDU, WORK( IU ),
00822 $ LDWRKU, CZERO, A, LDA )
00823
00824
00825
00826 CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
00827
00828 END IF
00829
00830 ELSE IF( M.GE.MNTHR2 ) THEN
00831
00832
00833
00834
00835
00836
00837
00838 IE = 1
00839 NRWORK = IE + N
00840 ITAUQ = 1
00841 ITAUP = ITAUQ + N
00842 NWORK = ITAUP + N
00843
00844
00845
00846
00847
00848 CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
00849 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
00850 $ IERR )
00851 IF( WNTQN ) THEN
00852
00853
00854
00855
00856
00857 CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1, DUM, 1,
00858 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
00859 ELSE IF( WNTQO ) THEN
00860 IU = NWORK
00861 IRU = NRWORK
00862 IRVT = IRU + N*N
00863 NRWORK = IRVT + N*N
00864
00865
00866
00867
00868
00869 CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
00870 CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
00871 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
00872
00873
00874
00875
00876
00877 CALL ZUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
00878 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
00879
00880 IF( LWORK.GE.M*N+3*N ) THEN
00881
00882
00883
00884 LDWRKU = M
00885 ELSE
00886
00887
00888
00889 LDWRKU = ( LWORK-3*N ) / N
00890 END IF
00891 NWORK = IU + LDWRKU*N
00892
00893
00894
00895
00896
00897
00898
00899 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
00900 $ N, RWORK( IRVT ), N, DUM, IDUM,
00901 $ RWORK( NRWORK ), IWORK, INFO )
00902
00903
00904
00905
00906
00907
00908 CALL ZLARCM( N, N, RWORK( IRVT ), N, VT, LDVT,
00909 $ WORK( IU ), LDWRKU, RWORK( NRWORK ) )
00910 CALL ZLACPY( 'F', N, N, WORK( IU ), LDWRKU, VT, LDVT )
00911
00912
00913
00914
00915
00916
00917 NRWORK = IRVT
00918 DO 20 I = 1, M, LDWRKU
00919 CHUNK = MIN( M-I+1, LDWRKU )
00920 CALL ZLACRM( CHUNK, N, A( I, 1 ), LDA, RWORK( IRU ),
00921 $ N, WORK( IU ), LDWRKU, RWORK( NRWORK ) )
00922 CALL ZLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
00923 $ A( I, 1 ), LDA )
00924 20 CONTINUE
00925
00926 ELSE IF( WNTQS ) THEN
00927
00928
00929
00930
00931
00932 CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
00933 CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
00934 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
00935
00936
00937
00938
00939
00940 CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
00941 CALL ZUNGBR( 'Q', M, N, N, U, LDU, WORK( ITAUQ ),
00942 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
00943
00944
00945
00946
00947
00948
00949
00950 IRU = NRWORK
00951 IRVT = IRU + N*N
00952 NRWORK = IRVT + N*N
00953 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
00954 $ N, RWORK( IRVT ), N, DUM, IDUM,
00955 $ RWORK( NRWORK ), IWORK, INFO )
00956
00957
00958
00959
00960
00961
00962 CALL ZLARCM( N, N, RWORK( IRVT ), N, VT, LDVT, A, LDA,
00963 $ RWORK( NRWORK ) )
00964 CALL ZLACPY( 'F', N, N, A, LDA, VT, LDVT )
00965
00966
00967
00968
00969
00970
00971 NRWORK = IRVT
00972 CALL ZLACRM( M, N, U, LDU, RWORK( IRU ), N, A, LDA,
00973 $ RWORK( NRWORK ) )
00974 CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
00975 ELSE
00976
00977
00978
00979
00980
00981 CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
00982 CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
00983 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
00984
00985
00986
00987
00988
00989 CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
00990 CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
00991 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
00992
00993
00994
00995
00996
00997
00998
00999 IRU = NRWORK
01000 IRVT = IRU + N*N
01001 NRWORK = IRVT + N*N
01002 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
01003 $ N, RWORK( IRVT ), N, DUM, IDUM,
01004 $ RWORK( NRWORK ), IWORK, INFO )
01005
01006
01007
01008
01009
01010
01011 CALL ZLARCM( N, N, RWORK( IRVT ), N, VT, LDVT, A, LDA,
01012 $ RWORK( NRWORK ) )
01013 CALL ZLACPY( 'F', N, N, A, LDA, VT, LDVT )
01014
01015
01016
01017
01018
01019
01020 NRWORK = IRVT
01021 CALL ZLACRM( M, N, U, LDU, RWORK( IRU ), N, A, LDA,
01022 $ RWORK( NRWORK ) )
01023 CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
01024 END IF
01025
01026 ELSE
01027
01028
01029
01030
01031
01032
01033
01034 IE = 1
01035 NRWORK = IE + N
01036 ITAUQ = 1
01037 ITAUP = ITAUQ + N
01038 NWORK = ITAUP + N
01039
01040
01041
01042
01043
01044 CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
01045 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
01046 $ IERR )
01047 IF( WNTQN ) THEN
01048
01049
01050
01051
01052
01053 CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1, DUM, 1,
01054 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
01055 ELSE IF( WNTQO ) THEN
01056 IU = NWORK
01057 IRU = NRWORK
01058 IRVT = IRU + N*N
01059 NRWORK = IRVT + N*N
01060 IF( LWORK.GE.M*N+3*N ) THEN
01061
01062
01063
01064 LDWRKU = M
01065 ELSE
01066
01067
01068
01069 LDWRKU = ( LWORK-3*N ) / N
01070 END IF
01071 NWORK = IU + LDWRKU*N
01072
01073
01074
01075
01076
01077
01078
01079 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
01080 $ N, RWORK( IRVT ), N, DUM, IDUM,
01081 $ RWORK( NRWORK ), IWORK, INFO )
01082
01083
01084
01085
01086
01087
01088 CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
01089 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
01090 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
01091 $ LWORK-NWORK+1, IERR )
01092
01093 IF( LWORK.GE.M*N+3*N ) THEN
01094
01095
01096
01097
01098
01099
01100
01101 CALL ZLASET( 'F', M, N, CZERO, CZERO, WORK( IU ),
01102 $ LDWRKU )
01103 CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
01104 $ LDWRKU )
01105 CALL ZUNMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
01106 $ WORK( ITAUQ ), WORK( IU ), LDWRKU,
01107 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01108 CALL ZLACPY( 'F', M, N, WORK( IU ), LDWRKU, A, LDA )
01109 ELSE
01110
01111
01112
01113
01114
01115 CALL ZUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
01116 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01117
01118
01119
01120
01121
01122
01123 NRWORK = IRVT
01124 DO 30 I = 1, M, LDWRKU
01125 CHUNK = MIN( M-I+1, LDWRKU )
01126 CALL ZLACRM( CHUNK, N, A( I, 1 ), LDA,
01127 $ RWORK( IRU ), N, WORK( IU ), LDWRKU,
01128 $ RWORK( NRWORK ) )
01129 CALL ZLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
01130 $ A( I, 1 ), LDA )
01131 30 CONTINUE
01132 END IF
01133
01134 ELSE IF( WNTQS ) THEN
01135
01136
01137
01138
01139
01140
01141
01142 IRU = NRWORK
01143 IRVT = IRU + N*N
01144 NRWORK = IRVT + N*N
01145 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
01146 $ N, RWORK( IRVT ), N, DUM, IDUM,
01147 $ RWORK( NRWORK ), IWORK, INFO )
01148
01149
01150
01151
01152
01153
01154 CALL ZLASET( 'F', M, N, CZERO, CZERO, U, LDU )
01155 CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
01156 CALL ZUNMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
01157 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
01158 $ LWORK-NWORK+1, IERR )
01159
01160
01161
01162
01163
01164
01165 CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
01166 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
01167 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
01168 $ LWORK-NWORK+1, IERR )
01169 ELSE
01170
01171
01172
01173
01174
01175
01176
01177 IRU = NRWORK
01178 IRVT = IRU + N*N
01179 NRWORK = IRVT + N*N
01180 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
01181 $ N, RWORK( IRVT ), N, DUM, IDUM,
01182 $ RWORK( NRWORK ), IWORK, INFO )
01183
01184
01185
01186 CALL ZLASET( 'F', M, M, CZERO, CZERO, U, LDU )
01187 IF( M.GT.N ) THEN
01188 CALL ZLASET( 'F', M-N, M-N, CZERO, CONE,
01189 $ U( N+1, N+1 ), LDU )
01190 END IF
01191
01192
01193
01194
01195
01196
01197 CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
01198 CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
01199 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
01200 $ LWORK-NWORK+1, IERR )
01201
01202
01203
01204
01205
01206
01207 CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
01208 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
01209 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
01210 $ LWORK-NWORK+1, IERR )
01211 END IF
01212
01213 END IF
01214
01215 ELSE
01216
01217
01218
01219
01220
01221 IF( N.GE.MNTHR1 ) THEN
01222
01223 IF( WNTQN ) THEN
01224
01225
01226
01227
01228 ITAU = 1
01229 NWORK = ITAU + M
01230
01231
01232
01233
01234
01235 CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
01236 $ LWORK-NWORK+1, IERR )
01237
01238
01239
01240 CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO, A( 1, 2 ),
01241 $ LDA )
01242 IE = 1
01243 ITAUQ = 1
01244 ITAUP = ITAUQ + M
01245 NWORK = ITAUP + M
01246
01247
01248
01249
01250
01251 CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
01252 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
01253 $ IERR )
01254 NRWORK = IE + M
01255
01256
01257
01258
01259
01260 CALL DBDSDC( 'U', 'N', M, S, RWORK( IE ), DUM, 1, DUM, 1,
01261 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
01262
01263 ELSE IF( WNTQO ) THEN
01264
01265
01266
01267
01268
01269 IVT = 1
01270 LDWKVT = M
01271
01272
01273
01274 IL = IVT + LDWKVT*M
01275 IF( LWORK.GE.M*N+M*M+3*M ) THEN
01276
01277
01278
01279 LDWRKL = M
01280 CHUNK = N
01281 ELSE
01282
01283
01284
01285 LDWRKL = M
01286 CHUNK = ( LWORK-M*M-3*M ) / M
01287 END IF
01288 ITAU = IL + LDWRKL*CHUNK
01289 NWORK = ITAU + M
01290
01291
01292
01293
01294
01295 CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
01296 $ LWORK-NWORK+1, IERR )
01297
01298
01299
01300 CALL ZLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
01301 CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
01302 $ WORK( IL+LDWRKL ), LDWRKL )
01303
01304
01305
01306
01307
01308 CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
01309 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01310 IE = 1
01311 ITAUQ = ITAU
01312 ITAUP = ITAUQ + M
01313 NWORK = ITAUP + M
01314
01315
01316
01317
01318
01319 CALL ZGEBRD( M, M, WORK( IL ), LDWRKL, S, RWORK( IE ),
01320 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
01321 $ LWORK-NWORK+1, IERR )
01322
01323
01324
01325
01326
01327
01328
01329 IRU = IE + M
01330 IRVT = IRU + M*M
01331 NRWORK = IRVT + M*M
01332 CALL DBDSDC( 'U', 'I', M, S, RWORK( IE ), RWORK( IRU ),
01333 $ M, RWORK( IRVT ), M, DUM, IDUM,
01334 $ RWORK( NRWORK ), IWORK, INFO )
01335
01336
01337
01338
01339
01340
01341 CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
01342 CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
01343 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
01344 $ LWORK-NWORK+1, IERR )
01345
01346
01347
01348
01349
01350
01351 CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
01352 $ LDWKVT )
01353 CALL ZUNMBR( 'P', 'R', 'C', M, M, M, WORK( IL ), LDWRKL,
01354 $ WORK( ITAUP ), WORK( IVT ), LDWKVT,
01355 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01356
01357
01358
01359
01360
01361
01362 DO 40 I = 1, N, CHUNK
01363 BLK = MIN( N-I+1, CHUNK )
01364 CALL ZGEMM( 'N', 'N', M, BLK, M, CONE, WORK( IVT ), M,
01365 $ A( 1, I ), LDA, CZERO, WORK( IL ),
01366 $ LDWRKL )
01367 CALL ZLACPY( 'F', M, BLK, WORK( IL ), LDWRKL,
01368 $ A( 1, I ), LDA )
01369 40 CONTINUE
01370
01371 ELSE IF( WNTQS ) THEN
01372
01373
01374
01375
01376
01377 IL = 1
01378
01379
01380
01381 LDWRKL = M
01382 ITAU = IL + LDWRKL*M
01383 NWORK = ITAU + M
01384
01385
01386
01387
01388
01389 CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
01390 $ LWORK-NWORK+1, IERR )
01391
01392
01393
01394 CALL ZLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
01395 CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
01396 $ WORK( IL+LDWRKL ), LDWRKL )
01397
01398
01399
01400
01401
01402 CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
01403 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01404 IE = 1
01405 ITAUQ = ITAU
01406 ITAUP = ITAUQ + M
01407 NWORK = ITAUP + M
01408
01409
01410
01411
01412
01413 CALL ZGEBRD( M, M, WORK( IL ), LDWRKL, S, RWORK( IE ),
01414 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
01415 $ LWORK-NWORK+1, IERR )
01416
01417
01418
01419
01420
01421
01422
01423 IRU = IE + M
01424 IRVT = IRU + M*M
01425 NRWORK = IRVT + M*M
01426 CALL DBDSDC( 'U', 'I', M, S, RWORK( IE ), RWORK( IRU ),
01427 $ M, RWORK( IRVT ), M, DUM, IDUM,
01428 $ RWORK( NRWORK ), IWORK, INFO )
01429
01430
01431
01432
01433
01434
01435 CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
01436 CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
01437 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
01438 $ LWORK-NWORK+1, IERR )
01439
01440
01441
01442
01443
01444
01445 CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
01446 CALL ZUNMBR( 'P', 'R', 'C', M, M, M, WORK( IL ), LDWRKL,
01447 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
01448 $ LWORK-NWORK+1, IERR )
01449
01450
01451
01452
01453
01454
01455 CALL ZLACPY( 'F', M, M, VT, LDVT, WORK( IL ), LDWRKL )
01456 CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IL ), LDWRKL,
01457 $ A, LDA, CZERO, VT, LDVT )
01458
01459 ELSE IF( WNTQA ) THEN
01460
01461
01462
01463
01464
01465 IVT = 1
01466
01467
01468
01469 LDWKVT = M
01470 ITAU = IVT + LDWKVT*M
01471 NWORK = ITAU + M
01472
01473
01474
01475
01476
01477 CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
01478 $ LWORK-NWORK+1, IERR )
01479 CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
01480
01481
01482
01483
01484
01485 CALL ZUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
01486 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01487
01488
01489
01490 CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO, A( 1, 2 ),
01491 $ LDA )
01492 IE = 1
01493 ITAUQ = ITAU
01494 ITAUP = ITAUQ + M
01495 NWORK = ITAUP + M
01496
01497
01498
01499
01500
01501 CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
01502 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
01503 $ IERR )
01504
01505
01506
01507
01508
01509
01510
01511 IRU = IE + M
01512 IRVT = IRU + M*M
01513 NRWORK = IRVT + M*M
01514 CALL DBDSDC( 'U', 'I', M, S, RWORK( IE ), RWORK( IRU ),
01515 $ M, RWORK( IRVT ), M, DUM, IDUM,
01516 $ RWORK( NRWORK ), IWORK, INFO )
01517
01518
01519
01520
01521
01522
01523 CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
01524 CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, A, LDA,
01525 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
01526 $ LWORK-NWORK+1, IERR )
01527
01528
01529
01530
01531
01532
01533 CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
01534 $ LDWKVT )
01535 CALL ZUNMBR( 'P', 'R', 'C', M, M, M, A, LDA,
01536 $ WORK( ITAUP ), WORK( IVT ), LDWKVT,
01537 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01538
01539
01540
01541
01542
01543
01544 CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IVT ), LDWKVT,
01545 $ VT, LDVT, CZERO, A, LDA )
01546
01547
01548
01549 CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
01550
01551 END IF
01552
01553 ELSE IF( N.GE.MNTHR2 ) THEN
01554
01555
01556
01557
01558
01559
01560
01561
01562 IE = 1
01563 NRWORK = IE + M
01564 ITAUQ = 1
01565 ITAUP = ITAUQ + M
01566 NWORK = ITAUP + M
01567
01568
01569
01570
01571
01572 CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
01573 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
01574 $ IERR )
01575
01576 IF( WNTQN ) THEN
01577
01578
01579
01580
01581
01582 CALL DBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM, 1, DUM, 1,
01583 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
01584 ELSE IF( WNTQO ) THEN
01585 IRVT = NRWORK
01586 IRU = IRVT + M*M
01587 NRWORK = IRU + M*M
01588 IVT = NWORK
01589
01590
01591
01592
01593
01594 CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
01595 CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
01596 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01597
01598
01599
01600
01601
01602 CALL ZUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
01603 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01604
01605 LDWKVT = M
01606 IF( LWORK.GE.M*N+3*M ) THEN
01607
01608
01609
01610 NWORK = IVT + LDWKVT*N
01611 CHUNK = N
01612 ELSE
01613
01614
01615
01616 CHUNK = ( LWORK-3*M ) / M
01617 NWORK = IVT + LDWKVT*CHUNK
01618 END IF
01619
01620
01621
01622
01623
01624
01625
01626 CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
01627 $ M, RWORK( IRVT ), M, DUM, IDUM,
01628 $ RWORK( NRWORK ), IWORK, INFO )
01629
01630
01631
01632
01633
01634
01635 CALL ZLACRM( M, M, U, LDU, RWORK( IRU ), M, WORK( IVT ),
01636 $ LDWKVT, RWORK( NRWORK ) )
01637 CALL ZLACPY( 'F', M, M, WORK( IVT ), LDWKVT, U, LDU )
01638
01639
01640
01641
01642
01643
01644 NRWORK = IRU
01645 DO 50 I = 1, N, CHUNK
01646 BLK = MIN( N-I+1, CHUNK )
01647 CALL ZLARCM( M, BLK, RWORK( IRVT ), M, A( 1, I ), LDA,
01648 $ WORK( IVT ), LDWKVT, RWORK( NRWORK ) )
01649 CALL ZLACPY( 'F', M, BLK, WORK( IVT ), LDWKVT,
01650 $ A( 1, I ), LDA )
01651 50 CONTINUE
01652 ELSE IF( WNTQS ) THEN
01653
01654
01655
01656
01657
01658 CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
01659 CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
01660 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01661
01662
01663
01664
01665
01666 CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
01667 CALL ZUNGBR( 'P', M, N, M, VT, LDVT, WORK( ITAUP ),
01668 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01669
01670
01671
01672
01673
01674
01675
01676 IRVT = NRWORK
01677 IRU = IRVT + M*M
01678 NRWORK = IRU + M*M
01679 CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
01680 $ M, RWORK( IRVT ), M, DUM, IDUM,
01681 $ RWORK( NRWORK ), IWORK, INFO )
01682
01683
01684
01685
01686
01687
01688 CALL ZLACRM( M, M, U, LDU, RWORK( IRU ), M, A, LDA,
01689 $ RWORK( NRWORK ) )
01690 CALL ZLACPY( 'F', M, M, A, LDA, U, LDU )
01691
01692
01693
01694
01695
01696
01697 NRWORK = IRU
01698 CALL ZLARCM( M, N, RWORK( IRVT ), M, VT, LDVT, A, LDA,
01699 $ RWORK( NRWORK ) )
01700 CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
01701 ELSE
01702
01703
01704
01705
01706
01707 CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
01708 CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
01709 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01710
01711
01712
01713
01714
01715 CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
01716 CALL ZUNGBR( 'P', N, N, M, VT, LDVT, WORK( ITAUP ),
01717 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01718
01719
01720
01721
01722
01723
01724
01725 IRVT = NRWORK
01726 IRU = IRVT + M*M
01727 NRWORK = IRU + M*M
01728 CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
01729 $ M, RWORK( IRVT ), M, DUM, IDUM,
01730 $ RWORK( NRWORK ), IWORK, INFO )
01731
01732
01733
01734
01735
01736
01737 CALL ZLACRM( M, M, U, LDU, RWORK( IRU ), M, A, LDA,
01738 $ RWORK( NRWORK ) )
01739 CALL ZLACPY( 'F', M, M, A, LDA, U, LDU )
01740
01741
01742
01743
01744
01745
01746 CALL ZLARCM( M, N, RWORK( IRVT ), M, VT, LDVT, A, LDA,
01747 $ RWORK( NRWORK ) )
01748 CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
01749 END IF
01750
01751 ELSE
01752
01753
01754
01755
01756
01757
01758
01759 IE = 1
01760 NRWORK = IE + M
01761 ITAUQ = 1
01762 ITAUP = ITAUQ + M
01763 NWORK = ITAUP + M
01764
01765
01766
01767
01768
01769 CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
01770 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
01771 $ IERR )
01772 IF( WNTQN ) THEN
01773
01774
01775
01776
01777
01778 CALL DBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM, 1, DUM, 1,
01779 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
01780 ELSE IF( WNTQO ) THEN
01781 LDWKVT = M
01782 IVT = NWORK
01783 IF( LWORK.GE.M*N+3*M ) THEN
01784
01785
01786
01787 CALL ZLASET( 'F', M, N, CZERO, CZERO, WORK( IVT ),
01788 $ LDWKVT )
01789 NWORK = IVT + LDWKVT*N
01790 ELSE
01791
01792
01793
01794 CHUNK = ( LWORK-3*M ) / M
01795 NWORK = IVT + LDWKVT*CHUNK
01796 END IF
01797
01798
01799
01800
01801
01802
01803
01804 IRVT = NRWORK
01805 IRU = IRVT + M*M
01806 NRWORK = IRU + M*M
01807 CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
01808 $ M, RWORK( IRVT ), M, DUM, IDUM,
01809 $ RWORK( NRWORK ), IWORK, INFO )
01810
01811
01812
01813
01814
01815
01816 CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
01817 CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
01818 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
01819 $ LWORK-NWORK+1, IERR )
01820
01821 IF( LWORK.GE.M*N+3*M ) THEN
01822
01823
01824
01825
01826
01827
01828
01829 CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
01830 $ LDWKVT )
01831 CALL ZUNMBR( 'P', 'R', 'C', M, N, M, A, LDA,
01832 $ WORK( ITAUP ), WORK( IVT ), LDWKVT,
01833 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01834 CALL ZLACPY( 'F', M, N, WORK( IVT ), LDWKVT, A, LDA )
01835 ELSE
01836
01837
01838
01839
01840
01841 CALL ZUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
01842 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
01843
01844
01845
01846
01847
01848
01849 NRWORK = IRU
01850 DO 60 I = 1, N, CHUNK
01851 BLK = MIN( N-I+1, CHUNK )
01852 CALL ZLARCM( M, BLK, RWORK( IRVT ), M, A( 1, I ),
01853 $ LDA, WORK( IVT ), LDWKVT,
01854 $ RWORK( NRWORK ) )
01855 CALL ZLACPY( 'F', M, BLK, WORK( IVT ), LDWKVT,
01856 $ A( 1, I ), LDA )
01857 60 CONTINUE
01858 END IF
01859 ELSE IF( WNTQS ) THEN
01860
01861
01862
01863
01864
01865
01866
01867 IRVT = NRWORK
01868 IRU = IRVT + M*M
01869 NRWORK = IRU + M*M
01870 CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
01871 $ M, RWORK( IRVT ), M, DUM, IDUM,
01872 $ RWORK( NRWORK ), IWORK, INFO )
01873
01874
01875
01876
01877
01878
01879 CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
01880 CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
01881 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
01882 $ LWORK-NWORK+1, IERR )
01883
01884
01885
01886
01887
01888
01889 CALL ZLASET( 'F', M, N, CZERO, CZERO, VT, LDVT )
01890 CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
01891 CALL ZUNMBR( 'P', 'R', 'C', M, N, M, A, LDA,
01892 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
01893 $ LWORK-NWORK+1, IERR )
01894 ELSE
01895
01896
01897
01898
01899
01900
01901
01902 IRVT = NRWORK
01903 IRU = IRVT + M*M
01904 NRWORK = IRU + M*M
01905
01906 CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
01907 $ M, RWORK( IRVT ), M, DUM, IDUM,
01908 $ RWORK( NRWORK ), IWORK, INFO )
01909
01910
01911
01912
01913
01914
01915 CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
01916 CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
01917 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
01918 $ LWORK-NWORK+1, IERR )
01919
01920
01921
01922 CALL ZLASET( 'F', N, N, CZERO, CONE, VT, LDVT )
01923
01924
01925
01926
01927
01928
01929 CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
01930 CALL ZUNMBR( 'P', 'R', 'C', N, N, M, A, LDA,
01931 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
01932 $ LWORK-NWORK+1, IERR )
01933 END IF
01934
01935 END IF
01936
01937 END IF
01938
01939
01940
01941 IF( ISCL.EQ.1 ) THEN
01942 IF( ANRM.GT.BIGNUM )
01943 $ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
01944 $ IERR )
01945 IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
01946 $ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1,
01947 $ RWORK( IE ), MINMN, IERR )
01948 IF( ANRM.LT.SMLNUM )
01949 $ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
01950 $ IERR )
01951 IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
01952 $ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1,
01953 $ RWORK( IE ), MINMN, IERR )
01954 END IF
01955
01956
01957
01958 WORK( 1 ) = MAXWRK
01959
01960 RETURN
01961
01962
01963
01964 END