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