00001 SUBROUTINE CGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,
00002 $ WORK, LWORK, RWORK, INFO )
00003
00004
00005
00006
00007
00008
00009
00010 CHARACTER JOBU, JOBVT
00011 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
00012
00013
00014 REAL RWORK( * ), S( * )
00015 COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
00016 $ WORK( * )
00017
00018
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 COMPLEX CZERO, CONE
00141 PARAMETER ( CZERO = ( 0.0E0, 0.0E0 ),
00142 $ CONE = ( 1.0E0, 0.0E0 ) )
00143 REAL ZERO, ONE
00144 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
00145
00146
00147 LOGICAL LQUERY, WNTUA, WNTUAS, WNTUN, WNTUO, WNTUS,
00148 $ WNTVA, WNTVAS, WNTVN, WNTVO, WNTVS
00149 INTEGER BLK, CHUNK, I, IE, IERR, IR, IRWORK, ISCL,
00150 $ ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,
00151 $ MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,
00152 $ NRVT, WRKBL
00153 REAL ANRM, BIGNUM, EPS, SMLNUM
00154
00155
00156 REAL DUM( 1 )
00157 COMPLEX CDUM( 1 )
00158
00159
00160 EXTERNAL CBDSQR, CGEBRD, CGELQF, CGEMM, CGEQRF, CLACPY,
00161 $ CLASCL, CLASET, CUNGBR, CUNGLQ, CUNGQR, CUNMBR,
00162 $ SLASCL, XERBLA
00163
00164
00165 LOGICAL LSAME
00166 INTEGER ILAENV
00167 REAL CLANGE, SLAMCH
00168 EXTERNAL LSAME, ILAENV, CLANGE, SLAMCH
00169
00170
00171 INTRINSIC MAX, MIN, SQRT
00172
00173
00174
00175
00176
00177 INFO = 0
00178 MINMN = MIN( M, N )
00179 WNTUA = LSAME( JOBU, 'A' )
00180 WNTUS = LSAME( JOBU, 'S' )
00181 WNTUAS = WNTUA .OR. WNTUS
00182 WNTUO = LSAME( JOBU, 'O' )
00183 WNTUN = LSAME( JOBU, 'N' )
00184 WNTVA = LSAME( JOBVT, 'A' )
00185 WNTVS = LSAME( JOBVT, 'S' )
00186 WNTVAS = WNTVA .OR. WNTVS
00187 WNTVO = LSAME( JOBVT, 'O' )
00188 WNTVN = LSAME( JOBVT, 'N' )
00189 LQUERY = ( LWORK.EQ.-1 )
00190
00191 IF( .NOT.( WNTUA .OR. WNTUS .OR. WNTUO .OR. WNTUN ) ) THEN
00192 INFO = -1
00193 ELSE IF( .NOT.( WNTVA .OR. WNTVS .OR. WNTVO .OR. WNTVN ) .OR.
00194 $ ( WNTVO .AND. WNTUO ) ) THEN
00195 INFO = -2
00196 ELSE IF( M.LT.0 ) THEN
00197 INFO = -3
00198 ELSE IF( N.LT.0 ) THEN
00199 INFO = -4
00200 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
00201 INFO = -6
00202 ELSE IF( LDU.LT.1 .OR. ( WNTUAS .AND. LDU.LT.M ) ) THEN
00203 INFO = -9
00204 ELSE IF( LDVT.LT.1 .OR. ( WNTVA .AND. LDVT.LT.N ) .OR.
00205 $ ( WNTVS .AND. LDVT.LT.MINMN ) ) THEN
00206 INFO = -11
00207 END IF
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 IF( INFO.EQ.0 ) THEN
00218 MINWRK = 1
00219 MAXWRK = 1
00220 IF( M.GE.N .AND. MINMN.GT.0 ) THEN
00221
00222
00223
00224 MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
00225 IF( M.GE.MNTHR ) THEN
00226 IF( WNTUN ) THEN
00227
00228
00229
00230 MAXWRK = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1,
00231 $ -1 )
00232 MAXWRK = MAX( MAXWRK, 2*N+2*N*
00233 $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
00234 IF( WNTVO .OR. WNTVAS )
00235 $ MAXWRK = MAX( MAXWRK, 2*N+( N-1 )*
00236 $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
00237 MINWRK = 3*N
00238 ELSE IF( WNTUO .AND. WNTVN ) THEN
00239
00240
00241
00242 WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
00243 WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
00244 $ N, N, -1 ) )
00245 WRKBL = MAX( WRKBL, 2*N+2*N*
00246 $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
00247 WRKBL = MAX( WRKBL, 2*N+N*
00248 $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
00249 MAXWRK = MAX( N*N+WRKBL, N*N+M*N )
00250 MINWRK = 2*N + M
00251 ELSE IF( WNTUO .AND. WNTVAS ) THEN
00252
00253
00254
00255
00256 WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
00257 WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
00258 $ N, N, -1 ) )
00259 WRKBL = MAX( WRKBL, 2*N+2*N*
00260 $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
00261 WRKBL = MAX( WRKBL, 2*N+N*
00262 $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
00263 WRKBL = MAX( WRKBL, 2*N+( N-1 )*
00264 $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
00265 MAXWRK = MAX( N*N+WRKBL, N*N+M*N )
00266 MINWRK = 2*N + M
00267 ELSE IF( WNTUS .AND. WNTVN ) THEN
00268
00269
00270
00271 WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
00272 WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
00273 $ N, N, -1 ) )
00274 WRKBL = MAX( WRKBL, 2*N+2*N*
00275 $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
00276 WRKBL = MAX( WRKBL, 2*N+N*
00277 $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
00278 MAXWRK = N*N + WRKBL
00279 MINWRK = 2*N + M
00280 ELSE IF( WNTUS .AND. WNTVO ) THEN
00281
00282
00283
00284 WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
00285 WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
00286 $ N, N, -1 ) )
00287 WRKBL = MAX( WRKBL, 2*N+2*N*
00288 $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
00289 WRKBL = MAX( WRKBL, 2*N+N*
00290 $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
00291 WRKBL = MAX( WRKBL, 2*N+( N-1 )*
00292 $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
00293 MAXWRK = 2*N*N + WRKBL
00294 MINWRK = 2*N + M
00295 ELSE IF( WNTUS .AND. WNTVAS ) THEN
00296
00297
00298
00299
00300 WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
00301 WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
00302 $ N, N, -1 ) )
00303 WRKBL = MAX( WRKBL, 2*N+2*N*
00304 $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
00305 WRKBL = MAX( WRKBL, 2*N+N*
00306 $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
00307 WRKBL = MAX( WRKBL, 2*N+( N-1 )*
00308 $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
00309 MAXWRK = N*N + WRKBL
00310 MINWRK = 2*N + M
00311 ELSE IF( WNTUA .AND. WNTVN ) THEN
00312
00313
00314
00315 WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
00316 WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'CUNGQR', ' ', M,
00317 $ M, N, -1 ) )
00318 WRKBL = MAX( WRKBL, 2*N+2*N*
00319 $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
00320 WRKBL = MAX( WRKBL, 2*N+N*
00321 $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
00322 MAXWRK = N*N + WRKBL
00323 MINWRK = 2*N + M
00324 ELSE IF( WNTUA .AND. WNTVO ) THEN
00325
00326
00327
00328 WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
00329 WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'CUNGQR', ' ', M,
00330 $ M, N, -1 ) )
00331 WRKBL = MAX( WRKBL, 2*N+2*N*
00332 $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
00333 WRKBL = MAX( WRKBL, 2*N+N*
00334 $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
00335 WRKBL = MAX( WRKBL, 2*N+( N-1 )*
00336 $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
00337 MAXWRK = 2*N*N + WRKBL
00338 MINWRK = 2*N + M
00339 ELSE IF( WNTUA .AND. WNTVAS ) THEN
00340
00341
00342
00343
00344 WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
00345 WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'CUNGQR', ' ', M,
00346 $ M, N, -1 ) )
00347 WRKBL = MAX( WRKBL, 2*N+2*N*
00348 $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
00349 WRKBL = MAX( WRKBL, 2*N+N*
00350 $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
00351 WRKBL = MAX( WRKBL, 2*N+( N-1 )*
00352 $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
00353 MAXWRK = N*N + WRKBL
00354 MINWRK = 2*N + M
00355 END IF
00356 ELSE
00357
00358
00359
00360 MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'CGEBRD', ' ', M, N,
00361 $ -1, -1 )
00362 IF( WNTUS .OR. WNTUO )
00363 $ MAXWRK = MAX( MAXWRK, 2*N+N*
00364 $ ILAENV( 1, 'CUNGBR', 'Q', M, N, N, -1 ) )
00365 IF( WNTUA )
00366 $ MAXWRK = MAX( MAXWRK, 2*N+M*
00367 $ ILAENV( 1, 'CUNGBR', 'Q', M, M, N, -1 ) )
00368 IF( .NOT.WNTVN )
00369 $ MAXWRK = MAX( MAXWRK, 2*N+( N-1 )*
00370 $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
00371 MINWRK = 2*N + M
00372 END IF
00373 ELSE IF( MINMN.GT.0 ) THEN
00374
00375
00376
00377 MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
00378 IF( N.GE.MNTHR ) THEN
00379 IF( WNTVN ) THEN
00380
00381
00382
00383 MAXWRK = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1,
00384 $ -1 )
00385 MAXWRK = MAX( MAXWRK, 2*M+2*M*
00386 $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
00387 IF( WNTUO .OR. WNTUAS )
00388 $ MAXWRK = MAX( MAXWRK, 2*M+M*
00389 $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
00390 MINWRK = 3*M
00391 ELSE IF( WNTVO .AND. WNTUN ) THEN
00392
00393
00394
00395 WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
00396 WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
00397 $ N, M, -1 ) )
00398 WRKBL = MAX( WRKBL, 2*M+2*M*
00399 $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
00400 WRKBL = MAX( WRKBL, 2*M+( M-1 )*
00401 $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
00402 MAXWRK = MAX( M*M+WRKBL, M*M+M*N )
00403 MINWRK = 2*M + N
00404 ELSE IF( WNTVO .AND. WNTUAS ) THEN
00405
00406
00407
00408
00409 WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
00410 WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
00411 $ N, M, -1 ) )
00412 WRKBL = MAX( WRKBL, 2*M+2*M*
00413 $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
00414 WRKBL = MAX( WRKBL, 2*M+( M-1 )*
00415 $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
00416 WRKBL = MAX( WRKBL, 2*M+M*
00417 $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
00418 MAXWRK = MAX( M*M+WRKBL, M*M+M*N )
00419 MINWRK = 2*M + N
00420 ELSE IF( WNTVS .AND. WNTUN ) THEN
00421
00422
00423
00424 WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
00425 WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
00426 $ N, M, -1 ) )
00427 WRKBL = MAX( WRKBL, 2*M+2*M*
00428 $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
00429 WRKBL = MAX( WRKBL, 2*M+( M-1 )*
00430 $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
00431 MAXWRK = M*M + WRKBL
00432 MINWRK = 2*M + N
00433 ELSE IF( WNTVS .AND. WNTUO ) THEN
00434
00435
00436
00437 WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
00438 WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
00439 $ N, M, -1 ) )
00440 WRKBL = MAX( WRKBL, 2*M+2*M*
00441 $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
00442 WRKBL = MAX( WRKBL, 2*M+( M-1 )*
00443 $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
00444 WRKBL = MAX( WRKBL, 2*M+M*
00445 $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
00446 MAXWRK = 2*M*M + WRKBL
00447 MINWRK = 2*M + N
00448 ELSE IF( WNTVS .AND. WNTUAS ) THEN
00449
00450
00451
00452
00453 WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
00454 WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
00455 $ N, M, -1 ) )
00456 WRKBL = MAX( WRKBL, 2*M+2*M*
00457 $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
00458 WRKBL = MAX( WRKBL, 2*M+( M-1 )*
00459 $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
00460 WRKBL = MAX( WRKBL, 2*M+M*
00461 $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
00462 MAXWRK = M*M + WRKBL
00463 MINWRK = 2*M + N
00464 ELSE IF( WNTVA .AND. WNTUN ) THEN
00465
00466
00467
00468 WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
00469 WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'CUNGLQ', ' ', N,
00470 $ N, M, -1 ) )
00471 WRKBL = MAX( WRKBL, 2*M+2*M*
00472 $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
00473 WRKBL = MAX( WRKBL, 2*M+( M-1 )*
00474 $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
00475 MAXWRK = M*M + WRKBL
00476 MINWRK = 2*M + N
00477 ELSE IF( WNTVA .AND. WNTUO ) THEN
00478
00479
00480
00481 WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
00482 WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'CUNGLQ', ' ', N,
00483 $ N, M, -1 ) )
00484 WRKBL = MAX( WRKBL, 2*M+2*M*
00485 $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
00486 WRKBL = MAX( WRKBL, 2*M+( M-1 )*
00487 $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
00488 WRKBL = MAX( WRKBL, 2*M+M*
00489 $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
00490 MAXWRK = 2*M*M + WRKBL
00491 MINWRK = 2*M + N
00492 ELSE IF( WNTVA .AND. WNTUAS ) THEN
00493
00494
00495
00496
00497 WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
00498 WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'CUNGLQ', ' ', N,
00499 $ N, M, -1 ) )
00500 WRKBL = MAX( WRKBL, 2*M+2*M*
00501 $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
00502 WRKBL = MAX( WRKBL, 2*M+( M-1 )*
00503 $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
00504 WRKBL = MAX( WRKBL, 2*M+M*
00505 $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
00506 MAXWRK = M*M + WRKBL
00507 MINWRK = 2*M + N
00508 END IF
00509 ELSE
00510
00511
00512
00513 MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'CGEBRD', ' ', M, N,
00514 $ -1, -1 )
00515 IF( WNTVS .OR. WNTVO )
00516 $ MAXWRK = MAX( MAXWRK, 2*M+M*
00517 $ ILAENV( 1, 'CUNGBR', 'P', M, N, M, -1 ) )
00518 IF( WNTVA )
00519 $ MAXWRK = MAX( MAXWRK, 2*M+N*
00520 $ ILAENV( 1, 'CUNGBR', 'P', N, N, M, -1 ) )
00521 IF( .NOT.WNTUN )
00522 $ MAXWRK = MAX( MAXWRK, 2*M+( M-1 )*
00523 $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
00524 MINWRK = 2*M + N
00525 END IF
00526 END IF
00527 MAXWRK = MAX( MINWRK, MAXWRK )
00528 WORK( 1 ) = MAXWRK
00529
00530 IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
00531 INFO = -13
00532 END IF
00533 END IF
00534
00535 IF( INFO.NE.0 ) THEN
00536 CALL XERBLA( 'CGESVD', -INFO )
00537 RETURN
00538 ELSE IF( LQUERY ) THEN
00539 RETURN
00540 END IF
00541
00542
00543
00544 IF( M.EQ.0 .OR. N.EQ.0 ) THEN
00545 RETURN
00546 END IF
00547
00548
00549
00550 EPS = SLAMCH( 'P' )
00551 SMLNUM = SQRT( SLAMCH( 'S' ) ) / EPS
00552 BIGNUM = ONE / SMLNUM
00553
00554
00555
00556 ANRM = CLANGE( 'M', M, N, A, LDA, DUM )
00557 ISCL = 0
00558 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
00559 ISCL = 1
00560 CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
00561 ELSE IF( ANRM.GT.BIGNUM ) THEN
00562 ISCL = 1
00563 CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
00564 END IF
00565
00566 IF( M.GE.N ) THEN
00567
00568
00569
00570
00571
00572 IF( M.GE.MNTHR ) THEN
00573
00574 IF( WNTUN ) THEN
00575
00576
00577
00578
00579 ITAU = 1
00580 IWORK = ITAU + N
00581
00582
00583
00584
00585
00586 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
00587 $ LWORK-IWORK+1, IERR )
00588
00589
00590
00591 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
00592 $ LDA )
00593 IE = 1
00594 ITAUQ = 1
00595 ITAUP = ITAUQ + N
00596 IWORK = ITAUP + N
00597
00598
00599
00600
00601
00602 CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
00603 $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
00604 $ IERR )
00605 NCVT = 0
00606 IF( WNTVO .OR. WNTVAS ) THEN
00607
00608
00609
00610
00611
00612 CALL CUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
00613 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00614 NCVT = N
00615 END IF
00616 IRWORK = IE + N
00617
00618
00619
00620
00621
00622
00623 CALL CBDSQR( 'U', N, NCVT, 0, 0, S, RWORK( IE ), A, LDA,
00624 $ CDUM, 1, CDUM, 1, RWORK( IRWORK ), INFO )
00625
00626
00627
00628 IF( WNTVAS )
00629 $ CALL CLACPY( 'F', N, N, A, LDA, VT, LDVT )
00630
00631 ELSE IF( WNTUO .AND. WNTVN ) THEN
00632
00633
00634
00635
00636
00637 IF( LWORK.GE.N*N+3*N ) THEN
00638
00639
00640
00641 IR = 1
00642 IF( LWORK.GE.MAX( WRKBL, LDA*N )+LDA*N ) THEN
00643
00644
00645
00646 LDWRKU = LDA
00647 LDWRKR = LDA
00648 ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N )+N*N ) THEN
00649
00650
00651
00652 LDWRKU = LDA
00653 LDWRKR = N
00654 ELSE
00655
00656
00657
00658 LDWRKU = ( LWORK-N*N ) / N
00659 LDWRKR = N
00660 END IF
00661 ITAU = IR + LDWRKR*N
00662 IWORK = ITAU + N
00663
00664
00665
00666
00667
00668 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
00669 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00670
00671
00672
00673 CALL CLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
00674 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
00675 $ WORK( IR+1 ), LDWRKR )
00676
00677
00678
00679
00680
00681 CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
00682 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00683 IE = 1
00684 ITAUQ = ITAU
00685 ITAUP = ITAUQ + N
00686 IWORK = ITAUP + N
00687
00688
00689
00690
00691
00692 CALL CGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
00693 $ WORK( ITAUQ ), WORK( ITAUP ),
00694 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00695
00696
00697
00698
00699
00700 CALL CUNGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
00701 $ WORK( ITAUQ ), WORK( IWORK ),
00702 $ LWORK-IWORK+1, IERR )
00703 IRWORK = IE + N
00704
00705
00706
00707
00708
00709
00710 CALL CBDSQR( 'U', N, 0, N, 0, S, RWORK( IE ), CDUM, 1,
00711 $ WORK( IR ), LDWRKR, CDUM, 1,
00712 $ RWORK( IRWORK ), INFO )
00713 IU = ITAUQ
00714
00715
00716
00717
00718
00719
00720 DO 10 I = 1, M, LDWRKU
00721 CHUNK = MIN( M-I+1, LDWRKU )
00722 CALL CGEMM( 'N', 'N', CHUNK, N, N, CONE, A( I, 1 ),
00723 $ LDA, WORK( IR ), LDWRKR, CZERO,
00724 $ WORK( IU ), LDWRKU )
00725 CALL CLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
00726 $ A( I, 1 ), LDA )
00727 10 CONTINUE
00728
00729 ELSE
00730
00731
00732
00733 IE = 1
00734 ITAUQ = 1
00735 ITAUP = ITAUQ + N
00736 IWORK = ITAUP + N
00737
00738
00739
00740
00741
00742 CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ),
00743 $ WORK( ITAUQ ), WORK( ITAUP ),
00744 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00745
00746
00747
00748
00749
00750 CALL CUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
00751 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00752 IRWORK = IE + N
00753
00754
00755
00756
00757
00758
00759 CALL CBDSQR( 'U', N, 0, M, 0, S, RWORK( IE ), CDUM, 1,
00760 $ A, LDA, CDUM, 1, RWORK( IRWORK ), INFO )
00761
00762 END IF
00763
00764 ELSE IF( WNTUO .AND. WNTVAS ) THEN
00765
00766
00767
00768
00769
00770 IF( LWORK.GE.N*N+3*N ) THEN
00771
00772
00773
00774 IR = 1
00775 IF( LWORK.GE.MAX( WRKBL, LDA*N )+LDA*N ) THEN
00776
00777
00778
00779 LDWRKU = LDA
00780 LDWRKR = LDA
00781 ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N )+N*N ) THEN
00782
00783
00784
00785 LDWRKU = LDA
00786 LDWRKR = N
00787 ELSE
00788
00789
00790
00791 LDWRKU = ( LWORK-N*N ) / N
00792 LDWRKR = N
00793 END IF
00794 ITAU = IR + LDWRKR*N
00795 IWORK = ITAU + N
00796
00797
00798
00799
00800
00801 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
00802 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00803
00804
00805
00806 CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
00807 IF( N.GT.1 )
00808 $ CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
00809 $ VT( 2, 1 ), LDVT )
00810
00811
00812
00813
00814
00815 CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
00816 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00817 IE = 1
00818 ITAUQ = ITAU
00819 ITAUP = ITAUQ + N
00820 IWORK = ITAUP + N
00821
00822
00823
00824
00825
00826 CALL CGEBRD( N, N, VT, LDVT, S, RWORK( IE ),
00827 $ WORK( ITAUQ ), WORK( ITAUP ),
00828 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00829 CALL CLACPY( 'L', N, N, VT, LDVT, WORK( IR ), LDWRKR )
00830
00831
00832
00833
00834
00835 CALL CUNGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
00836 $ WORK( ITAUQ ), WORK( IWORK ),
00837 $ LWORK-IWORK+1, IERR )
00838
00839
00840
00841
00842
00843 CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
00844 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00845 IRWORK = IE + N
00846
00847
00848
00849
00850
00851
00852
00853 CALL CBDSQR( 'U', N, N, N, 0, S, RWORK( IE ), VT,
00854 $ LDVT, WORK( IR ), LDWRKR, CDUM, 1,
00855 $ RWORK( IRWORK ), INFO )
00856 IU = ITAUQ
00857
00858
00859
00860
00861
00862
00863 DO 20 I = 1, M, LDWRKU
00864 CHUNK = MIN( M-I+1, LDWRKU )
00865 CALL CGEMM( 'N', 'N', CHUNK, N, N, CONE, A( I, 1 ),
00866 $ LDA, WORK( IR ), LDWRKR, CZERO,
00867 $ WORK( IU ), LDWRKU )
00868 CALL CLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
00869 $ A( I, 1 ), LDA )
00870 20 CONTINUE
00871
00872 ELSE
00873
00874
00875
00876 ITAU = 1
00877 IWORK = ITAU + N
00878
00879
00880
00881
00882
00883 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
00884 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00885
00886
00887
00888 CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
00889 IF( N.GT.1 )
00890 $ CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
00891 $ VT( 2, 1 ), LDVT )
00892
00893
00894
00895
00896
00897 CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
00898 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00899 IE = 1
00900 ITAUQ = ITAU
00901 ITAUP = ITAUQ + N
00902 IWORK = ITAUP + N
00903
00904
00905
00906
00907
00908 CALL CGEBRD( N, N, VT, LDVT, S, RWORK( IE ),
00909 $ WORK( ITAUQ ), WORK( ITAUP ),
00910 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00911
00912
00913
00914
00915
00916 CALL CUNMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
00917 $ WORK( ITAUQ ), A, LDA, WORK( IWORK ),
00918 $ LWORK-IWORK+1, IERR )
00919
00920
00921
00922
00923
00924 CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
00925 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00926 IRWORK = IE + N
00927
00928
00929
00930
00931
00932
00933
00934 CALL CBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), VT,
00935 $ LDVT, A, LDA, CDUM, 1, RWORK( IRWORK ),
00936 $ INFO )
00937
00938 END IF
00939
00940 ELSE IF( WNTUS ) THEN
00941
00942 IF( WNTVN ) THEN
00943
00944
00945
00946
00947
00948 IF( LWORK.GE.N*N+3*N ) THEN
00949
00950
00951
00952 IR = 1
00953 IF( LWORK.GE.WRKBL+LDA*N ) THEN
00954
00955
00956
00957 LDWRKR = LDA
00958 ELSE
00959
00960
00961
00962 LDWRKR = N
00963 END IF
00964 ITAU = IR + LDWRKR*N
00965 IWORK = ITAU + N
00966
00967
00968
00969
00970
00971 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
00972 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00973
00974
00975
00976 CALL CLACPY( 'U', N, N, A, LDA, WORK( IR ),
00977 $ LDWRKR )
00978 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
00979 $ WORK( IR+1 ), LDWRKR )
00980
00981
00982
00983
00984
00985 CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
00986 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
00987 IE = 1
00988 ITAUQ = ITAU
00989 ITAUP = ITAUQ + N
00990 IWORK = ITAUP + N
00991
00992
00993
00994
00995
00996 CALL CGEBRD( N, N, WORK( IR ), LDWRKR, S,
00997 $ RWORK( IE ), WORK( ITAUQ ),
00998 $ WORK( ITAUP ), WORK( IWORK ),
00999 $ LWORK-IWORK+1, IERR )
01000
01001
01002
01003
01004
01005 CALL CUNGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
01006 $ WORK( ITAUQ ), WORK( IWORK ),
01007 $ LWORK-IWORK+1, IERR )
01008 IRWORK = IE + N
01009
01010
01011
01012
01013
01014
01015 CALL CBDSQR( 'U', N, 0, N, 0, S, RWORK( IE ), CDUM,
01016 $ 1, WORK( IR ), LDWRKR, CDUM, 1,
01017 $ RWORK( IRWORK ), INFO )
01018
01019
01020
01021
01022
01023
01024 CALL CGEMM( 'N', 'N', M, N, N, CONE, A, LDA,
01025 $ WORK( IR ), LDWRKR, CZERO, U, LDU )
01026
01027 ELSE
01028
01029
01030
01031 ITAU = 1
01032 IWORK = ITAU + N
01033
01034
01035
01036
01037
01038 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
01039 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01040 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
01041
01042
01043
01044
01045
01046 CALL CUNGQR( M, N, N, U, LDU, WORK( ITAU ),
01047 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01048 IE = 1
01049 ITAUQ = ITAU
01050 ITAUP = ITAUQ + N
01051 IWORK = ITAUP + N
01052
01053
01054
01055 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
01056 $ A( 2, 1 ), LDA )
01057
01058
01059
01060
01061
01062 CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ),
01063 $ WORK( ITAUQ ), WORK( ITAUP ),
01064 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01065
01066
01067
01068
01069
01070 CALL CUNMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
01071 $ WORK( ITAUQ ), U, LDU, WORK( IWORK ),
01072 $ LWORK-IWORK+1, IERR )
01073 IRWORK = IE + N
01074
01075
01076
01077
01078
01079
01080 CALL CBDSQR( 'U', N, 0, M, 0, S, RWORK( IE ), CDUM,
01081 $ 1, U, LDU, CDUM, 1, RWORK( IRWORK ),
01082 $ INFO )
01083
01084 END IF
01085
01086 ELSE IF( WNTVO ) THEN
01087
01088
01089
01090
01091
01092 IF( LWORK.GE.2*N*N+3*N ) THEN
01093
01094
01095
01096 IU = 1
01097 IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
01098
01099
01100
01101 LDWRKU = LDA
01102 IR = IU + LDWRKU*N
01103 LDWRKR = LDA
01104 ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
01105
01106
01107
01108 LDWRKU = LDA
01109 IR = IU + LDWRKU*N
01110 LDWRKR = N
01111 ELSE
01112
01113
01114
01115 LDWRKU = N
01116 IR = IU + LDWRKU*N
01117 LDWRKR = N
01118 END IF
01119 ITAU = IR + LDWRKR*N
01120 IWORK = ITAU + N
01121
01122
01123
01124
01125
01126 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
01127 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01128
01129
01130
01131 CALL CLACPY( 'U', N, N, A, LDA, WORK( IU ),
01132 $ LDWRKU )
01133 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
01134 $ WORK( IU+1 ), LDWRKU )
01135
01136
01137
01138
01139
01140 CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
01141 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01142 IE = 1
01143 ITAUQ = ITAU
01144 ITAUP = ITAUQ + N
01145 IWORK = ITAUP + N
01146
01147
01148
01149
01150
01151
01152
01153 CALL CGEBRD( N, N, WORK( IU ), LDWRKU, S,
01154 $ RWORK( IE ), WORK( ITAUQ ),
01155 $ WORK( ITAUP ), WORK( IWORK ),
01156 $ LWORK-IWORK+1, IERR )
01157 CALL CLACPY( 'U', N, N, WORK( IU ), LDWRKU,
01158 $ WORK( IR ), LDWRKR )
01159
01160
01161
01162
01163
01164 CALL CUNGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
01165 $ WORK( ITAUQ ), WORK( IWORK ),
01166 $ LWORK-IWORK+1, IERR )
01167
01168
01169
01170
01171
01172
01173 CALL CUNGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
01174 $ WORK( ITAUP ), WORK( IWORK ),
01175 $ LWORK-IWORK+1, IERR )
01176 IRWORK = IE + N
01177
01178
01179
01180
01181
01182
01183
01184 CALL CBDSQR( 'U', N, N, N, 0, S, RWORK( IE ),
01185 $ WORK( IR ), LDWRKR, WORK( IU ),
01186 $ LDWRKU, CDUM, 1, RWORK( IRWORK ),
01187 $ INFO )
01188
01189
01190
01191
01192
01193
01194 CALL CGEMM( 'N', 'N', M, N, N, CONE, A, LDA,
01195 $ WORK( IU ), LDWRKU, CZERO, U, LDU )
01196
01197
01198
01199
01200
01201 CALL CLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
01202 $ LDA )
01203
01204 ELSE
01205
01206
01207
01208 ITAU = 1
01209 IWORK = ITAU + N
01210
01211
01212
01213
01214
01215 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
01216 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01217 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
01218
01219
01220
01221
01222
01223 CALL CUNGQR( M, N, N, U, LDU, WORK( ITAU ),
01224 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01225 IE = 1
01226 ITAUQ = ITAU
01227 ITAUP = ITAUQ + N
01228 IWORK = ITAUP + N
01229
01230
01231
01232 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
01233 $ A( 2, 1 ), LDA )
01234
01235
01236
01237
01238
01239 CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ),
01240 $ WORK( ITAUQ ), WORK( ITAUP ),
01241 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01242
01243
01244
01245
01246
01247 CALL CUNMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
01248 $ WORK( ITAUQ ), U, LDU, WORK( IWORK ),
01249 $ LWORK-IWORK+1, IERR )
01250
01251
01252
01253
01254
01255 CALL CUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
01256 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01257 IRWORK = IE + N
01258
01259
01260
01261
01262
01263
01264
01265 CALL CBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), A,
01266 $ LDA, U, LDU, CDUM, 1, RWORK( IRWORK ),
01267 $ INFO )
01268
01269 END IF
01270
01271 ELSE IF( WNTVAS ) THEN
01272
01273
01274
01275
01276
01277
01278 IF( LWORK.GE.N*N+3*N ) THEN
01279
01280
01281
01282 IU = 1
01283 IF( LWORK.GE.WRKBL+LDA*N ) THEN
01284
01285
01286
01287 LDWRKU = LDA
01288 ELSE
01289
01290
01291
01292 LDWRKU = N
01293 END IF
01294 ITAU = IU + LDWRKU*N
01295 IWORK = ITAU + N
01296
01297
01298
01299
01300
01301 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
01302 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01303
01304
01305
01306 CALL CLACPY( 'U', N, N, A, LDA, WORK( IU ),
01307 $ LDWRKU )
01308 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
01309 $ WORK( IU+1 ), LDWRKU )
01310
01311
01312
01313
01314
01315 CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
01316 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01317 IE = 1
01318 ITAUQ = ITAU
01319 ITAUP = ITAUQ + N
01320 IWORK = ITAUP + N
01321
01322
01323
01324
01325
01326 CALL CGEBRD( N, N, WORK( IU ), LDWRKU, S,
01327 $ RWORK( IE ), WORK( ITAUQ ),
01328 $ WORK( ITAUP ), WORK( IWORK ),
01329 $ LWORK-IWORK+1, IERR )
01330 CALL CLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
01331 $ LDVT )
01332
01333
01334
01335
01336
01337 CALL CUNGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
01338 $ WORK( ITAUQ ), WORK( IWORK ),
01339 $ LWORK-IWORK+1, IERR )
01340
01341
01342
01343
01344
01345
01346 CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
01347 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01348 IRWORK = IE + N
01349
01350
01351
01352
01353
01354
01355
01356 CALL CBDSQR( 'U', N, N, N, 0, S, RWORK( IE ), VT,
01357 $ LDVT, WORK( IU ), LDWRKU, CDUM, 1,
01358 $ RWORK( IRWORK ), INFO )
01359
01360
01361
01362
01363
01364
01365 CALL CGEMM( 'N', 'N', M, N, N, CONE, A, LDA,
01366 $ WORK( IU ), LDWRKU, CZERO, U, LDU )
01367
01368 ELSE
01369
01370
01371
01372 ITAU = 1
01373 IWORK = ITAU + N
01374
01375
01376
01377
01378
01379 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
01380 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01381 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
01382
01383
01384
01385
01386
01387 CALL CUNGQR( M, N, N, U, LDU, WORK( ITAU ),
01388 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01389
01390
01391
01392 CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
01393 IF( N.GT.1 )
01394 $ CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
01395 $ VT( 2, 1 ), LDVT )
01396 IE = 1
01397 ITAUQ = ITAU
01398 ITAUP = ITAUQ + N
01399 IWORK = ITAUP + N
01400
01401
01402
01403
01404
01405 CALL CGEBRD( N, N, VT, LDVT, S, RWORK( IE ),
01406 $ WORK( ITAUQ ), WORK( ITAUP ),
01407 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01408
01409
01410
01411
01412
01413
01414 CALL CUNMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
01415 $ WORK( ITAUQ ), U, LDU, WORK( IWORK ),
01416 $ LWORK-IWORK+1, IERR )
01417
01418
01419
01420
01421
01422 CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
01423 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01424 IRWORK = IE + N
01425
01426
01427
01428
01429
01430
01431
01432 CALL CBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), VT,
01433 $ LDVT, U, LDU, CDUM, 1,
01434 $ RWORK( IRWORK ), INFO )
01435
01436 END IF
01437
01438 END IF
01439
01440 ELSE IF( WNTUA ) THEN
01441
01442 IF( WNTVN ) THEN
01443
01444
01445
01446
01447
01448 IF( LWORK.GE.N*N+MAX( N+M, 3*N ) ) THEN
01449
01450
01451
01452 IR = 1
01453 IF( LWORK.GE.WRKBL+LDA*N ) THEN
01454
01455
01456
01457 LDWRKR = LDA
01458 ELSE
01459
01460
01461
01462 LDWRKR = N
01463 END IF
01464 ITAU = IR + LDWRKR*N
01465 IWORK = ITAU + N
01466
01467
01468
01469
01470
01471 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
01472 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01473 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
01474
01475
01476
01477 CALL CLACPY( 'U', N, N, A, LDA, WORK( IR ),
01478 $ LDWRKR )
01479 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
01480 $ WORK( IR+1 ), LDWRKR )
01481
01482
01483
01484
01485
01486 CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
01487 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01488 IE = 1
01489 ITAUQ = ITAU
01490 ITAUP = ITAUQ + N
01491 IWORK = ITAUP + N
01492
01493
01494
01495
01496
01497 CALL CGEBRD( N, N, WORK( IR ), LDWRKR, S,
01498 $ RWORK( IE ), WORK( ITAUQ ),
01499 $ WORK( ITAUP ), WORK( IWORK ),
01500 $ LWORK-IWORK+1, IERR )
01501
01502
01503
01504
01505
01506 CALL CUNGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
01507 $ WORK( ITAUQ ), WORK( IWORK ),
01508 $ LWORK-IWORK+1, IERR )
01509 IRWORK = IE + N
01510
01511
01512
01513
01514
01515
01516 CALL CBDSQR( 'U', N, 0, N, 0, S, RWORK( IE ), CDUM,
01517 $ 1, WORK( IR ), LDWRKR, CDUM, 1,
01518 $ RWORK( IRWORK ), INFO )
01519
01520
01521
01522
01523
01524
01525 CALL CGEMM( 'N', 'N', M, N, N, CONE, U, LDU,
01526 $ WORK( IR ), LDWRKR, CZERO, A, LDA )
01527
01528
01529
01530 CALL CLACPY( 'F', M, N, A, LDA, U, LDU )
01531
01532 ELSE
01533
01534
01535
01536 ITAU = 1
01537 IWORK = ITAU + N
01538
01539
01540
01541
01542
01543 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
01544 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01545 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
01546
01547
01548
01549
01550
01551 CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
01552 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01553 IE = 1
01554 ITAUQ = ITAU
01555 ITAUP = ITAUQ + N
01556 IWORK = ITAUP + N
01557
01558
01559
01560 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
01561 $ A( 2, 1 ), LDA )
01562
01563
01564
01565
01566
01567 CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ),
01568 $ WORK( ITAUQ ), WORK( ITAUP ),
01569 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01570
01571
01572
01573
01574
01575
01576 CALL CUNMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
01577 $ WORK( ITAUQ ), U, LDU, WORK( IWORK ),
01578 $ LWORK-IWORK+1, IERR )
01579 IRWORK = IE + N
01580
01581
01582
01583
01584
01585
01586 CALL CBDSQR( 'U', N, 0, M, 0, S, RWORK( IE ), CDUM,
01587 $ 1, U, LDU, CDUM, 1, RWORK( IRWORK ),
01588 $ INFO )
01589
01590 END IF
01591
01592 ELSE IF( WNTVO ) THEN
01593
01594
01595
01596
01597
01598 IF( LWORK.GE.2*N*N+MAX( N+M, 3*N ) ) THEN
01599
01600
01601
01602 IU = 1
01603 IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
01604
01605
01606
01607 LDWRKU = LDA
01608 IR = IU + LDWRKU*N
01609 LDWRKR = LDA
01610 ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
01611
01612
01613
01614 LDWRKU = LDA
01615 IR = IU + LDWRKU*N
01616 LDWRKR = N
01617 ELSE
01618
01619
01620
01621 LDWRKU = N
01622 IR = IU + LDWRKU*N
01623 LDWRKR = N
01624 END IF
01625 ITAU = IR + LDWRKR*N
01626 IWORK = ITAU + N
01627
01628
01629
01630
01631
01632 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
01633 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01634 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
01635
01636
01637
01638
01639
01640 CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
01641 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01642
01643
01644
01645 CALL CLACPY( 'U', N, N, A, LDA, WORK( IU ),
01646 $ LDWRKU )
01647 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
01648 $ WORK( IU+1 ), LDWRKU )
01649 IE = 1
01650 ITAUQ = ITAU
01651 ITAUP = ITAUQ + N
01652 IWORK = ITAUP + N
01653
01654
01655
01656
01657
01658
01659
01660 CALL CGEBRD( N, N, WORK( IU ), LDWRKU, S,
01661 $ RWORK( IE ), WORK( ITAUQ ),
01662 $ WORK( ITAUP ), WORK( IWORK ),
01663 $ LWORK-IWORK+1, IERR )
01664 CALL CLACPY( 'U', N, N, WORK( IU ), LDWRKU,
01665 $ WORK( IR ), LDWRKR )
01666
01667
01668
01669
01670
01671 CALL CUNGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
01672 $ WORK( ITAUQ ), WORK( IWORK ),
01673 $ LWORK-IWORK+1, IERR )
01674
01675
01676
01677
01678
01679
01680 CALL CUNGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
01681 $ WORK( ITAUP ), WORK( IWORK ),
01682 $ LWORK-IWORK+1, IERR )
01683 IRWORK = IE + N
01684
01685
01686
01687
01688
01689
01690
01691 CALL CBDSQR( 'U', N, N, N, 0, S, RWORK( IE ),
01692 $ WORK( IR ), LDWRKR, WORK( IU ),
01693 $ LDWRKU, CDUM, 1, RWORK( IRWORK ),
01694 $ INFO )
01695
01696
01697
01698
01699
01700
01701 CALL CGEMM( 'N', 'N', M, N, N, CONE, U, LDU,
01702 $ WORK( IU ), LDWRKU, CZERO, A, LDA )
01703
01704
01705
01706 CALL CLACPY( 'F', M, N, A, LDA, U, LDU )
01707
01708
01709
01710 CALL CLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
01711 $ LDA )
01712
01713 ELSE
01714
01715
01716
01717 ITAU = 1
01718 IWORK = ITAU + N
01719
01720
01721
01722
01723
01724 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
01725 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01726 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
01727
01728
01729
01730
01731
01732 CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
01733 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01734 IE = 1
01735 ITAUQ = ITAU
01736 ITAUP = ITAUQ + N
01737 IWORK = ITAUP + N
01738
01739
01740
01741 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
01742 $ A( 2, 1 ), LDA )
01743
01744
01745
01746
01747
01748 CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ),
01749 $ WORK( ITAUQ ), WORK( ITAUP ),
01750 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01751
01752
01753
01754
01755
01756
01757 CALL CUNMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
01758 $ WORK( ITAUQ ), U, LDU, WORK( IWORK ),
01759 $ LWORK-IWORK+1, IERR )
01760
01761
01762
01763
01764
01765 CALL CUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
01766 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01767 IRWORK = IE + N
01768
01769
01770
01771
01772
01773
01774
01775 CALL CBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), A,
01776 $ LDA, U, LDU, CDUM, 1, RWORK( IRWORK ),
01777 $ INFO )
01778
01779 END IF
01780
01781 ELSE IF( WNTVAS ) THEN
01782
01783
01784
01785
01786
01787
01788 IF( LWORK.GE.N*N+MAX( N+M, 3*N ) ) THEN
01789
01790
01791
01792 IU = 1
01793 IF( LWORK.GE.WRKBL+LDA*N ) THEN
01794
01795
01796
01797 LDWRKU = LDA
01798 ELSE
01799
01800
01801
01802 LDWRKU = N
01803 END IF
01804 ITAU = IU + LDWRKU*N
01805 IWORK = ITAU + N
01806
01807
01808
01809
01810
01811 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
01812 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01813 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
01814
01815
01816
01817
01818
01819 CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
01820 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01821
01822
01823
01824 CALL CLACPY( 'U', N, N, A, LDA, WORK( IU ),
01825 $ LDWRKU )
01826 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
01827 $ WORK( IU+1 ), LDWRKU )
01828 IE = 1
01829 ITAUQ = ITAU
01830 ITAUP = ITAUQ + N
01831 IWORK = ITAUP + N
01832
01833
01834
01835
01836
01837 CALL CGEBRD( N, N, WORK( IU ), LDWRKU, S,
01838 $ RWORK( IE ), WORK( ITAUQ ),
01839 $ WORK( ITAUP ), WORK( IWORK ),
01840 $ LWORK-IWORK+1, IERR )
01841 CALL CLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
01842 $ LDVT )
01843
01844
01845
01846
01847
01848 CALL CUNGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
01849 $ WORK( ITAUQ ), WORK( IWORK ),
01850 $ LWORK-IWORK+1, IERR )
01851
01852
01853
01854
01855
01856
01857 CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
01858 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01859 IRWORK = IE + N
01860
01861
01862
01863
01864
01865
01866
01867 CALL CBDSQR( 'U', N, N, N, 0, S, RWORK( IE ), VT,
01868 $ LDVT, WORK( IU ), LDWRKU, CDUM, 1,
01869 $ RWORK( IRWORK ), INFO )
01870
01871
01872
01873
01874
01875
01876 CALL CGEMM( 'N', 'N', M, N, N, CONE, U, LDU,
01877 $ WORK( IU ), LDWRKU, CZERO, A, LDA )
01878
01879
01880
01881 CALL CLACPY( 'F', M, N, A, LDA, U, LDU )
01882
01883 ELSE
01884
01885
01886
01887 ITAU = 1
01888 IWORK = ITAU + N
01889
01890
01891
01892
01893
01894 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ),
01895 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01896 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
01897
01898
01899
01900
01901
01902 CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
01903 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01904
01905
01906
01907 CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
01908 IF( N.GT.1 )
01909 $ CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
01910 $ VT( 2, 1 ), LDVT )
01911 IE = 1
01912 ITAUQ = ITAU
01913 ITAUP = ITAUQ + N
01914 IWORK = ITAUP + N
01915
01916
01917
01918
01919
01920 CALL CGEBRD( N, N, VT, LDVT, S, RWORK( IE ),
01921 $ WORK( ITAUQ ), WORK( ITAUP ),
01922 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01923
01924
01925
01926
01927
01928
01929 CALL CUNMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
01930 $ WORK( ITAUQ ), U, LDU, WORK( IWORK ),
01931 $ LWORK-IWORK+1, IERR )
01932
01933
01934
01935
01936
01937 CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
01938 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01939 IRWORK = IE + N
01940
01941
01942
01943
01944
01945
01946
01947 CALL CBDSQR( 'U', N, N, M, 0, S, RWORK( IE ), VT,
01948 $ LDVT, U, LDU, CDUM, 1,
01949 $ RWORK( IRWORK ), INFO )
01950
01951 END IF
01952
01953 END IF
01954
01955 END IF
01956
01957 ELSE
01958
01959
01960
01961
01962
01963
01964 IE = 1
01965 ITAUQ = 1
01966 ITAUP = ITAUQ + N
01967 IWORK = ITAUP + N
01968
01969
01970
01971
01972
01973 CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
01974 $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
01975 $ IERR )
01976 IF( WNTUAS ) THEN
01977
01978
01979
01980
01981
01982
01983 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
01984 IF( WNTUS )
01985 $ NCU = N
01986 IF( WNTUA )
01987 $ NCU = M
01988 CALL CUNGBR( 'Q', M, NCU, N, U, LDU, WORK( ITAUQ ),
01989 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
01990 END IF
01991 IF( WNTVAS ) THEN
01992
01993
01994
01995
01996
01997
01998 CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
01999 CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
02000 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02001 END IF
02002 IF( WNTUO ) THEN
02003
02004
02005
02006
02007
02008
02009 CALL CUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
02010 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02011 END IF
02012 IF( WNTVO ) THEN
02013
02014
02015
02016
02017
02018
02019 CALL CUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
02020 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02021 END IF
02022 IRWORK = IE + N
02023 IF( WNTUAS .OR. WNTUO )
02024 $ NRU = M
02025 IF( WNTUN )
02026 $ NRU = 0
02027 IF( WNTVAS .OR. WNTVO )
02028 $ NCVT = N
02029 IF( WNTVN )
02030 $ NCVT = 0
02031 IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
02032
02033
02034
02035
02036
02037
02038
02039 CALL CBDSQR( 'U', N, NCVT, NRU, 0, S, RWORK( IE ), VT,
02040 $ LDVT, U, LDU, CDUM, 1, RWORK( IRWORK ),
02041 $ INFO )
02042 ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
02043
02044
02045
02046
02047
02048
02049
02050 CALL CBDSQR( 'U', N, NCVT, NRU, 0, S, RWORK( IE ), A,
02051 $ LDA, U, LDU, CDUM, 1, RWORK( IRWORK ),
02052 $ INFO )
02053 ELSE
02054
02055
02056
02057
02058
02059
02060
02061 CALL CBDSQR( 'U', N, NCVT, NRU, 0, S, RWORK( IE ), VT,
02062 $ LDVT, A, LDA, CDUM, 1, RWORK( IRWORK ),
02063 $ INFO )
02064 END IF
02065
02066 END IF
02067
02068 ELSE
02069
02070
02071
02072
02073
02074 IF( N.GE.MNTHR ) THEN
02075
02076 IF( WNTVN ) THEN
02077
02078
02079
02080
02081 ITAU = 1
02082 IWORK = ITAU + M
02083
02084
02085
02086
02087
02088 CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
02089 $ LWORK-IWORK+1, IERR )
02090
02091
02092
02093 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO, A( 1, 2 ),
02094 $ LDA )
02095 IE = 1
02096 ITAUQ = 1
02097 ITAUP = ITAUQ + M
02098 IWORK = ITAUP + M
02099
02100
02101
02102
02103
02104 CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
02105 $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
02106 $ IERR )
02107 IF( WNTUO .OR. WNTUAS ) THEN
02108
02109
02110
02111
02112
02113 CALL CUNGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
02114 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02115 END IF
02116 IRWORK = IE + M
02117 NRU = 0
02118 IF( WNTUO .OR. WNTUAS )
02119 $ NRU = M
02120
02121
02122
02123
02124
02125
02126 CALL CBDSQR( 'U', M, 0, NRU, 0, S, RWORK( IE ), CDUM, 1,
02127 $ A, LDA, CDUM, 1, RWORK( IRWORK ), INFO )
02128
02129
02130
02131 IF( WNTUAS )
02132 $ CALL CLACPY( 'F', M, M, A, LDA, U, LDU )
02133
02134 ELSE IF( WNTVO .AND. WNTUN ) THEN
02135
02136
02137
02138
02139
02140 IF( LWORK.GE.M*M+3*M ) THEN
02141
02142
02143
02144 IR = 1
02145 IF( LWORK.GE.MAX( WRKBL, LDA*N )+LDA*M ) THEN
02146
02147
02148
02149 LDWRKU = LDA
02150 CHUNK = N
02151 LDWRKR = LDA
02152 ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N )+M*M ) THEN
02153
02154
02155
02156 LDWRKU = LDA
02157 CHUNK = N
02158 LDWRKR = M
02159 ELSE
02160
02161
02162
02163 LDWRKU = M
02164 CHUNK = ( LWORK-M*M ) / M
02165 LDWRKR = M
02166 END IF
02167 ITAU = IR + LDWRKR*M
02168 IWORK = ITAU + M
02169
02170
02171
02172
02173
02174 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
02175 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02176
02177
02178
02179 CALL CLACPY( 'L', M, M, A, LDA, WORK( IR ), LDWRKR )
02180 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
02181 $ WORK( IR+LDWRKR ), LDWRKR )
02182
02183
02184
02185
02186
02187 CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
02188 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02189 IE = 1
02190 ITAUQ = ITAU
02191 ITAUP = ITAUQ + M
02192 IWORK = ITAUP + M
02193
02194
02195
02196
02197
02198 CALL CGEBRD( M, M, WORK( IR ), LDWRKR, S, RWORK( IE ),
02199 $ WORK( ITAUQ ), WORK( ITAUP ),
02200 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02201
02202
02203
02204
02205
02206 CALL CUNGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
02207 $ WORK( ITAUP ), WORK( IWORK ),
02208 $ LWORK-IWORK+1, IERR )
02209 IRWORK = IE + M
02210
02211
02212
02213
02214
02215
02216 CALL CBDSQR( 'U', M, M, 0, 0, S, RWORK( IE ),
02217 $ WORK( IR ), LDWRKR, CDUM, 1, CDUM, 1,
02218 $ RWORK( IRWORK ), INFO )
02219 IU = ITAUQ
02220
02221
02222
02223
02224
02225
02226 DO 30 I = 1, N, CHUNK
02227 BLK = MIN( N-I+1, CHUNK )
02228 CALL CGEMM( 'N', 'N', M, BLK, M, CONE, WORK( IR ),
02229 $ LDWRKR, A( 1, I ), LDA, CZERO,
02230 $ WORK( IU ), LDWRKU )
02231 CALL CLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
02232 $ A( 1, I ), LDA )
02233 30 CONTINUE
02234
02235 ELSE
02236
02237
02238
02239 IE = 1
02240 ITAUQ = 1
02241 ITAUP = ITAUQ + M
02242 IWORK = ITAUP + M
02243
02244
02245
02246
02247
02248 CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ),
02249 $ WORK( ITAUQ ), WORK( ITAUP ),
02250 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02251
02252
02253
02254
02255
02256 CALL CUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
02257 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02258 IRWORK = IE + M
02259
02260
02261
02262
02263
02264
02265 CALL CBDSQR( 'L', M, N, 0, 0, S, RWORK( IE ), A, LDA,
02266 $ CDUM, 1, CDUM, 1, RWORK( IRWORK ), INFO )
02267
02268 END IF
02269
02270 ELSE IF( WNTVO .AND. WNTUAS ) THEN
02271
02272
02273
02274
02275
02276 IF( LWORK.GE.M*M+3*M ) THEN
02277
02278
02279
02280 IR = 1
02281 IF( LWORK.GE.MAX( WRKBL, LDA*N )+LDA*M ) THEN
02282
02283
02284
02285 LDWRKU = LDA
02286 CHUNK = N
02287 LDWRKR = LDA
02288 ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N )+M*M ) THEN
02289
02290
02291
02292 LDWRKU = LDA
02293 CHUNK = N
02294 LDWRKR = M
02295 ELSE
02296
02297
02298
02299 LDWRKU = M
02300 CHUNK = ( LWORK-M*M ) / M
02301 LDWRKR = M
02302 END IF
02303 ITAU = IR + LDWRKR*M
02304 IWORK = ITAU + M
02305
02306
02307
02308
02309
02310 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
02311 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02312
02313
02314
02315 CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
02316 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO, U( 1, 2 ),
02317 $ LDU )
02318
02319
02320
02321
02322
02323 CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
02324 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02325 IE = 1
02326 ITAUQ = ITAU
02327 ITAUP = ITAUQ + M
02328 IWORK = ITAUP + M
02329
02330
02331
02332
02333
02334 CALL CGEBRD( M, M, U, LDU, S, RWORK( IE ),
02335 $ WORK( ITAUQ ), WORK( ITAUP ),
02336 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02337 CALL CLACPY( 'U', M, M, U, LDU, WORK( IR ), LDWRKR )
02338
02339
02340
02341
02342
02343 CALL CUNGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
02344 $ WORK( ITAUP ), WORK( IWORK ),
02345 $ LWORK-IWORK+1, IERR )
02346
02347
02348
02349
02350
02351 CALL CUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
02352 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02353 IRWORK = IE + M
02354
02355
02356
02357
02358
02359
02360
02361 CALL CBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
02362 $ WORK( IR ), LDWRKR, U, LDU, CDUM, 1,
02363 $ RWORK( IRWORK ), INFO )
02364 IU = ITAUQ
02365
02366
02367
02368
02369
02370
02371 DO 40 I = 1, N, CHUNK
02372 BLK = MIN( N-I+1, CHUNK )
02373 CALL CGEMM( 'N', 'N', M, BLK, M, CONE, WORK( IR ),
02374 $ LDWRKR, A( 1, I ), LDA, CZERO,
02375 $ WORK( IU ), LDWRKU )
02376 CALL CLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
02377 $ A( 1, I ), LDA )
02378 40 CONTINUE
02379
02380 ELSE
02381
02382
02383
02384 ITAU = 1
02385 IWORK = ITAU + M
02386
02387
02388
02389
02390
02391 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
02392 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02393
02394
02395
02396 CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
02397 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO, U( 1, 2 ),
02398 $ LDU )
02399
02400
02401
02402
02403
02404 CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
02405 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02406 IE = 1
02407 ITAUQ = ITAU
02408 ITAUP = ITAUQ + M
02409 IWORK = ITAUP + M
02410
02411
02412
02413
02414
02415 CALL CGEBRD( M, M, U, LDU, S, RWORK( IE ),
02416 $ WORK( ITAUQ ), WORK( ITAUP ),
02417 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02418
02419
02420
02421
02422
02423 CALL CUNMBR( 'P', 'L', 'C', M, N, M, U, LDU,
02424 $ WORK( ITAUP ), A, LDA, WORK( IWORK ),
02425 $ LWORK-IWORK+1, IERR )
02426
02427
02428
02429
02430
02431 CALL CUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
02432 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02433 IRWORK = IE + M
02434
02435
02436
02437
02438
02439
02440
02441 CALL CBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), A, LDA,
02442 $ U, LDU, CDUM, 1, RWORK( IRWORK ), INFO )
02443
02444 END IF
02445
02446 ELSE IF( WNTVS ) THEN
02447
02448 IF( WNTUN ) THEN
02449
02450
02451
02452
02453
02454 IF( LWORK.GE.M*M+3*M ) THEN
02455
02456
02457
02458 IR = 1
02459 IF( LWORK.GE.WRKBL+LDA*M ) THEN
02460
02461
02462
02463 LDWRKR = LDA
02464 ELSE
02465
02466
02467
02468 LDWRKR = M
02469 END IF
02470 ITAU = IR + LDWRKR*M
02471 IWORK = ITAU + M
02472
02473
02474
02475
02476
02477 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
02478 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02479
02480
02481
02482 CALL CLACPY( 'L', M, M, A, LDA, WORK( IR ),
02483 $ LDWRKR )
02484 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
02485 $ WORK( IR+LDWRKR ), LDWRKR )
02486
02487
02488
02489
02490
02491 CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
02492 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02493 IE = 1
02494 ITAUQ = ITAU
02495 ITAUP = ITAUQ + M
02496 IWORK = ITAUP + M
02497
02498
02499
02500
02501
02502 CALL CGEBRD( M, M, WORK( IR ), LDWRKR, S,
02503 $ RWORK( IE ), WORK( ITAUQ ),
02504 $ WORK( ITAUP ), WORK( IWORK ),
02505 $ LWORK-IWORK+1, IERR )
02506
02507
02508
02509
02510
02511
02512 CALL CUNGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
02513 $ WORK( ITAUP ), WORK( IWORK ),
02514 $ LWORK-IWORK+1, IERR )
02515 IRWORK = IE + M
02516
02517
02518
02519
02520
02521
02522 CALL CBDSQR( 'U', M, M, 0, 0, S, RWORK( IE ),
02523 $ WORK( IR ), LDWRKR, CDUM, 1, CDUM, 1,
02524 $ RWORK( IRWORK ), INFO )
02525
02526
02527
02528
02529
02530
02531 CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IR ),
02532 $ LDWRKR, A, LDA, CZERO, VT, LDVT )
02533
02534 ELSE
02535
02536
02537
02538 ITAU = 1
02539 IWORK = ITAU + M
02540
02541
02542
02543
02544
02545 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
02546 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02547
02548
02549
02550 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
02551
02552
02553
02554
02555
02556 CALL CUNGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
02557 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02558 IE = 1
02559 ITAUQ = ITAU
02560 ITAUP = ITAUQ + M
02561 IWORK = ITAUP + M
02562
02563
02564
02565 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
02566 $ A( 1, 2 ), LDA )
02567
02568
02569
02570
02571
02572 CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ),
02573 $ WORK( ITAUQ ), WORK( ITAUP ),
02574 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02575
02576
02577
02578
02579
02580 CALL CUNMBR( 'P', 'L', 'C', M, N, M, A, LDA,
02581 $ WORK( ITAUP ), VT, LDVT,
02582 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02583 IRWORK = IE + M
02584
02585
02586
02587
02588
02589
02590 CALL CBDSQR( 'U', M, N, 0, 0, S, RWORK( IE ), VT,
02591 $ LDVT, CDUM, 1, CDUM, 1,
02592 $ RWORK( IRWORK ), INFO )
02593
02594 END IF
02595
02596 ELSE IF( WNTUO ) THEN
02597
02598
02599
02600
02601
02602 IF( LWORK.GE.2*M*M+3*M ) THEN
02603
02604
02605
02606 IU = 1
02607 IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
02608
02609
02610
02611 LDWRKU = LDA
02612 IR = IU + LDWRKU*M
02613 LDWRKR = LDA
02614 ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
02615
02616
02617
02618 LDWRKU = LDA
02619 IR = IU + LDWRKU*M
02620 LDWRKR = M
02621 ELSE
02622
02623
02624
02625 LDWRKU = M
02626 IR = IU + LDWRKU*M
02627 LDWRKR = M
02628 END IF
02629 ITAU = IR + LDWRKR*M
02630 IWORK = ITAU + M
02631
02632
02633
02634
02635
02636 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
02637 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02638
02639
02640
02641 CALL CLACPY( 'L', M, M, A, LDA, WORK( IU ),
02642 $ LDWRKU )
02643 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
02644 $ WORK( IU+LDWRKU ), LDWRKU )
02645
02646
02647
02648
02649
02650 CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
02651 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02652 IE = 1
02653 ITAUQ = ITAU
02654 ITAUP = ITAUQ + M
02655 IWORK = ITAUP + M
02656
02657
02658
02659
02660
02661
02662
02663 CALL CGEBRD( M, M, WORK( IU ), LDWRKU, S,
02664 $ RWORK( IE ), WORK( ITAUQ ),
02665 $ WORK( ITAUP ), WORK( IWORK ),
02666 $ LWORK-IWORK+1, IERR )
02667 CALL CLACPY( 'L', M, M, WORK( IU ), LDWRKU,
02668 $ WORK( IR ), LDWRKR )
02669
02670
02671
02672
02673
02674
02675 CALL CUNGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
02676 $ WORK( ITAUP ), WORK( IWORK ),
02677 $ LWORK-IWORK+1, IERR )
02678
02679
02680
02681
02682
02683 CALL CUNGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
02684 $ WORK( ITAUQ ), WORK( IWORK ),
02685 $ LWORK-IWORK+1, IERR )
02686 IRWORK = IE + M
02687
02688
02689
02690
02691
02692
02693
02694 CALL CBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
02695 $ WORK( IU ), LDWRKU, WORK( IR ),
02696 $ LDWRKR, CDUM, 1, RWORK( IRWORK ),
02697 $ INFO )
02698
02699
02700
02701
02702
02703
02704 CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IU ),
02705 $ LDWRKU, A, LDA, CZERO, VT, LDVT )
02706
02707
02708
02709
02710
02711 CALL CLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
02712 $ LDA )
02713
02714 ELSE
02715
02716
02717
02718 ITAU = 1
02719 IWORK = ITAU + M
02720
02721
02722
02723
02724
02725 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
02726 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02727 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
02728
02729
02730
02731
02732
02733 CALL CUNGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
02734 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02735 IE = 1
02736 ITAUQ = ITAU
02737 ITAUP = ITAUQ + M
02738 IWORK = ITAUP + M
02739
02740
02741
02742 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
02743 $ A( 1, 2 ), LDA )
02744
02745
02746
02747
02748
02749 CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ),
02750 $ WORK( ITAUQ ), WORK( ITAUP ),
02751 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02752
02753
02754
02755
02756
02757 CALL CUNMBR( 'P', 'L', 'C', M, N, M, A, LDA,
02758 $ WORK( ITAUP ), VT, LDVT,
02759 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02760
02761
02762
02763
02764
02765 CALL CUNGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
02766 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02767 IRWORK = IE + M
02768
02769
02770
02771
02772
02773
02774
02775 CALL CBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), VT,
02776 $ LDVT, A, LDA, CDUM, 1,
02777 $ RWORK( IRWORK ), INFO )
02778
02779 END IF
02780
02781 ELSE IF( WNTUAS ) THEN
02782
02783
02784
02785
02786
02787
02788 IF( LWORK.GE.M*M+3*M ) THEN
02789
02790
02791
02792 IU = 1
02793 IF( LWORK.GE.WRKBL+LDA*M ) THEN
02794
02795
02796
02797 LDWRKU = LDA
02798 ELSE
02799
02800
02801
02802 LDWRKU = M
02803 END IF
02804 ITAU = IU + LDWRKU*M
02805 IWORK = ITAU + M
02806
02807
02808
02809
02810
02811 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
02812 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02813
02814
02815
02816 CALL CLACPY( 'L', M, M, A, LDA, WORK( IU ),
02817 $ LDWRKU )
02818 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
02819 $ WORK( IU+LDWRKU ), LDWRKU )
02820
02821
02822
02823
02824
02825 CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
02826 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02827 IE = 1
02828 ITAUQ = ITAU
02829 ITAUP = ITAUQ + M
02830 IWORK = ITAUP + M
02831
02832
02833
02834
02835
02836 CALL CGEBRD( M, M, WORK( IU ), LDWRKU, S,
02837 $ RWORK( IE ), WORK( ITAUQ ),
02838 $ WORK( ITAUP ), WORK( IWORK ),
02839 $ LWORK-IWORK+1, IERR )
02840 CALL CLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
02841 $ LDU )
02842
02843
02844
02845
02846
02847
02848 CALL CUNGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
02849 $ WORK( ITAUP ), WORK( IWORK ),
02850 $ LWORK-IWORK+1, IERR )
02851
02852
02853
02854
02855
02856 CALL CUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
02857 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02858 IRWORK = IE + M
02859
02860
02861
02862
02863
02864
02865
02866 CALL CBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
02867 $ WORK( IU ), LDWRKU, U, LDU, CDUM, 1,
02868 $ RWORK( IRWORK ), INFO )
02869
02870
02871
02872
02873
02874
02875 CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IU ),
02876 $ LDWRKU, A, LDA, CZERO, VT, LDVT )
02877
02878 ELSE
02879
02880
02881
02882 ITAU = 1
02883 IWORK = ITAU + M
02884
02885
02886
02887
02888
02889 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
02890 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02891 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
02892
02893
02894
02895
02896
02897 CALL CUNGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
02898 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02899
02900
02901
02902 CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
02903 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
02904 $ U( 1, 2 ), LDU )
02905 IE = 1
02906 ITAUQ = ITAU
02907 ITAUP = ITAUQ + M
02908 IWORK = ITAUP + M
02909
02910
02911
02912
02913
02914 CALL CGEBRD( M, M, U, LDU, S, RWORK( IE ),
02915 $ WORK( ITAUQ ), WORK( ITAUP ),
02916 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02917
02918
02919
02920
02921
02922
02923 CALL CUNMBR( 'P', 'L', 'C', M, N, M, U, LDU,
02924 $ WORK( ITAUP ), VT, LDVT,
02925 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02926
02927
02928
02929
02930
02931 CALL CUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
02932 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02933 IRWORK = IE + M
02934
02935
02936
02937
02938
02939
02940
02941 CALL CBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), VT,
02942 $ LDVT, U, LDU, CDUM, 1,
02943 $ RWORK( IRWORK ), INFO )
02944
02945 END IF
02946
02947 END IF
02948
02949 ELSE IF( WNTVA ) THEN
02950
02951 IF( WNTUN ) THEN
02952
02953
02954
02955
02956
02957 IF( LWORK.GE.M*M+MAX( N+M, 3*M ) ) THEN
02958
02959
02960
02961 IR = 1
02962 IF( LWORK.GE.WRKBL+LDA*M ) THEN
02963
02964
02965
02966 LDWRKR = LDA
02967 ELSE
02968
02969
02970
02971 LDWRKR = M
02972 END IF
02973 ITAU = IR + LDWRKR*M
02974 IWORK = ITAU + M
02975
02976
02977
02978
02979
02980 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
02981 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02982 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
02983
02984
02985
02986 CALL CLACPY( 'L', M, M, A, LDA, WORK( IR ),
02987 $ LDWRKR )
02988 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
02989 $ WORK( IR+LDWRKR ), LDWRKR )
02990
02991
02992
02993
02994
02995 CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
02996 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
02997 IE = 1
02998 ITAUQ = ITAU
02999 ITAUP = ITAUQ + M
03000 IWORK = ITAUP + M
03001
03002
03003
03004
03005
03006 CALL CGEBRD( M, M, WORK( IR ), LDWRKR, S,
03007 $ RWORK( IE ), WORK( ITAUQ ),
03008 $ WORK( ITAUP ), WORK( IWORK ),
03009 $ LWORK-IWORK+1, IERR )
03010
03011
03012
03013
03014
03015
03016 CALL CUNGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
03017 $ WORK( ITAUP ), WORK( IWORK ),
03018 $ LWORK-IWORK+1, IERR )
03019 IRWORK = IE + M
03020
03021
03022
03023
03024
03025
03026 CALL CBDSQR( 'U', M, M, 0, 0, S, RWORK( IE ),
03027 $ WORK( IR ), LDWRKR, CDUM, 1, CDUM, 1,
03028 $ RWORK( IRWORK ), INFO )
03029
03030
03031
03032
03033
03034
03035 CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IR ),
03036 $ LDWRKR, VT, LDVT, CZERO, A, LDA )
03037
03038
03039
03040 CALL CLACPY( 'F', M, N, A, LDA, VT, LDVT )
03041
03042 ELSE
03043
03044
03045
03046 ITAU = 1
03047 IWORK = ITAU + M
03048
03049
03050
03051
03052
03053 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
03054 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03055 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
03056
03057
03058
03059
03060
03061 CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
03062 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03063 IE = 1
03064 ITAUQ = ITAU
03065 ITAUP = ITAUQ + M
03066 IWORK = ITAUP + M
03067
03068
03069
03070 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
03071 $ A( 1, 2 ), LDA )
03072
03073
03074
03075
03076
03077 CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ),
03078 $ WORK( ITAUQ ), WORK( ITAUP ),
03079 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03080
03081
03082
03083
03084
03085
03086 CALL CUNMBR( 'P', 'L', 'C', M, N, M, A, LDA,
03087 $ WORK( ITAUP ), VT, LDVT,
03088 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03089 IRWORK = IE + M
03090
03091
03092
03093
03094
03095
03096 CALL CBDSQR( 'U', M, N, 0, 0, S, RWORK( IE ), VT,
03097 $ LDVT, CDUM, 1, CDUM, 1,
03098 $ RWORK( IRWORK ), INFO )
03099
03100 END IF
03101
03102 ELSE IF( WNTUO ) THEN
03103
03104
03105
03106
03107
03108 IF( LWORK.GE.2*M*M+MAX( N+M, 3*M ) ) THEN
03109
03110
03111
03112 IU = 1
03113 IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
03114
03115
03116
03117 LDWRKU = LDA
03118 IR = IU + LDWRKU*M
03119 LDWRKR = LDA
03120 ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
03121
03122
03123
03124 LDWRKU = LDA
03125 IR = IU + LDWRKU*M
03126 LDWRKR = M
03127 ELSE
03128
03129
03130
03131 LDWRKU = M
03132 IR = IU + LDWRKU*M
03133 LDWRKR = M
03134 END IF
03135 ITAU = IR + LDWRKR*M
03136 IWORK = ITAU + M
03137
03138
03139
03140
03141
03142 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
03143 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03144 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
03145
03146
03147
03148
03149
03150 CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
03151 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03152
03153
03154
03155 CALL CLACPY( 'L', M, M, A, LDA, WORK( IU ),
03156 $ LDWRKU )
03157 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
03158 $ WORK( IU+LDWRKU ), LDWRKU )
03159 IE = 1
03160 ITAUQ = ITAU
03161 ITAUP = ITAUQ + M
03162 IWORK = ITAUP + M
03163
03164
03165
03166
03167
03168
03169
03170 CALL CGEBRD( M, M, WORK( IU ), LDWRKU, S,
03171 $ RWORK( IE ), WORK( ITAUQ ),
03172 $ WORK( ITAUP ), WORK( IWORK ),
03173 $ LWORK-IWORK+1, IERR )
03174 CALL CLACPY( 'L', M, M, WORK( IU ), LDWRKU,
03175 $ WORK( IR ), LDWRKR )
03176
03177
03178
03179
03180
03181
03182 CALL CUNGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
03183 $ WORK( ITAUP ), WORK( IWORK ),
03184 $ LWORK-IWORK+1, IERR )
03185
03186
03187
03188
03189
03190 CALL CUNGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
03191 $ WORK( ITAUQ ), WORK( IWORK ),
03192 $ LWORK-IWORK+1, IERR )
03193 IRWORK = IE + M
03194
03195
03196
03197
03198
03199
03200
03201 CALL CBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
03202 $ WORK( IU ), LDWRKU, WORK( IR ),
03203 $ LDWRKR, CDUM, 1, RWORK( IRWORK ),
03204 $ INFO )
03205
03206
03207
03208
03209
03210
03211 CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IU ),
03212 $ LDWRKU, VT, LDVT, CZERO, A, LDA )
03213
03214
03215
03216 CALL CLACPY( 'F', M, N, A, LDA, VT, LDVT )
03217
03218
03219
03220 CALL CLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
03221 $ LDA )
03222
03223 ELSE
03224
03225
03226
03227 ITAU = 1
03228 IWORK = ITAU + M
03229
03230
03231
03232
03233
03234 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
03235 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03236 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
03237
03238
03239
03240
03241
03242 CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
03243 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03244 IE = 1
03245 ITAUQ = ITAU
03246 ITAUP = ITAUQ + M
03247 IWORK = ITAUP + M
03248
03249
03250
03251 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
03252 $ A( 1, 2 ), LDA )
03253
03254
03255
03256
03257
03258 CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ),
03259 $ WORK( ITAUQ ), WORK( ITAUP ),
03260 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03261
03262
03263
03264
03265
03266
03267 CALL CUNMBR( 'P', 'L', 'C', M, N, M, A, LDA,
03268 $ WORK( ITAUP ), VT, LDVT,
03269 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03270
03271
03272
03273
03274
03275 CALL CUNGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
03276 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03277 IRWORK = IE + M
03278
03279
03280
03281
03282
03283
03284
03285 CALL CBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), VT,
03286 $ LDVT, A, LDA, CDUM, 1,
03287 $ RWORK( IRWORK ), INFO )
03288
03289 END IF
03290
03291 ELSE IF( WNTUAS ) THEN
03292
03293
03294
03295
03296
03297
03298 IF( LWORK.GE.M*M+MAX( N+M, 3*M ) ) THEN
03299
03300
03301
03302 IU = 1
03303 IF( LWORK.GE.WRKBL+LDA*M ) THEN
03304
03305
03306
03307 LDWRKU = LDA
03308 ELSE
03309
03310
03311
03312 LDWRKU = M
03313 END IF
03314 ITAU = IU + LDWRKU*M
03315 IWORK = ITAU + M
03316
03317
03318
03319
03320
03321 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
03322 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03323 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
03324
03325
03326
03327
03328
03329 CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
03330 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03331
03332
03333
03334 CALL CLACPY( 'L', M, M, A, LDA, WORK( IU ),
03335 $ LDWRKU )
03336 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
03337 $ WORK( IU+LDWRKU ), LDWRKU )
03338 IE = 1
03339 ITAUQ = ITAU
03340 ITAUP = ITAUQ + M
03341 IWORK = ITAUP + M
03342
03343
03344
03345
03346
03347 CALL CGEBRD( M, M, WORK( IU ), LDWRKU, S,
03348 $ RWORK( IE ), WORK( ITAUQ ),
03349 $ WORK( ITAUP ), WORK( IWORK ),
03350 $ LWORK-IWORK+1, IERR )
03351 CALL CLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
03352 $ LDU )
03353
03354
03355
03356
03357
03358 CALL CUNGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
03359 $ WORK( ITAUP ), WORK( IWORK ),
03360 $ LWORK-IWORK+1, IERR )
03361
03362
03363
03364
03365
03366 CALL CUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
03367 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03368 IRWORK = IE + M
03369
03370
03371
03372
03373
03374
03375
03376 CALL CBDSQR( 'U', M, M, M, 0, S, RWORK( IE ),
03377 $ WORK( IU ), LDWRKU, U, LDU, CDUM, 1,
03378 $ RWORK( IRWORK ), INFO )
03379
03380
03381
03382
03383
03384
03385 CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IU ),
03386 $ LDWRKU, VT, LDVT, CZERO, A, LDA )
03387
03388
03389
03390 CALL CLACPY( 'F', M, N, A, LDA, VT, LDVT )
03391
03392 ELSE
03393
03394
03395
03396 ITAU = 1
03397 IWORK = ITAU + M
03398
03399
03400
03401
03402
03403 CALL CGELQF( M, N, A, LDA, WORK( ITAU ),
03404 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03405 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
03406
03407
03408
03409
03410
03411 CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
03412 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03413
03414
03415
03416 CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
03417 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
03418 $ U( 1, 2 ), LDU )
03419 IE = 1
03420 ITAUQ = ITAU
03421 ITAUP = ITAUQ + M
03422 IWORK = ITAUP + M
03423
03424
03425
03426
03427
03428 CALL CGEBRD( M, M, U, LDU, S, RWORK( IE ),
03429 $ WORK( ITAUQ ), WORK( ITAUP ),
03430 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03431
03432
03433
03434
03435
03436
03437 CALL CUNMBR( 'P', 'L', 'C', M, N, M, U, LDU,
03438 $ WORK( ITAUP ), VT, LDVT,
03439 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03440
03441
03442
03443
03444
03445 CALL CUNGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
03446 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03447 IRWORK = IE + M
03448
03449
03450
03451
03452
03453
03454
03455 CALL CBDSQR( 'U', M, N, M, 0, S, RWORK( IE ), VT,
03456 $ LDVT, U, LDU, CDUM, 1,
03457 $ RWORK( IRWORK ), INFO )
03458
03459 END IF
03460
03461 END IF
03462
03463 END IF
03464
03465 ELSE
03466
03467
03468
03469
03470
03471
03472 IE = 1
03473 ITAUQ = 1
03474 ITAUP = ITAUQ + M
03475 IWORK = ITAUP + M
03476
03477
03478
03479
03480
03481 CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
03482 $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
03483 $ IERR )
03484 IF( WNTUAS ) THEN
03485
03486
03487
03488
03489
03490
03491 CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
03492 CALL CUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
03493 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03494 END IF
03495 IF( WNTVAS ) THEN
03496
03497
03498
03499
03500
03501
03502 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
03503 IF( WNTVA )
03504 $ NRVT = N
03505 IF( WNTVS )
03506 $ NRVT = M
03507 CALL CUNGBR( 'P', NRVT, N, M, VT, LDVT, WORK( ITAUP ),
03508 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03509 END IF
03510 IF( WNTUO ) THEN
03511
03512
03513
03514
03515
03516
03517 CALL CUNGBR( 'Q', M, M, N, A, LDA, WORK( ITAUQ ),
03518 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03519 END IF
03520 IF( WNTVO ) THEN
03521
03522
03523
03524
03525
03526
03527 CALL CUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
03528 $ WORK( IWORK ), LWORK-IWORK+1, IERR )
03529 END IF
03530 IRWORK = IE + M
03531 IF( WNTUAS .OR. WNTUO )
03532 $ NRU = M
03533 IF( WNTUN )
03534 $ NRU = 0
03535 IF( WNTVAS .OR. WNTVO )
03536 $ NCVT = N
03537 IF( WNTVN )
03538 $ NCVT = 0
03539 IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
03540
03541
03542
03543
03544
03545
03546
03547 CALL CBDSQR( 'L', M, NCVT, NRU, 0, S, RWORK( IE ), VT,
03548 $ LDVT, U, LDU, CDUM, 1, RWORK( IRWORK ),
03549 $ INFO )
03550 ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
03551
03552
03553
03554
03555
03556
03557
03558 CALL CBDSQR( 'L', M, NCVT, NRU, 0, S, RWORK( IE ), A,
03559 $ LDA, U, LDU, CDUM, 1, RWORK( IRWORK ),
03560 $ INFO )
03561 ELSE
03562
03563
03564
03565
03566
03567
03568
03569 CALL CBDSQR( 'L', M, NCVT, NRU, 0, S, RWORK( IE ), VT,
03570 $ LDVT, A, LDA, CDUM, 1, RWORK( IRWORK ),
03571 $ INFO )
03572 END IF
03573
03574 END IF
03575
03576 END IF
03577
03578
03579
03580 IF( ISCL.EQ.1 ) THEN
03581 IF( ANRM.GT.BIGNUM )
03582 $ CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
03583 $ IERR )
03584 IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
03585 $ CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1,
03586 $ RWORK( IE ), MINMN, IERR )
03587 IF( ANRM.LT.SMLNUM )
03588 $ CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
03589 $ IERR )
03590 IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
03591 $ CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1,
03592 $ RWORK( IE ), MINMN, IERR )
03593 END IF
03594
03595
03596
03597 WORK( 1 ) = MAXWRK
03598
03599 RETURN
03600
03601
03602
03603 END