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