Replace Workspace calculations by calls to the routines with LWORK=-1.
This impacts only three routines: xGESVD, xGELSS, x[OR/UN]GBR
Testing have been run to check that the workspace size return is the same.
In a further effort (next major release probably), LAPACK will need to stick
to that LWORK=-1 rule to compute Workspace size.
INTEGER BL, CHUNK, I, IASCL, IBSCL, IE, IL, IRWORK,
$ ITAU, ITAUP, ITAUQ, IWORK, LDWORK, MAXMN,
$ MAXWRK, MINMN, MINWRK, MM, MNTHR
+ INTEGER LWORK_CGEQRF, LWORK_CUNMQR, LWORK_CGEBRD,
+ $ LWORK_CUNMBR, LWORK_CUNGBR, LWORK_CUNMLQ,
+ $ LWORK_CGELQF
REAL ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
* ..
* .. Local Arrays ..
- COMPLEX VDUM( 1 )
+ COMPLEX DUM( 1 )
* ..
* .. External Subroutines ..
EXTERNAL CBDSQR, CCOPY, CGEBRD, CGELQF, CGEMM, CGEMV,
* Path 1a - overdetermined, with many more rows than
* columns
*
+* Compute space needed for CGEQRF
+ CALL CGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, INFO )
+ LWORK_CGEQRF=DUM(1)
+* Compute space needed for CUNMQR
+ CALL CUNMQR( 'L', 'C', M, NRHS, N, A, LDA, DUM(1), B,
+ $ LDB, DUM(1), -1, INFO )
+ LWORK_CUNMQR=DUM(1)
MM = N
MAXWRK = MAX( MAXWRK, N + N*ILAENV( 1, 'CGEQRF', ' ', M,
$ N, -1, -1 ) )
*
* Path 1 - overdetermined or exactly determined
*
- MAXWRK = MAX( MAXWRK, 2*N + ( MM + N )*ILAENV( 1,
- $ 'CGEBRD', ' ', MM, N, -1, -1 ) )
- MAXWRK = MAX( MAXWRK, 2*N + NRHS*ILAENV( 1, 'CUNMBR',
- $ 'QLC', MM, NRHS, N, -1 ) )
- MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
- $ 'CUNGBR', 'P', N, N, N, -1 ) )
+* Compute space needed for CGEBRD
+ CALL CGEBRD( MM, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, INFO )
+ LWORK_CGEBRD=DUM(1)
+* Compute space needed for CUNMBR
+ CALL CUNMBR( 'Q', 'L', 'C', MM, NRHS, N, A, LDA, DUM(1),
+ $ B, LDB, DUM(1), -1, INFO )
+ LWORK_CUNMBR=DUM(1)
+* Compute space needed for CUNGBR
+ CALL CUNGBR( 'P', N, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, INFO )
+ LWORK_CUNGBR=DUM(1)
+* Compute total workspace needed
+ MAXWRK = MAX( MAXWRK, 2*N + LWORK_CGEBRD )
+ MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR )
+ MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR )
MAXWRK = MAX( MAXWRK, N*NRHS )
MINWRK = 2*N + MAX( NRHS, M )
END IF
* Path 2a - underdetermined, with many more columns
* than rows
*
- MAXWRK = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1,
- $ -1 )
- MAXWRK = MAX( MAXWRK, 3*M + M*M + 2*M*ILAENV( 1,
- $ 'CGEBRD', ' ', M, M, -1, -1 ) )
- MAXWRK = MAX( MAXWRK, 3*M + M*M + NRHS*ILAENV( 1,
- $ 'CUNMBR', 'QLC', M, NRHS, M, -1 ) )
- MAXWRK = MAX( MAXWRK, 3*M + M*M + ( M - 1 )*ILAENV( 1,
- $ 'CUNGBR', 'P', M, M, M, -1 ) )
+* Compute space needed for CGELQF
+ CALL CGELQF( M, N, A, LDA, DUM(1), DUM(1),
+ $ -1, INFO )
+ LWORK_CGELQF=DUM(1)
+* Compute space needed for CGEBRD
+ CALL CGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, INFO )
+ LWORK_CGEBRD=DUM(1)
+* Compute space needed for CUNMBR
+ CALL CUNMBR( 'Q', 'L', 'C', M, NRHS, N, A, LDA,
+ $ DUM(1), B, LDB, DUM(1), -1, INFO )
+ LWORK_CUNMBR=DUM(1)
+* Compute space needed for CUNGBR
+ CALL CUNGBR( 'P', M, M, M, A, LDA, DUM(1),
+ $ DUM(1), -1, INFO )
+ LWORK_CUNGBR=DUM(1)
+* Compute space needed for CUNMLQ
+ CALL CUNMLQ( 'L', 'C', N, NRHS, M, A, LDA, DUM(1),
+ $ B, LDB, DUM(1), -1, INFO )
+ LWORK_CUNMLQ=DUM(1)
+* Compute total workspace needed
+ MAXWRK = M + LWORK_CGELQF
+ MAXWRK = MAX( MAXWRK, 3*M + M*M + LWORK_CGEBRD )
+ MAXWRK = MAX( MAXWRK, 3*M + M*M + LWORK_CUNMBR )
+ MAXWRK = MAX( MAXWRK, 3*M + M*M + LWORK_CUNGBR )
IF( NRHS.GT.1 ) THEN
MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
ELSE
MAXWRK = MAX( MAXWRK, M*M + 2*M )
END IF
- MAXWRK = MAX( MAXWRK, M + NRHS*ILAENV( 1, 'CUNMLQ',
- $ 'LC', N, NRHS, M, -1 ) )
+ MAXWRK = MAX( MAXWRK, M + LWORK_CUNMLQ )
ELSE
*
* Path 2 - underdetermined
*
- MAXWRK = 2*M + ( N + M )*ILAENV( 1, 'CGEBRD', ' ', M,
- $ N, -1, -1 )
- MAXWRK = MAX( MAXWRK, 2*M + NRHS*ILAENV( 1, 'CUNMBR',
- $ 'QLC', M, NRHS, M, -1 ) )
- MAXWRK = MAX( MAXWRK, 2*M + M*ILAENV( 1, 'CUNGBR',
- $ 'P', M, N, M, -1 ) )
+* Compute space needed for CGEBRD
+ CALL CGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, INFO )
+ LWORK_CGEBRD=DUM(1)
+* Compute space needed for CUNMBR
+ CALL CUNMBR( 'Q', 'L', 'C', M, NRHS, M, A, LDA,
+ $ DUM(1), B, LDB, DUM(1), -1, INFO )
+ LWORK_CUNMBR=DUM(1)
+* Compute space needed for CUNGBR
+ CALL CUNGBR( 'P', M, N, M, A, LDA, DUM(1),
+ $ DUM(1), -1, INFO )
+ LWORK_CUNGBR=DUM(1)
+ MAXWRK = 2*M + LWORK_CGEBRD
+ MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR )
+ MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR )
MAXWRK = MAX( MAXWRK, N*NRHS )
END IF
END IF
* (CWorkspace: none)
* (RWorkspace: need BDSPAC)
*
- CALL CBDSQR( 'U', N, N, 0, NRHS, S, RWORK( IE ), A, LDA, VDUM,
+ CALL CBDSQR( 'U', N, N, 0, NRHS, S, RWORK( IE ), A, LDA, DUM,
$ 1, B, LDB, RWORK( IRWORK ), INFO )
IF( INFO.NE.0 )
$ GO TO 70
* (CWorkspace: none)
* (RWorkspace: need BDSPAC)
*
- CALL CBDSQR( 'L', M, N, 0, NRHS, S, RWORK( IE ), A, LDA, VDUM,
+ CALL CBDSQR( 'L', M, N, 0, NRHS, S, RWORK( IE ), A, LDA, DUM,
$ 1, B, LDB, RWORK( IRWORK ), INFO )
IF( INFO.NE.0 )
$ GO TO 70
$ ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,
$ MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,
$ NRVT, WRKBL
+ INTEGER LWORK_CGEQRF, LWORK_CUNGQR_N, LWORK_CUNGQR_M,
+ $ LWORK_CGEBRD, LWORK_CUNGBR_P, LWORK_CUNGBR_Q,
+ $ LWORK_CGELQF, LWORK_CUNGLQ_N, LWORK_CUNGLQ_M
REAL ANRM, BIGNUM, EPS, SMLNUM
* ..
* .. Local Arrays ..
MAXWRK = 1
IF( M.GE.N .AND. MINMN.GT.0 ) THEN
*
-* Space needed for CBDSQR is BDSPAC = 5*N
+* Space needed for ZBDSQR is BDSPAC = 5*N
+*
+ MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
+* Compute space needed for CGEQRF
+ CALL CGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_CGEQRF=DUM(1)
+* Compute space needed for CUNGQR
+ CALL CUNGQR( M, N, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_CUNGQR_N=DUM(1)
+ CALL CUNGQR( M, M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_CUNGQR_M=DUM(1)
+* Compute space needed for CGEBRD
+ CALL CGEBRD( N, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_CGEBRD=DUM(1)
+* Compute space needed for CUNGBR
+ CALL CUNGBR( 'P', N, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_CUNGBR_P=DUM(1)
+ CALL CUNGBR( 'Q', N, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_CUNGBR_Q=DUM(1)
*
MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
IF( M.GE.MNTHR ) THEN
*
* Path 1 (M much larger than N, JOBU='N')
*
- MAXWRK = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1,
- $ -1 )
- MAXWRK = MAX( MAXWRK, 2*N+2*N*
- $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
+ MAXWRK = N + LWORK_CGEQRF
+ MAXWRK = MAX( MAXWRK, 2*N+LWORK_CGEBRD )
IF( WNTVO .OR. WNTVAS )
- $ MAXWRK = MAX( MAXWRK, 2*N+( N-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+ $ MAXWRK = MAX( MAXWRK, 2*N+LWORK_CUNGBR_P )
MINWRK = 3*N
ELSE IF( WNTUO .AND. WNTVN ) THEN
*
* Path 2 (M much larger than N, JOBU='O', JOBVT='N')
*
- WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
+ WRKBL = N + LWORK_CGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_CUNGQR_N )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_Q )
MAXWRK = MAX( N*N+WRKBL, N*N+M*N )
MINWRK = 2*N + M
ELSE IF( WNTUO .AND. WNTVAS ) THEN
* Path 3 (M much larger than N, JOBU='O', JOBVT='S' or
* 'A')
*
- WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+( N-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_CGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_CUNGQR_N )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_Q )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_P )
MAXWRK = MAX( N*N+WRKBL, N*N+M*N )
MINWRK = 2*N + M
ELSE IF( WNTUS .AND. WNTVN ) THEN
*
* Path 4 (M much larger than N, JOBU='S', JOBVT='N')
*
- WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
+ WRKBL = N + LWORK_CGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_CUNGQR_N )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_Q )
MAXWRK = N*N + WRKBL
MINWRK = 2*N + M
ELSE IF( WNTUS .AND. WNTVO ) THEN
*
* Path 5 (M much larger than N, JOBU='S', JOBVT='O')
*
- WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+( N-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_CGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_CUNGQR_N )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_Q )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_P )
MAXWRK = 2*N*N + WRKBL
MINWRK = 2*N + M
ELSE IF( WNTUS .AND. WNTVAS ) THEN
* Path 6 (M much larger than N, JOBU='S', JOBVT='S' or
* 'A')
*
- WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+( N-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_CGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_CUNGQR_N )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_Q )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_P )
MAXWRK = N*N + WRKBL
MINWRK = 2*N + M
ELSE IF( WNTUA .AND. WNTVN ) THEN
*
* Path 7 (M much larger than N, JOBU='A', JOBVT='N')
*
- WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'CUNGQR', ' ', M,
- $ M, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
+ WRKBL = N + LWORK_CGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_CUNGQR_M )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_Q )
MAXWRK = N*N + WRKBL
MINWRK = 2*N + M
ELSE IF( WNTUA .AND. WNTVO ) THEN
*
* Path 8 (M much larger than N, JOBU='A', JOBVT='O')
*
- WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'CUNGQR', ' ', M,
- $ M, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+( N-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_CGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_CUNGQR_M )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_Q )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_P )
MAXWRK = 2*N*N + WRKBL
MINWRK = 2*N + M
ELSE IF( WNTUA .AND. WNTVAS ) THEN
* Path 9 (M much larger than N, JOBU='A', JOBVT='S' or
* 'A')
*
- WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'CUNGQR', ' ', M,
- $ M, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'CUNGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+( N-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_CGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_CUNGQR_M )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_Q )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_CUNGBR_P )
MAXWRK = N*N + WRKBL
MINWRK = 2*N + M
END IF
*
* Path 10 (M at least N, but not much larger)
*
- MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'CGEBRD', ' ', M, N,
- $ -1, -1 )
- IF( WNTUS .OR. WNTUO )
- $ MAXWRK = MAX( MAXWRK, 2*N+N*
- $ ILAENV( 1, 'CUNGBR', 'Q', M, N, N, -1 ) )
- IF( WNTUA )
- $ MAXWRK = MAX( MAXWRK, 2*N+M*
- $ ILAENV( 1, 'CUNGBR', 'Q', M, M, N, -1 ) )
- IF( .NOT.WNTVN )
- $ MAXWRK = MAX( MAXWRK, 2*N+( N-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
+ CALL CGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_CGEBRD=DUM(1)
+ MAXWRK = 2*N + LWORK_CGEBRD
+ IF( WNTUS .OR. WNTUO ) THEN
+ CALL CUNGBR( 'Q', M, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_CUNGBR_Q=DUM(1)
+ MAXWRK = MAX( MAXWRK, 2*N+LWORK_CUNGBR_Q )
+ END IF
+ IF( WNTUA ) THEN
+ CALL CUNGBR( 'Q', M, M, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_CUNGBR_Q=DUM(1)
+ MAXWRK = MAX( MAXWRK, 2*N+LWORK_CUNGBR_Q )
+ END IF
+ IF( .NOT.WNTVN ) THEN
+ MAXWRK = MAX( MAXWRK, 2*N+LWORK_CUNGBR_P )
MINWRK = 2*N + M
+ END IF
END IF
ELSE IF( MINMN.GT.0 ) THEN
*
* Space needed for CBDSQR is BDSPAC = 5*M
*
MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
+* Compute space needed for CGELQF
+ CALL CGELQF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_CGELQF=DUM(1)
+* Compute space needed for CUNGLQ
+ CALL CUNGLQ( N, N, M, VT, LDVT, DUM(1), DUM(1), -1, IERR )
+ LWORK_CUNGLQ_N=DUM(1)
+ CALL CUNGLQ( M, N, M, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_CUNGLQ_M=DUM(1)
+* Compute space needed for CGEBRD
+ CALL CGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_CGEBRD=DUM(1)
+* Compute space needed for CUNGBR P
+ CALL CUNGBR( 'P', M, M, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_CUNGBR_P=DUM(1)
+* Compute space needed for CUNGBR Q
+ CALL CUNGBR( 'Q', M, M, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_CUNGBR_Q=DUM(1)
IF( N.GE.MNTHR ) THEN
IF( WNTVN ) THEN
*
* Path 1t(N much larger than M, JOBVT='N')
*
- MAXWRK = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1,
- $ -1 )
- MAXWRK = MAX( MAXWRK, 2*M+2*M*
- $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
+ MAXWRK = M + LWORK_CGELQF
+ MAXWRK = MAX( MAXWRK, 2*M+LWORK_CGEBRD )
IF( WNTUO .OR. WNTUAS )
- $ MAXWRK = MAX( MAXWRK, 2*M+M*
- $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+ $ MAXWRK = MAX( MAXWRK, 2*M+LWORK_CUNGBR_Q )
MINWRK = 3*M
ELSE IF( WNTVO .AND. WNTUN ) THEN
*
* Path 2t(N much larger than M, JOBU='N', JOBVT='O')
*
- WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
+ WRKBL = M + LWORK_CGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_CUNGLQ_M )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_P )
MAXWRK = MAX( M*M+WRKBL, M*M+M*N )
MINWRK = 2*M + N
ELSE IF( WNTVO .AND. WNTUAS ) THEN
* Path 3t(N much larger than M, JOBU='S' or 'A',
* JOBVT='O')
*
- WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+M*
- $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_CGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_CUNGLQ_M )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_P )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_Q )
MAXWRK = MAX( M*M+WRKBL, M*M+M*N )
MINWRK = 2*M + N
ELSE IF( WNTVS .AND. WNTUN ) THEN
*
* Path 4t(N much larger than M, JOBU='N', JOBVT='S')
*
- WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
+ WRKBL = M + LWORK_CGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_CUNGLQ_M )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_P )
MAXWRK = M*M + WRKBL
MINWRK = 2*M + N
ELSE IF( WNTVS .AND. WNTUO ) THEN
*
* Path 5t(N much larger than M, JOBU='O', JOBVT='S')
*
- WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+M*
- $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_CGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_CUNGLQ_M )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_P )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_Q )
MAXWRK = 2*M*M + WRKBL
MINWRK = 2*M + N
ELSE IF( WNTVS .AND. WNTUAS ) THEN
* Path 6t(N much larger than M, JOBU='S' or 'A',
* JOBVT='S')
*
- WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+M*
- $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_CGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_CUNGLQ_M )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_P )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_Q )
MAXWRK = M*M + WRKBL
MINWRK = 2*M + N
ELSE IF( WNTVA .AND. WNTUN ) THEN
*
* Path 7t(N much larger than M, JOBU='N', JOBVT='A')
*
- WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'CUNGLQ', ' ', N,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
+ WRKBL = M + LWORK_CGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_CUNGLQ_N )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_P )
MAXWRK = M*M + WRKBL
MINWRK = 2*M + N
ELSE IF( WNTVA .AND. WNTUO ) THEN
*
* Path 8t(N much larger than M, JOBU='O', JOBVT='A')
*
- WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'CUNGLQ', ' ', N,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+M*
- $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_CGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_CUNGLQ_N )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_P )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_Q )
MAXWRK = 2*M*M + WRKBL
MINWRK = 2*M + N
ELSE IF( WNTVA .AND. WNTUAS ) THEN
* Path 9t(N much larger than M, JOBU='S' or 'A',
* JOBVT='A')
*
- WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'CUNGLQ', ' ', N,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'CUNGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+M*
- $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_CGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_CUNGLQ_N )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_P )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_CUNGBR_Q )
MAXWRK = M*M + WRKBL
MINWRK = 2*M + N
END IF
*
* Path 10t(N greater than M, but not much larger)
*
- MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'CGEBRD', ' ', M, N,
- $ -1, -1 )
- IF( WNTVS .OR. WNTVO )
- $ MAXWRK = MAX( MAXWRK, 2*M+M*
- $ ILAENV( 1, 'CUNGBR', 'P', M, N, M, -1 ) )
- IF( WNTVA )
- $ MAXWRK = MAX( MAXWRK, 2*M+N*
- $ ILAENV( 1, 'CUNGBR', 'P', N, N, M, -1 ) )
- IF( .NOT.WNTUN )
- $ MAXWRK = MAX( MAXWRK, 2*M+( M-1 )*
- $ ILAENV( 1, 'CUNGBR', 'Q', M, M, M, -1 ) )
+ CALL CGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_CGEBRD=DUM(1)
+ MAXWRK = 2*M + LWORK_CGEBRD
+ IF( WNTVS .OR. WNTVO ) THEN
+* Compute space needed for CUNGBR P
+ CALL CUNGBR( 'P', M, N, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_CUNGBR_P=DUM(1)
+ MAXWRK = MAX( MAXWRK, 2*M+LWORK_CUNGBR_P )
+ END IF
+ IF( WNTVA ) THEN
+ CALL CUNGBR( 'P', N, N, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_CUNGBR_P=DUM(1)
+ MAXWRK = MAX( MAXWRK, 2*M+LWORK_CUNGBR_P )
+ END IF
+ IF( .NOT.WNTUN ) THEN
+ MAXWRK = MAX( MAXWRK, 2*M+LWORK_CUNGBR_Q )
MINWRK = 2*M + N
+ END IF
END IF
END IF
MAXWRK = MAX( MINWRK, MAXWRK )
*
IF( INFO.EQ.0 ) THEN
IF( WANTQ ) THEN
- NB = ILAENV( 1, 'CUNGQR', ' ', M, N, K, -1 )
+ IF( M.GE.K ) THEN
+ CALL CUNGQR( M, N, K, A, LDA, TAU, WORK, -1, IINFO )
+ ELSE
+ CALL CUNGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK,
+ $ -1, IINFO )
+ END IF
ELSE
- NB = ILAENV( 1, 'CUNGLQ', ' ', M, N, K, -1 )
+ IF( K.LT.N ) THEN
+ CALL CUNGLQ( M, N, K, A, LDA, TAU, WORK, -1, IINFO )
+ ELSE
+ CALL CUNGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,
+ $ -1, IINFO )
+ END IF
END IF
- LWKOPT = MAX( 1, MN )*NB
- WORK( 1 ) = LWKOPT
+ LWKOPT = WORK( 1 )
END IF
*
IF( INFO.NE.0 ) THEN
INTEGER BDSPAC, BL, CHUNK, I, IASCL, IBSCL, IE, IL,
$ ITAU, ITAUP, ITAUQ, IWORK, LDWORK, MAXMN,
$ MAXWRK, MINMN, MINWRK, MM, MNTHR
+ INTEGER LWORK_DGEQRF, LWORK_DORMQR, LWORK_DGEBRD,
+ $ LWORK_DORMBR, LWORK_DORGBR, LWORK_DORMLQ,
+ $ LWORK_DGELQF
DOUBLE PRECISION ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
* ..
* .. Local Arrays ..
- DOUBLE PRECISION VDUM( 1 )
+ DOUBLE PRECISION DUM( 1 )
* ..
* .. External Subroutines ..
EXTERNAL DBDSQR, DCOPY, DGEBRD, DGELQF, DGEMM, DGEMV,
* Path 1a - overdetermined, with many more rows than
* columns
*
+* Compute space needed for DGEQRF
+ CALL DGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, INFO )
+ LWORK_DGEQRF=DUM(1)
+* Compute space needed for DORMQR
+ CALL DORMQR( 'L', 'T', M, NRHS, N, A, LDA, DUM(1), B,
+ $ LDB, DUM(1), -1, INFO )
+ LWORK_DORMQR=DUM(1)
MM = N
- MAXWRK = MAX( MAXWRK, N + N*ILAENV( 1, 'DGEQRF', ' ', M,
- $ N, -1, -1 ) )
- MAXWRK = MAX( MAXWRK, N + NRHS*ILAENV( 1, 'DORMQR', 'LT',
- $ M, NRHS, N, -1 ) )
+ MAXWRK = MAX( MAXWRK, N + LWORK_DGEQRF )
+ MAXWRK = MAX( MAXWRK, N + LWORK_DORMQR )
END IF
IF( M.GE.N ) THEN
*
* Compute workspace needed for DBDSQR
*
BDSPAC = MAX( 1, 5*N )
- MAXWRK = MAX( MAXWRK, 3*N + ( MM + N )*ILAENV( 1,
- $ 'DGEBRD', ' ', MM, N, -1, -1 ) )
- MAXWRK = MAX( MAXWRK, 3*N + NRHS*ILAENV( 1, 'DORMBR',
- $ 'QLT', MM, NRHS, N, -1 ) )
- MAXWRK = MAX( MAXWRK, 3*N + ( N - 1 )*ILAENV( 1,
- $ 'DORGBR', 'P', N, N, N, -1 ) )
+* Compute space needed for DGEBRD
+ CALL DGEBRD( MM, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, INFO )
+ LWORK_DGEBRD=DUM(1)
+* Compute space needed for DORMBR
+ CALL DORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, DUM(1),
+ $ B, LDB, DUM(1), -1, INFO )
+ LWORK_DORMBR=DUM(1)
+* Compute space needed for DORGBR
+ CALL DORGBR( 'P', N, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, INFO )
+ LWORK_DORGBR=DUM(1)
+* Compute total workspace needed
+ MAXWRK = MAX( MAXWRK, 3*N + LWORK_DGEBRD )
+ MAXWRK = MAX( MAXWRK, 3*N + LWORK_DORMBR )
+ MAXWRK = MAX( MAXWRK, 3*N + LWORK_DORGBR )
MAXWRK = MAX( MAXWRK, BDSPAC )
MAXWRK = MAX( MAXWRK, N*NRHS )
MINWRK = MAX( 3*N + MM, 3*N + NRHS, BDSPAC )
* Path 2a - underdetermined, with many more columns
* than rows
*
- MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1,
- $ -1 )
- MAXWRK = MAX( MAXWRK, M*M + 4*M + 2*M*ILAENV( 1,
- $ 'DGEBRD', ' ', M, M, -1, -1 ) )
- MAXWRK = MAX( MAXWRK, M*M + 4*M + NRHS*ILAENV( 1,
- $ 'DORMBR', 'QLT', M, NRHS, M, -1 ) )
- MAXWRK = MAX( MAXWRK, M*M + 4*M +
- $ ( M - 1 )*ILAENV( 1, 'DORGBR', 'P', M,
- $ M, M, -1 ) )
+* Compute space needed for DGELQF
+ CALL DGELQF( M, N, A, LDA, DUM(1), DUM(1),
+ $ -1, INFO )
+ LWORK_DGELQF=DUM(1)
+* Compute space needed for DGEBRD
+ CALL DGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, INFO )
+ LWORK_DGEBRD=DUM(1)
+* Compute space needed for DORMBR
+ CALL DORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA,
+ $ DUM(1), B, LDB, DUM(1), -1, INFO )
+ LWORK_DORMBR=DUM(1)
+* Compute space needed for DORGBR
+ CALL DORGBR( 'P', M, M, M, A, LDA, DUM(1),
+ $ DUM(1), -1, INFO )
+ LWORK_DORGBR=DUM(1)
+* Compute space needed for DORMLQ
+ CALL DORMLQ( 'L', 'T', N, NRHS, M, A, LDA, DUM(1),
+ $ B, LDB, DUM(1), -1, INFO )
+ LWORK_DORMLQ=DUM(1)
+* Compute total workspace needed
+ MAXWRK = M + LWORK_DGELQF
+ MAXWRK = MAX( MAXWRK, M*M + 4*M + LWORK_DGEBRD )
+ MAXWRK = MAX( MAXWRK, M*M + 4*M + LWORK_DORMBR )
+ MAXWRK = MAX( MAXWRK, M*M + 4*M + LWORK_DORGBR )
MAXWRK = MAX( MAXWRK, M*M + M + BDSPAC )
IF( NRHS.GT.1 ) THEN
MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
ELSE
MAXWRK = MAX( MAXWRK, M*M + 2*M )
END IF
- MAXWRK = MAX( MAXWRK, M + NRHS*ILAENV( 1, 'DORMLQ',
- $ 'LT', N, NRHS, M, -1 ) )
+ MAXWRK = MAX( MAXWRK, M + LWORK_DORMLQ )
ELSE
*
* Path 2 - underdetermined
*
- MAXWRK = 3*M + ( N + M )*ILAENV( 1, 'DGEBRD', ' ', M,
- $ N, -1, -1 )
- MAXWRK = MAX( MAXWRK, 3*M + NRHS*ILAENV( 1, 'DORMBR',
- $ 'QLT', M, NRHS, M, -1 ) )
- MAXWRK = MAX( MAXWRK, 3*M + M*ILAENV( 1, 'DORGBR',
- $ 'P', M, N, M, -1 ) )
+* Compute space needed for DGEBRD
+ CALL DGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, INFO )
+ LWORK_DGEBRD=DUM(1)
+* Compute space needed for DORMBR
+ CALL DORMBR( 'Q', 'L', 'T', M, NRHS, M, A, LDA,
+ $ DUM(1), B, LDB, DUM(1), -1, INFO )
+ LWORK_DORMBR=DUM(1)
+* Compute space needed for DORGBR
+ CALL DORGBR( 'P', M, N, M, A, LDA, DUM(1),
+ $ DUM(1), -1, INFO )
+ LWORK_DORGBR=DUM(1)
+ MAXWRK = 3*M + LWORK_DGEBRD
+ MAXWRK = MAX( MAXWRK, 3*M + LWORK_DORMBR )
+ MAXWRK = MAX( MAXWRK, 3*M + LWORK_DORGBR )
MAXWRK = MAX( MAXWRK, BDSPAC )
MAXWRK = MAX( MAXWRK, N*NRHS )
END IF
* compute right singular vectors in A
* (Workspace: need BDSPAC)
*
- CALL DBDSQR( 'U', N, N, 0, NRHS, S, WORK( IE ), A, LDA, VDUM,
+ CALL DBDSQR( 'U', N, N, 0, NRHS, S, WORK( IE ), A, LDA, DUM,
$ 1, B, LDB, WORK( IWORK ), INFO )
IF( INFO.NE.0 )
$ GO TO 70
* multiplying B by transpose of left singular vectors
* (Workspace: need BDSPAC)
*
- CALL DBDSQR( 'L', M, N, 0, NRHS, S, WORK( IE ), A, LDA, VDUM,
+ CALL DBDSQR( 'L', M, N, 0, NRHS, S, WORK( IE ), A, LDA, DUM,
$ 1, B, LDB, WORK( IWORK ), INFO )
IF( INFO.NE.0 )
$ GO TO 70
*> \ingroup doubleGEsing
*
* =====================================================================
- SUBROUTINE DGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,
- $ WORK, LWORK, INFO )
+ SUBROUTINE DGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU,
+ $ VT, LDVT, WORK, LWORK, INFO )
*
* -- LAPACK driver routine (version 3.3.1) --
* -- LAPACK is a software package provided by Univ. of Tennessee, --
$ ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,
$ MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,
$ NRVT, WRKBL
+ INTEGER LWORK_DGEQRF, LWORK_DORGQR_N, LWORK_DORGQR_M,
+ $ LWORK_DGEBRD, LWORK_DORGBR_P, LWORK_DORGBR_Q,
+ $ LWORK_DGELQF, LWORK_DORGLQ_N, LWORK_DORGLQ_M
DOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM
* ..
* .. Local Arrays ..
*
MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )
BDSPAC = 5*N
+* Compute space needed for DGEQRF
+ CALL DGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_DGEQRF=DUM(1)
+* Compute space needed for DORGQR
+ CALL DORGQR( M, N, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_DORGQR_N=DUM(1)
+ CALL DORGQR( M, M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_DORGQR_M=DUM(1)
+* Compute space needed for DGEBRD
+ CALL DGEBRD( N, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_DGEBRD=DUM(1)
+* Compute space needed for DORGBR P
+ CALL DORGBR( 'P', N, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_DORGBR_P=DUM(1)
+* Compute space needed for DORGBR Q
+ CALL DORGBR( 'Q', N, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_DORGBR_Q=DUM(1)
+*
IF( M.GE.MNTHR ) THEN
IF( WNTUN ) THEN
*
* Path 1 (M much larger than N, JOBU='N')
*
- MAXWRK = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1,
- $ -1 )
- MAXWRK = MAX( MAXWRK, 3*N+2*N*
- $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
+ MAXWRK = N + LWORK_DGEQRF
+ MAXWRK = MAX( MAXWRK, 3*N+LWORK_DGEBRD )
IF( WNTVO .OR. WNTVAS )
- $ MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+ $ MAXWRK = MAX( MAXWRK, 3*N+LWORK_DORGBR_P )
MAXWRK = MAX( MAXWRK, BDSPAC )
MINWRK = MAX( 4*N, BDSPAC )
ELSE IF( WNTUO .AND. WNTVN ) THEN
*
* Path 2 (M much larger than N, JOBU='O', JOBVT='N')
*
- WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
+ WRKBL = N + LWORK_DGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_DORGQR_N )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
MINWRK = MAX( 3*N+M, BDSPAC )
* Path 3 (M much larger than N, JOBU='O', JOBVT='S' or
* 'A')
*
- WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+( N-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_DGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_DORGQR_N )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
MINWRK = MAX( 3*N+M, BDSPAC )
*
* Path 4 (M much larger than N, JOBU='S', JOBVT='N')
*
- WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
+ WRKBL = N + LWORK_DGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_DORGQR_N )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = N*N + WRKBL
MINWRK = MAX( 3*N+M, BDSPAC )
*
* Path 5 (M much larger than N, JOBU='S', JOBVT='O')
*
- WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+( N-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_DGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_DORGQR_N )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = 2*N*N + WRKBL
MINWRK = MAX( 3*N+M, BDSPAC )
* Path 6 (M much larger than N, JOBU='S', JOBVT='S' or
* 'A')
*
- WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+( N-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_DGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_DORGQR_N )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = N*N + WRKBL
MINWRK = MAX( 3*N+M, BDSPAC )
*
* Path 7 (M much larger than N, JOBU='A', JOBVT='N')
*
- WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
- $ M, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
+ WRKBL = N + LWORK_DGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_DORGQR_M )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = N*N + WRKBL
MINWRK = MAX( 3*N+M, BDSPAC )
*
* Path 8 (M much larger than N, JOBU='A', JOBVT='O')
*
- WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
- $ M, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+( N-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_DGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_DORGQR_M )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = 2*N*N + WRKBL
MINWRK = MAX( 3*N+M, BDSPAC )
* Path 9 (M much larger than N, JOBU='A', JOBVT='S' or
* 'A')
*
- WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
- $ M, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+( N-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_DGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_DORGQR_M )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = N*N + WRKBL
MINWRK = MAX( 3*N+M, BDSPAC )
*
* Path 10 (M at least N, but not much larger)
*
- MAXWRK = 3*N + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N,
- $ -1, -1 )
- IF( WNTUS .OR. WNTUO )
- $ MAXWRK = MAX( MAXWRK, 3*N+N*
- $ ILAENV( 1, 'DORGBR', 'Q', M, N, N, -1 ) )
- IF( WNTUA )
- $ MAXWRK = MAX( MAXWRK, 3*N+M*
- $ ILAENV( 1, 'DORGBR', 'Q', M, M, N, -1 ) )
- IF( .NOT.WNTVN )
- $ MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
+ CALL DGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_DGEBRD=DUM(1)
+ MAXWRK = 3*N + LWORK_DGEBRD
+ IF( WNTUS .OR. WNTUO ) THEN
+ CALL DORGBR( 'Q', M, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_DORGBR_Q=DUM(1)
+ MAXWRK = MAX( MAXWRK, 3*N+LWORK_DORGBR_Q )
+ END IF
+ IF( WNTUA ) THEN
+ CALL DORGBR( 'Q', M, M, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_DORGBR_Q=DUM(1)
+ MAXWRK = MAX( MAXWRK, 3*N+LWORK_DORGBR_Q )
+ END IF
+ IF( .NOT.WNTVN ) THEN
+ MAXWRK = MAX( MAXWRK, 3*N+LWORK_DORGBR_P )
+ END IF
MAXWRK = MAX( MAXWRK, BDSPAC )
MINWRK = MAX( 3*N+M, BDSPAC )
END IF
*
MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )
BDSPAC = 5*M
+* Compute space needed for DGELQF
+ CALL DGELQF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_DGELQF=DUM(1)
+* Compute space needed for DORGLQ
+ CALL DORGLQ( N, N, M, VT, LDVT, DUM(1), DUM(1), -1, IERR )
+ LWORK_DORGLQ_N=DUM(1)
+ CALL DORGLQ( M, N, M, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_DORGLQ_M=DUM(1)
+* Compute space needed for DGEBRD
+ CALL DGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_DGEBRD=DUM(1)
+* Compute space needed for DORGBR P
+ CALL DORGBR( 'P', M, M, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_DORGBR_P=DUM(1)
+* Compute space needed for DORGBR Q
+ CALL DORGBR( 'Q', M, M, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_DORGBR_Q=DUM(1)
IF( N.GE.MNTHR ) THEN
IF( WNTVN ) THEN
*
* Path 1t(N much larger than M, JOBVT='N')
*
- MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1,
- $ -1 )
- MAXWRK = MAX( MAXWRK, 3*M+2*M*
- $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
+ MAXWRK = M + LWORK_DGELQF
+ MAXWRK = MAX( MAXWRK, 3*M+LWORK_DGEBRD )
IF( WNTUO .OR. WNTUAS )
- $ MAXWRK = MAX( MAXWRK, 3*M+M*
- $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+ $ MAXWRK = MAX( MAXWRK, 3*M+LWORK_DORGBR_Q )
MAXWRK = MAX( MAXWRK, BDSPAC )
MINWRK = MAX( 4*M, BDSPAC )
ELSE IF( WNTVO .AND. WNTUN ) THEN
*
* Path 2t(N much larger than M, JOBU='N', JOBVT='O')
*
- WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
+ WRKBL = M + LWORK_DGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_M )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
MINWRK = MAX( 3*M+N, BDSPAC )
* Path 3t(N much larger than M, JOBU='S' or 'A',
* JOBVT='O')
*
- WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+M*
- $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_DGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_M )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
MINWRK = MAX( 3*M+N, BDSPAC )
*
* Path 4t(N much larger than M, JOBU='N', JOBVT='S')
*
- WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
+ WRKBL = M + LWORK_DGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_M )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = M*M + WRKBL
MINWRK = MAX( 3*M+N, BDSPAC )
*
* Path 5t(N much larger than M, JOBU='O', JOBVT='S')
*
- WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+M*
- $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_DGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_M )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = 2*M*M + WRKBL
MINWRK = MAX( 3*M+N, BDSPAC )
* Path 6t(N much larger than M, JOBU='S' or 'A',
* JOBVT='S')
*
- WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+M*
- $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_DGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_M )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = M*M + WRKBL
MINWRK = MAX( 3*M+N, BDSPAC )
*
* Path 7t(N much larger than M, JOBU='N', JOBVT='A')
*
- WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
+ WRKBL = M + LWORK_DGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_N )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = M*M + WRKBL
MINWRK = MAX( 3*M+N, BDSPAC )
*
* Path 8t(N much larger than M, JOBU='O', JOBVT='A')
*
- WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+M*
- $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_DGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_N )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = 2*M*M + WRKBL
MINWRK = MAX( 3*M+N, BDSPAC )
* Path 9t(N much larger than M, JOBU='S' or 'A',
* JOBVT='A')
*
- WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+M*
- $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_DGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_N )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = M*M + WRKBL
MINWRK = MAX( 3*M+N, BDSPAC )
*
* Path 10t(N greater than M, but not much larger)
*
- MAXWRK = 3*M + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N,
- $ -1, -1 )
- IF( WNTVS .OR. WNTVO )
- $ MAXWRK = MAX( MAXWRK, 3*M+M*
- $ ILAENV( 1, 'DORGBR', 'P', M, N, M, -1 ) )
- IF( WNTVA )
- $ MAXWRK = MAX( MAXWRK, 3*M+N*
- $ ILAENV( 1, 'DORGBR', 'P', N, N, M, -1 ) )
- IF( .NOT.WNTUN )
- $ MAXWRK = MAX( MAXWRK, 3*M+( M-1 )*
- $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
+ CALL DGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_DGEBRD=DUM(1)
+ MAXWRK = 3*M + LWORK_DGEBRD
+ IF( WNTVS .OR. WNTVO ) THEN
+* Compute space needed for DORGBR P
+ CALL DORGBR( 'P', M, N, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_DORGBR_P=DUM(1)
+ MAXWRK = MAX( MAXWRK, 3*M+LWORK_DORGBR_P )
+ END IF
+ IF( WNTVA ) THEN
+ CALL DORGBR( 'P', N, N, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_DORGBR_P=DUM(1)
+ MAXWRK = MAX( MAXWRK, 3*M+LWORK_DORGBR_P )
+ END IF
+ IF( .NOT.WNTUN ) THEN
+ MAXWRK = MAX( MAXWRK, 3*M+LWORK_DORGBR_Q )
+ END IF
MAXWRK = MAX( MAXWRK, BDSPAC )
MINWRK = MAX( 3*M+N, BDSPAC )
END IF
*
IF( INFO.EQ.0 ) THEN
IF( WANTQ ) THEN
- NB = ILAENV( 1, 'DORGQR', ' ', M, N, K, -1 )
+ IF( M.GE.K ) THEN
+ CALL DORGQR( M, N, K, A, LDA, TAU, WORK, -1, IINFO )
+ ELSE
+ CALL DORGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK,
+ $ -1, IINFO )
+ END IF
ELSE
- NB = ILAENV( 1, 'DORGLQ', ' ', M, N, K, -1 )
+ IF( K.LT.N ) THEN
+ CALL DORGLQ( M, N, K, A, LDA, TAU, WORK, -1, IINFO )
+ ELSE
+ CALL DORGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,
+ $ -1, IINFO )
+ END IF
END IF
- LWKOPT = MAX( 1, MN )*NB
- WORK( 1 ) = LWKOPT
+ LWKOPT = WORK( 1 )
END IF
*
IF( INFO.NE.0 ) THEN
INTEGER BDSPAC, BL, CHUNK, I, IASCL, IBSCL, IE, IL,
$ ITAU, ITAUP, ITAUQ, IWORK, LDWORK, MAXMN,
$ MAXWRK, MINMN, MINWRK, MM, MNTHR
+ INTEGER LWORK_SGEQRF, LWORK_SORMQR, LWORK_SGEBRD,
+ $ LWORK_SORMBR, LWORK_SORGBR, LWORK_SORMLQ
REAL ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
* ..
* .. Local Arrays ..
- REAL VDUM( 1 )
+ REAL DUM( 1 )
* ..
* .. External Subroutines ..
EXTERNAL SBDSQR, SCOPY, SGEBRD, SGELQF, SGEMM, SGEMV,
* Path 1a - overdetermined, with many more rows than
* columns
*
+* Compute space needed for SGEQRF
+ CALL SGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, INFO )
+ LWORK_SGEQRF=DUM(1)
+* Compute space needed for SORMQR
+ CALL SORMQR( 'L', 'T', M, NRHS, N, A, LDA, DUM(1), B,
+ $ LDB, DUM(1), -1, INFO )
+ LWORK_SORMQR=DUM(1)
MM = N
- MAXWRK = MAX( MAXWRK, N + N*ILAENV( 1, 'SGEQRF', ' ', M,
- $ N, -1, -1 ) )
- MAXWRK = MAX( MAXWRK, N + NRHS*ILAENV( 1, 'SORMQR', 'LT',
- $ M, NRHS, N, -1 ) )
+ MAXWRK = MAX( MAXWRK, N + LWORK_SGEQRF )
+ MAXWRK = MAX( MAXWRK, N + LWORK_SORMQR )
END IF
IF( M.GE.N ) THEN
*
* Compute workspace needed for SBDSQR
*
BDSPAC = MAX( 1, 5*N )
- MAXWRK = MAX( MAXWRK, 3*N + ( MM + N )*ILAENV( 1,
- $ 'SGEBRD', ' ', MM, N, -1, -1 ) )
- MAXWRK = MAX( MAXWRK, 3*N + NRHS*ILAENV( 1, 'SORMBR',
- $ 'QLT', MM, NRHS, N, -1 ) )
- MAXWRK = MAX( MAXWRK, 3*N + ( N - 1 )*ILAENV( 1,
- $ 'SORGBR', 'P', N, N, N, -1 ) )
+* Compute space needed for SGEBRD
+ CALL SGEBRD( MM, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, INFO )
+ LWORK_SGEBRD=DUM(1)
+* Compute space needed for SORMBR
+ CALL SORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, DUM(1),
+ $ B, LDB, DUM(1), -1, INFO )
+ LWORK_SORMBR=DUM(1)
+* Compute space needed for SORGBR
+ CALL SORGBR( 'P', N, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, INFO )
+ LWORK_SORGBR=DUM(1)
+* Compute total workspace needed
+ MAXWRK = MAX( MAXWRK, 3*N + LWORK_SGEBRD )
+ MAXWRK = MAX( MAXWRK, 3*N + LWORK_SORMBR )
+ MAXWRK = MAX( MAXWRK, 3*N + LWORK_SORGBR )
MAXWRK = MAX( MAXWRK, BDSPAC )
MAXWRK = MAX( MAXWRK, N*NRHS )
MINWRK = MAX( 3*N + MM, 3*N + NRHS, BDSPAC )
* Path 2a - underdetermined, with many more columns
* than rows
*
+* Compute space needed for SGEBRD
+ CALL SGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, INFO )
+ LWORK_SGEBRD=DUM(1)
+* Compute space needed for SORMBR
+ CALL SORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA,
+ $ DUM(1), B, LDB, DUM(1), -1, INFO )
+ LWORK_SORMBR=DUM(1)
+* Compute space needed for SORGBR
+ CALL SORGBR( 'P', M, M, M, A, LDA, DUM(1),
+ $ DUM(1), -1, INFO )
+ LWORK_SORGBR=DUM(1)
+* Compute space needed for SORMLQ
+ CALL SORMLQ( 'L', 'T', N, NRHS, M, A, LDA, DUM(1),
+ $ B, LDB, DUM(1), -1, INFO )
+ LWORK_SORMLQ=DUM(1)
+* Compute total workspace needed
MAXWRK = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1,
$ -1 )
- MAXWRK = MAX( MAXWRK, M*M + 4*M + 2*M*ILAENV( 1,
- $ 'SGEBRD', ' ', M, M, -1, -1 ) )
- MAXWRK = MAX( MAXWRK, M*M + 4*M + NRHS*ILAENV( 1,
- $ 'SORMBR', 'QLT', M, NRHS, M, -1 ) )
- MAXWRK = MAX( MAXWRK, M*M + 4*M +
- $ ( M - 1 )*ILAENV( 1, 'SORGBR', 'P', M,
- $ M, M, -1 ) )
+ MAXWRK = MAX( MAXWRK, M*M + 4*M + LWORK_SGEBRD )
+ MAXWRK = MAX( MAXWRK, M*M + 4*M + LWORK_SORMBR )
+ MAXWRK = MAX( MAXWRK, M*M + 4*M + LWORK_SORGBR )
MAXWRK = MAX( MAXWRK, M*M + M + BDSPAC )
IF( NRHS.GT.1 ) THEN
MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
ELSE
MAXWRK = MAX( MAXWRK, M*M + 2*M )
END IF
- MAXWRK = MAX( MAXWRK, M + NRHS*ILAENV( 1, 'SORMLQ',
- $ 'LT', N, NRHS, M, -1 ) )
+ MAXWRK = MAX( MAXWRK, M + LWORK_SORMLQ )
ELSE
*
* Path 2 - underdetermined
*
- MAXWRK = 3*M + ( N + M )*ILAENV( 1, 'SGEBRD', ' ', M,
- $ N, -1, -1 )
- MAXWRK = MAX( MAXWRK, 3*M + NRHS*ILAENV( 1, 'SORMBR',
- $ 'QLT', M, NRHS, M, -1 ) )
- MAXWRK = MAX( MAXWRK, 3*M + M*ILAENV( 1, 'SORGBR',
- $ 'P', M, N, M, -1 ) )
+* Compute space needed for SGEBRD
+ CALL SGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, INFO )
+ LWORK_SGEBRD=DUM(1)
+* Compute space needed for SORMBR
+ CALL SORMBR( 'Q', 'L', 'T', M, NRHS, M, A, LDA,
+ $ DUM(1), B, LDB, DUM(1), -1, INFO )
+ LWORK_SORMBR=DUM(1)
+* Compute space needed for SORGBR
+ CALL SORGBR( 'P', M, N, M, A, LDA, DUM(1),
+ $ DUM(1), -1, INFO )
+ LWORK_SORGBR=DUM(1)
+ MAXWRK = 3*M + LWORK_SGEBRD
+ MAXWRK = MAX( MAXWRK, 3*M + LWORK_SORMBR )
+ MAXWRK = MAX( MAXWRK, 3*M + LWORK_SORGBR )
MAXWRK = MAX( MAXWRK, BDSPAC )
MAXWRK = MAX( MAXWRK, N*NRHS )
END IF
* compute right singular vectors in A
* (Workspace: need BDSPAC)
*
- CALL SBDSQR( 'U', N, N, 0, NRHS, S, WORK( IE ), A, LDA, VDUM,
+ CALL SBDSQR( 'U', N, N, 0, NRHS, S, WORK( IE ), A, LDA, DUM,
$ 1, B, LDB, WORK( IWORK ), INFO )
IF( INFO.NE.0 )
$ GO TO 70
* multiplying B by transpose of left singular vectors
* (Workspace: need BDSPAC)
*
- CALL SBDSQR( 'L', M, N, 0, NRHS, S, WORK( IE ), A, LDA, VDUM,
+ CALL SBDSQR( 'L', M, N, 0, NRHS, S, WORK( IE ), A, LDA, DUM,
$ 1, B, LDB, WORK( IWORK ), INFO )
IF( INFO.NE.0 )
$ GO TO 70
$ ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,
$ MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,
$ NRVT, WRKBL
+ INTEGER LWORK_SGEQRF, LWORK_SORGQR_N, LWORK_SORGQR_M,
+ $ LWORK_SGEBRD, LWORK_SORGBR_P, LWORK_SORGBR_Q,
+ $ LWORK_SGELQF, LWORK_SORGLQ_N, LWORK_SORGLQ_M
REAL ANRM, BIGNUM, EPS, SMLNUM
* ..
* .. Local Arrays ..
*
MNTHR = ILAENV( 6, 'SGESVD', JOBU // JOBVT, M, N, 0, 0 )
BDSPAC = 5*N
+* Compute space needed for SGEQRF
+ CALL SGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_SGEQRF=DUM(1)
+* Compute space needed for SORGQR
+ CALL SORGQR( M, N, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_SORGQR_N=DUM(1)
+ CALL SORGQR( M, M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_SORGQR_M=DUM(1)
+* Compute space needed for SGEBRD
+ CALL SGEBRD( N, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_SGEBRD=DUM(1)
+* Compute space needed for SORGBR P
+ CALL SORGBR( 'P', N, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_SORGBR_P=DUM(1)
+* Compute space needed for SORGBR Q
+ CALL SORGBR( 'Q', N, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_SORGBR_Q=DUM(1)
+*
IF( M.GE.MNTHR ) THEN
IF( WNTUN ) THEN
*
* Path 1 (M much larger than N, JOBU='N')
*
- MAXWRK = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1,
- $ -1 )
- MAXWRK = MAX( MAXWRK, 3*N+2*N*
- $ ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
+ MAXWRK = N + LWORK_SGEQRF
+ MAXWRK = MAX( MAXWRK, 3*N+LWORK_SGEBRD )
IF( WNTVO .OR. WNTVAS )
- $ MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+ $ MAXWRK = MAX( MAXWRK, 3*N+LWORK_SORGBR_P )
MAXWRK = MAX( MAXWRK, BDSPAC )
MINWRK = MAX( 4*N, BDSPAC )
ELSE IF( WNTUO .AND. WNTVN ) THEN
*
* Path 2 (M much larger than N, JOBU='O', JOBVT='N')
*
- WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'SORGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
+ WRKBL = N + LWORK_SGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_SORGQR_N )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
MINWRK = MAX( 3*N+M, BDSPAC )
* Path 3 (M much larger than N, JOBU='O', JOBVT='S' or
* 'A')
*
- WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'SORGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+( N-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_SGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_SORGQR_N )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_Q )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
MINWRK = MAX( 3*N+M, BDSPAC )
*
* Path 4 (M much larger than N, JOBU='S', JOBVT='N')
*
- WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'SORGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
+ WRKBL = N + LWORK_SGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_SORGQR_N )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = N*N + WRKBL
MINWRK = MAX( 3*N+M, BDSPAC )
*
* Path 5 (M much larger than N, JOBU='S', JOBVT='O')
*
- WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'SORGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+( N-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_SGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_SORGQR_N )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_Q )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = 2*N*N + WRKBL
MINWRK = MAX( 3*N+M, BDSPAC )
* Path 6 (M much larger than N, JOBU='S', JOBVT='S' or
* 'A')
*
- WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'SORGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+( N-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_SGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_SORGQR_N )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_Q )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = N*N + WRKBL
MINWRK = MAX( 3*N+M, BDSPAC )
*
* Path 7 (M much larger than N, JOBU='A', JOBVT='N')
*
- WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'SORGQR', ' ', M,
- $ M, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
+ WRKBL = N + LWORK_SGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_SORGQR_M )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = N*N + WRKBL
MINWRK = MAX( 3*N+M, BDSPAC )
*
* Path 8 (M much larger than N, JOBU='A', JOBVT='O')
*
- WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'SORGQR', ' ', M,
- $ M, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+( N-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_SGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_SORGQR_M )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_Q )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = 2*N*N + WRKBL
MINWRK = MAX( 3*N+M, BDSPAC )
* Path 9 (M much larger than N, JOBU='A', JOBVT='S' or
* 'A')
*
- WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'SORGQR', ' ', M,
- $ M, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+2*N*
- $ ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+N*
- $ ILAENV( 1, 'SORGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 3*N+( N-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_SGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_SORGQR_M )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_Q )
+ WRKBL = MAX( WRKBL, 3*N+LWORK_SORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = N*N + WRKBL
MINWRK = MAX( 3*N+M, BDSPAC )
*
* Path 10 (M at least N, but not much larger)
*
- MAXWRK = 3*N + ( M+N )*ILAENV( 1, 'SGEBRD', ' ', M, N,
- $ -1, -1 )
- IF( WNTUS .OR. WNTUO )
- $ MAXWRK = MAX( MAXWRK, 3*N+N*
- $ ILAENV( 1, 'SORGBR', 'Q', M, N, N, -1 ) )
- IF( WNTUA )
- $ MAXWRK = MAX( MAXWRK, 3*N+M*
- $ ILAENV( 1, 'SORGBR', 'Q', M, M, N, -1 ) )
- IF( .NOT.WNTVN )
- $ MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', N, N, N, -1 ) )
+ CALL SGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_SGEBRD=DUM(1)
+ MAXWRK = 3*N + LWORK_SGEBRD
+ IF( WNTUS .OR. WNTUO ) THEN
+ CALL SORGBR( 'Q', M, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_SORGBR_Q=DUM(1)
+ MAXWRK = MAX( MAXWRK, 3*N+LWORK_SORGBR_Q )
+ END IF
+ IF( WNTUA ) THEN
+ CALL SORGBR( 'Q', M, M, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_SORGBR_Q=DUM(1)
+ MAXWRK = MAX( MAXWRK, 3*N+LWORK_SORGBR_Q )
+ END IF
+ IF( .NOT.WNTVN ) THEN
+ MAXWRK = MAX( MAXWRK, 3*N+LWORK_SORGBR_P )
+ END IF
MAXWRK = MAX( MAXWRK, BDSPAC )
MINWRK = MAX( 3*N+M, BDSPAC )
END IF
*
MNTHR = ILAENV( 6, 'SGESVD', JOBU // JOBVT, M, N, 0, 0 )
BDSPAC = 5*M
+* Compute space needed for SGELQF
+ CALL SGELQF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_SGELQF=DUM(1)
+* Compute space needed for SORGLQ
+ CALL SORGLQ( N, N, M, VT, LDVT, DUM(1), DUM(1), -1, IERR )
+ LWORK_SORGLQ_N=DUM(1)
+ CALL SORGLQ( M, N, M, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_SORGLQ_M=DUM(1)
+* Compute space needed for SGEBRD
+ CALL SGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_SGEBRD=DUM(1)
+* Compute space needed for SORGBR P
+ CALL SORGBR( 'P', M, M, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_SORGBR_P=DUM(1)
+* Compute space needed for SORGBR Q
+ CALL SORGBR( 'Q', M, M, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_SORGBR_Q=DUM(1)
IF( N.GE.MNTHR ) THEN
IF( WNTVN ) THEN
*
* Path 1t(N much larger than M, JOBVT='N')
*
- MAXWRK = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1,
- $ -1 )
- MAXWRK = MAX( MAXWRK, 3*M+2*M*
- $ ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
+ MAXWRK = M + LWORK_SGELQF
+ MAXWRK = MAX( MAXWRK, 3*M+LWORK_SGEBRD )
IF( WNTUO .OR. WNTUAS )
- $ MAXWRK = MAX( MAXWRK, 3*M+M*
- $ ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+ $ MAXWRK = MAX( MAXWRK, 3*M+LWORK_SORGBR_Q )
MAXWRK = MAX( MAXWRK, BDSPAC )
MINWRK = MAX( 4*M, BDSPAC )
ELSE IF( WNTVO .AND. WNTUN ) THEN
*
* Path 2t(N much larger than M, JOBU='N', JOBVT='O')
*
- WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'SORGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
+ WRKBL = M + LWORK_SGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_SORGLQ_M )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
MINWRK = MAX( 3*M+N, BDSPAC )
* Path 3t(N much larger than M, JOBU='S' or 'A',
* JOBVT='O')
*
- WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'SORGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+M*
- $ ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_SGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_SORGLQ_M )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_P )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
MINWRK = MAX( 3*M+N, BDSPAC )
*
* Path 4t(N much larger than M, JOBU='N', JOBVT='S')
*
- WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'SORGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
+ WRKBL = M + LWORK_SGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_SORGLQ_M )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = M*M + WRKBL
MINWRK = MAX( 3*M+N, BDSPAC )
*
* Path 5t(N much larger than M, JOBU='O', JOBVT='S')
*
- WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'SORGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+M*
- $ ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_SGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_SORGLQ_M )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_P )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = 2*M*M + WRKBL
MINWRK = MAX( 3*M+N, BDSPAC )
* Path 6t(N much larger than M, JOBU='S' or 'A',
* JOBVT='S')
*
- WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'SORGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+M*
- $ ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_SGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_SORGLQ_M )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_P )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = M*M + WRKBL
MINWRK = MAX( 3*M+N, BDSPAC )
*
* Path 7t(N much larger than M, JOBU='N', JOBVT='A')
*
- WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'SORGLQ', ' ', N,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
+ WRKBL = M + LWORK_SGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_SORGLQ_N )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_P )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = M*M + WRKBL
MINWRK = MAX( 3*M+N, BDSPAC )
*
* Path 8t(N much larger than M, JOBU='O', JOBVT='A')
*
- WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'SORGLQ', ' ', N,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+M*
- $ ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_SGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_SORGLQ_N )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_P )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = 2*M*M + WRKBL
MINWRK = MAX( 3*M+N, BDSPAC )
* Path 9t(N much larger than M, JOBU='S' or 'A',
* JOBVT='A')
*
- WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'SORGLQ', ' ', N,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+2*M*
- $ ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+( M-1 )*
- $ ILAENV( 1, 'SORGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 3*M+M*
- $ ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_SGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_SORGLQ_N )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SGEBRD )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_P )
+ WRKBL = MAX( WRKBL, 3*M+LWORK_SORGBR_Q )
WRKBL = MAX( WRKBL, BDSPAC )
MAXWRK = M*M + WRKBL
MINWRK = MAX( 3*M+N, BDSPAC )
*
* Path 10t(N greater than M, but not much larger)
*
- MAXWRK = 3*M + ( M+N )*ILAENV( 1, 'SGEBRD', ' ', M, N,
- $ -1, -1 )
- IF( WNTVS .OR. WNTVO )
- $ MAXWRK = MAX( MAXWRK, 3*M+M*
- $ ILAENV( 1, 'SORGBR', 'P', M, N, M, -1 ) )
- IF( WNTVA )
- $ MAXWRK = MAX( MAXWRK, 3*M+N*
- $ ILAENV( 1, 'SORGBR', 'P', N, N, M, -1 ) )
- IF( .NOT.WNTUN )
- $ MAXWRK = MAX( MAXWRK, 3*M+( M-1 )*
- $ ILAENV( 1, 'SORGBR', 'Q', M, M, M, -1 ) )
+ CALL SGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_SGEBRD=DUM(1)
+ MAXWRK = 3*M + LWORK_SGEBRD
+ IF( WNTVS .OR. WNTVO ) THEN
+* Compute space needed for SORGBR P
+ CALL SORGBR( 'P', M, N, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_SORGBR_P=DUM(1)
+ MAXWRK = MAX( MAXWRK, 3*M+LWORK_SORGBR_P )
+ END IF
+ IF( WNTVA ) THEN
+ CALL SORGBR( 'P', N, N, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_SORGBR_P=DUM(1)
+ MAXWRK = MAX( MAXWRK, 3*M+LWORK_SORGBR_P )
+ END IF
+ IF( .NOT.WNTUN ) THEN
+ MAXWRK = MAX( MAXWRK, 3*M+LWORK_SORGBR_Q )
+ END IF
MAXWRK = MAX( MAXWRK, BDSPAC )
MINWRK = MAX( 3*M+N, BDSPAC )
END IF
*
IF( INFO.EQ.0 ) THEN
IF( WANTQ ) THEN
- NB = ILAENV( 1, 'SORGQR', ' ', M, N, K, -1 )
+ IF( M.GE.K ) THEN
+ CALL SORGQR( M, N, K, A, LDA, TAU, WORK, -1, IINFO )
+ ELSE
+ CALL SORGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK,
+ $ -1, IINFO )
+ END IF
ELSE
- NB = ILAENV( 1, 'SORGLQ', ' ', M, N, K, -1 )
+ IF( K.LT.N ) THEN
+ CALL SORGLQ( M, N, K, A, LDA, TAU, WORK, -1, IINFO )
+ ELSE
+ CALL SORGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,
+ $ -1, IINFO )
+ END IF
END IF
- LWKOPT = MAX( 1, MN )*NB
- WORK( 1 ) = LWKOPT
+ LWKOPT = WORK( 1 )
END IF
*
IF( INFO.NE.0 ) THEN
INTEGER BL, CHUNK, I, IASCL, IBSCL, IE, IL, IRWORK,
$ ITAU, ITAUP, ITAUQ, IWORK, LDWORK, MAXMN,
$ MAXWRK, MINMN, MINWRK, MM, MNTHR
+ INTEGER LWORK_ZGEQRF, LWORK_ZUNMQR, LWORK_ZGEBRD,
+ $ LWORK_ZUNMBR, LWORK_ZUNGBR, LWORK_ZUNMLQ,
+ $ LWORK_ZGELQF
DOUBLE PRECISION ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
* ..
* .. Local Arrays ..
- COMPLEX*16 VDUM( 1 )
+ COMPLEX*16 DUM( 1 )
* ..
* .. External Subroutines ..
EXTERNAL DLABAD, DLASCL, DLASET, XERBLA, ZBDSQR, ZCOPY,
* Path 1a - overdetermined, with many more rows than
* columns
*
+* Compute space needed for ZGEQRF
+ CALL ZGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, INFO )
+ LWORK_ZGEQRF=DUM(1)
+* Compute space needed for ZUNMQR
+ CALL ZUNMQR( 'L', 'C', M, NRHS, N, A, LDA, DUM(1), B,
+ $ LDB, DUM(1), -1, INFO )
+ LWORK_ZUNMQR=DUM(1)
MM = N
MAXWRK = MAX( MAXWRK, N + N*ILAENV( 1, 'ZGEQRF', ' ', M,
$ N, -1, -1 ) )
*
* Path 1 - overdetermined or exactly determined
*
- MAXWRK = MAX( MAXWRK, 2*N + ( MM + N )*ILAENV( 1,
- $ 'ZGEBRD', ' ', MM, N, -1, -1 ) )
- MAXWRK = MAX( MAXWRK, 2*N + NRHS*ILAENV( 1, 'ZUNMBR',
- $ 'QLC', MM, NRHS, N, -1 ) )
- MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
- $ 'ZUNGBR', 'P', N, N, N, -1 ) )
+* Compute space needed for ZGEBRD
+ CALL ZGEBRD( MM, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, INFO )
+ LWORK_ZGEBRD=DUM(1)
+* Compute space needed for ZUNMBR
+ CALL ZUNMBR( 'Q', 'L', 'C', MM, NRHS, N, A, LDA, DUM(1),
+ $ B, LDB, DUM(1), -1, INFO )
+ LWORK_ZUNMBR=DUM(1)
+* Compute space needed for ZUNGBR
+ CALL ZUNGBR( 'P', N, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, INFO )
+ LWORK_ZUNGBR=DUM(1)
+* Compute total workspace needed
+ MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZGEBRD )
+ MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR )
+ MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR )
MAXWRK = MAX( MAXWRK, N*NRHS )
MINWRK = 2*N + MAX( NRHS, M )
END IF
* Path 2a - underdetermined, with many more columns
* than rows
*
- MAXWRK = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1,
- $ -1 )
- MAXWRK = MAX( MAXWRK, 3*M + M*M + 2*M*ILAENV( 1,
- $ 'ZGEBRD', ' ', M, M, -1, -1 ) )
- MAXWRK = MAX( MAXWRK, 3*M + M*M + NRHS*ILAENV( 1,
- $ 'ZUNMBR', 'QLC', M, NRHS, M, -1 ) )
- MAXWRK = MAX( MAXWRK, 3*M + M*M + ( M - 1 )*ILAENV( 1,
- $ 'ZUNGBR', 'P', M, M, M, -1 ) )
+* Compute space needed for ZGELQF
+ CALL ZGELQF( M, N, A, LDA, DUM(1), DUM(1),
+ $ -1, INFO )
+ LWORK_ZGELQF=DUM(1)
+* Compute space needed for ZGEBRD
+ CALL ZGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, INFO )
+ LWORK_ZGEBRD=DUM(1)
+* Compute space needed for ZUNMBR
+ CALL ZUNMBR( 'Q', 'L', 'C', M, NRHS, N, A, LDA,
+ $ DUM(1), B, LDB, DUM(1), -1, INFO )
+ LWORK_ZUNMBR=DUM(1)
+* Compute space needed for ZUNGBR
+ CALL ZUNGBR( 'P', M, M, M, A, LDA, DUM(1),
+ $ DUM(1), -1, INFO )
+ LWORK_ZUNGBR=DUM(1)
+* Compute space needed for ZUNMLQ
+ CALL ZUNMLQ( 'L', 'C', N, NRHS, M, A, LDA, DUM(1),
+ $ B, LDB, DUM(1), -1, INFO )
+ LWORK_ZUNMLQ=DUM(1)
+* Compute total workspace needed
+ MAXWRK = M + LWORK_ZGELQF
+ MAXWRK = MAX( MAXWRK, 3*M + M*M + LWORK_ZGEBRD )
+ MAXWRK = MAX( MAXWRK, 3*M + M*M + LWORK_ZUNMBR )
+ MAXWRK = MAX( MAXWRK, 3*M + M*M + LWORK_ZUNGBR )
IF( NRHS.GT.1 ) THEN
MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
ELSE
MAXWRK = MAX( MAXWRK, M*M + 2*M )
END IF
- MAXWRK = MAX( MAXWRK, M + NRHS*ILAENV( 1, 'ZUNMLQ',
- $ 'LC', N, NRHS, M, -1 ) )
+ MAXWRK = MAX( MAXWRK, M + LWORK_ZUNMLQ )
ELSE
*
* Path 2 - underdetermined
*
- MAXWRK = 2*M + ( N + M )*ILAENV( 1, 'ZGEBRD', ' ', M,
- $ N, -1, -1 )
- MAXWRK = MAX( MAXWRK, 2*M + NRHS*ILAENV( 1, 'ZUNMBR',
- $ 'QLC', M, NRHS, M, -1 ) )
- MAXWRK = MAX( MAXWRK, 2*M + M*ILAENV( 1, 'ZUNGBR',
- $ 'P', M, N, M, -1 ) )
+* Compute space needed for ZGEBRD
+ CALL ZGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, INFO )
+ LWORK_ZGEBRD=DUM(1)
+* Compute space needed for ZUNMBR
+ CALL ZUNMBR( 'Q', 'L', 'C', M, NRHS, M, A, LDA,
+ $ DUM(1), B, LDB, DUM(1), -1, INFO )
+ LWORK_ZUNMBR=DUM(1)
+* Compute space needed for ZUNGBR
+ CALL ZUNGBR( 'P', M, N, M, A, LDA, DUM(1),
+ $ DUM(1), -1, INFO )
+ LWORK_ZUNGBR=DUM(1)
+ MAXWRK = 2*M + LWORK_ZGEBRD
+ MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR )
+ MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR )
MAXWRK = MAX( MAXWRK, N*NRHS )
END IF
END IF
* (CWorkspace: none)
* (RWorkspace: need BDSPAC)
*
- CALL ZBDSQR( 'U', N, N, 0, NRHS, S, RWORK( IE ), A, LDA, VDUM,
+ CALL ZBDSQR( 'U', N, N, 0, NRHS, S, RWORK( IE ), A, LDA, DUM,
$ 1, B, LDB, RWORK( IRWORK ), INFO )
IF( INFO.NE.0 )
$ GO TO 70
* (CWorkspace: none)
* (RWorkspace: need BDSPAC)
*
- CALL ZBDSQR( 'L', M, N, 0, NRHS, S, RWORK( IE ), A, LDA, VDUM,
+ CALL ZBDSQR( 'L', M, N, 0, NRHS, S, RWORK( IE ), A, LDA, DUM,
$ 1, B, LDB, RWORK( IRWORK ), INFO )
IF( INFO.NE.0 )
$ GO TO 70
*> \ingroup complex16GEsing
*
* =====================================================================
- SUBROUTINE ZGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,
- $ WORK, LWORK, RWORK, INFO )
+ SUBROUTINE ZGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU,
+ $ VT, LDVT, WORK, LWORK, RWORK, INFO )
*
* -- LAPACK driver routine (version 3.2) --
* -- LAPACK is a software package provided by Univ. of Tennessee, --
$ ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,
$ MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,
$ NRVT, WRKBL
+ INTEGER LWORK_ZGEQRF, LWORK_ZUNGQR_N, LWORK_ZUNGQR_M,
+ $ LWORK_ZGEBRD, LWORK_ZUNGBR_P, LWORK_ZUNGBR_Q,
+ $ LWORK_ZGELQF, LWORK_ZUNGLQ_N, LWORK_ZUNGLQ_M
DOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM
* ..
* .. Local Arrays ..
* Space needed for ZBDSQR is BDSPAC = 5*N
*
MNTHR = ILAENV( 6, 'ZGESVD', JOBU // JOBVT, M, N, 0, 0 )
+* Compute space needed for ZGEQRF
+ CALL ZGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_ZGEQRF=DUM(1)
+* Compute space needed for ZUNGQR
+ CALL ZUNGQR( M, N, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_ZUNGQR_N=DUM(1)
+ CALL ZUNGQR( M, M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_ZUNGQR_M=DUM(1)
+* Compute space needed for ZGEBRD
+ CALL ZGEBRD( N, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_ZGEBRD=DUM(1)
+* Compute space needed for ZUNGBR
+ CALL ZUNGBR( 'P', N, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_ZUNGBR_P=DUM(1)
+ CALL ZUNGBR( 'Q', N, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_ZUNGBR_Q=DUM(1)
+*
IF( M.GE.MNTHR ) THEN
IF( WNTUN ) THEN
*
* Path 1 (M much larger than N, JOBU='N')
*
- MAXWRK = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1,
- $ -1 )
- MAXWRK = MAX( MAXWRK, 2*N+2*N*
- $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
+ MAXWRK = N + LWORK_ZGEQRF
+ MAXWRK = MAX( MAXWRK, 2*N+LWORK_ZGEBRD )
IF( WNTVO .OR. WNTVAS )
- $ MAXWRK = MAX( MAXWRK, 2*N+( N-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+ $ MAXWRK = MAX( MAXWRK, 2*N+LWORK_ZUNGBR_P )
MINWRK = 3*N
ELSE IF( WNTUO .AND. WNTVN ) THEN
*
* Path 2 (M much larger than N, JOBU='O', JOBVT='N')
*
- WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
+ WRKBL = N + LWORK_ZGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_ZUNGQR_N )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_Q )
MAXWRK = MAX( N*N+WRKBL, N*N+M*N )
MINWRK = 2*N + M
ELSE IF( WNTUO .AND. WNTVAS ) THEN
* Path 3 (M much larger than N, JOBU='O', JOBVT='S' or
* 'A')
*
- WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+( N-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_ZGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_ZUNGQR_N )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_Q )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_P )
MAXWRK = MAX( N*N+WRKBL, N*N+M*N )
MINWRK = 2*N + M
ELSE IF( WNTUS .AND. WNTVN ) THEN
*
* Path 4 (M much larger than N, JOBU='S', JOBVT='N')
*
- WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
+ WRKBL = N + LWORK_ZGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_ZUNGQR_N )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_Q )
MAXWRK = N*N + WRKBL
MINWRK = 2*N + M
ELSE IF( WNTUS .AND. WNTVO ) THEN
*
* Path 5 (M much larger than N, JOBU='S', JOBVT='O')
*
- WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+( N-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_ZGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_ZUNGQR_N )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_Q )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_P )
MAXWRK = 2*N*N + WRKBL
MINWRK = 2*N + M
ELSE IF( WNTUS .AND. WNTVAS ) THEN
* Path 6 (M much larger than N, JOBU='S', JOBVT='S' or
* 'A')
*
- WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
- $ N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+( N-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_ZGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_ZUNGQR_N )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_Q )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_P )
MAXWRK = N*N + WRKBL
MINWRK = 2*N + M
ELSE IF( WNTUA .AND. WNTVN ) THEN
*
* Path 7 (M much larger than N, JOBU='A', JOBVT='N')
*
- WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'ZUNGQR', ' ', M,
- $ M, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
+ WRKBL = N + LWORK_ZGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_ZUNGQR_M )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_Q )
MAXWRK = N*N + WRKBL
MINWRK = 2*N + M
ELSE IF( WNTUA .AND. WNTVO ) THEN
*
* Path 8 (M much larger than N, JOBU='A', JOBVT='O')
*
- WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'ZUNGQR', ' ', M,
- $ M, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+( N-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_ZGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_ZUNGQR_M )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_Q )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_P )
MAXWRK = 2*N*N + WRKBL
MINWRK = 2*N + M
ELSE IF( WNTUA .AND. WNTVAS ) THEN
* Path 9 (M much larger than N, JOBU='A', JOBVT='S' or
* 'A')
*
- WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'ZUNGQR', ' ', M,
- $ M, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+2*N*
- $ ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+N*
- $ ILAENV( 1, 'ZUNGBR', 'Q', N, N, N, -1 ) )
- WRKBL = MAX( WRKBL, 2*N+( N-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+ WRKBL = N + LWORK_ZGEQRF
+ WRKBL = MAX( WRKBL, N+LWORK_ZUNGQR_M )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_Q )
+ WRKBL = MAX( WRKBL, 2*N+LWORK_ZUNGBR_P )
MAXWRK = N*N + WRKBL
MINWRK = 2*N + M
END IF
*
* Path 10 (M at least N, but not much larger)
*
- MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
- $ -1, -1 )
- IF( WNTUS .OR. WNTUO )
- $ MAXWRK = MAX( MAXWRK, 2*N+N*
- $ ILAENV( 1, 'ZUNGBR', 'Q', M, N, N, -1 ) )
- IF( WNTUA )
- $ MAXWRK = MAX( MAXWRK, 2*N+M*
- $ ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
- IF( .NOT.WNTVN )
- $ MAXWRK = MAX( MAXWRK, 2*N+( N-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
+ CALL ZGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_ZGEBRD=DUM(1)
+ MAXWRK = 2*N + LWORK_ZGEBRD
+ IF( WNTUS .OR. WNTUO ) THEN
+ CALL ZUNGBR( 'Q', M, N, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_ZUNGBR_Q=DUM(1)
+ MAXWRK = MAX( MAXWRK, 2*N+LWORK_ZUNGBR_Q )
+ END IF
+ IF( WNTUA ) THEN
+ CALL ZUNGBR( 'Q', M, M, N, A, LDA, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_ZUNGBR_Q=DUM(1)
+ MAXWRK = MAX( MAXWRK, 2*N+LWORK_ZUNGBR_Q )
+ END IF
+ IF( .NOT.WNTVN ) THEN
+ MAXWRK = MAX( MAXWRK, 2*N+LWORK_ZUNGBR_P )
MINWRK = 2*N + M
+ END IF
END IF
ELSE IF( MINMN.GT.0 ) THEN
*
* Space needed for ZBDSQR is BDSPAC = 5*M
*
MNTHR = ILAENV( 6, 'ZGESVD', JOBU // JOBVT, M, N, 0, 0 )
+* Compute space needed for ZGELQF
+ CALL ZGELQF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_ZGELQF=DUM(1)
+* Compute space needed for ZUNGLQ
+ CALL ZUNGLQ( N, N, M, VT, LDVT, DUM(1), DUM(1), -1, IERR )
+ LWORK_ZUNGLQ_N=DUM(1)
+ CALL ZUNGLQ( M, N, M, A, LDA, DUM(1), DUM(1), -1, IERR )
+ LWORK_ZUNGLQ_M=DUM(1)
+* Compute space needed for ZGEBRD
+ CALL ZGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_ZGEBRD=DUM(1)
+* Compute space needed for ZUNGBR P
+ CALL ZUNGBR( 'P', M, M, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_ZUNGBR_P=DUM(1)
+* Compute space needed for ZUNGBR Q
+ CALL ZUNGBR( 'Q', M, M, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_ZUNGBR_Q=DUM(1)
IF( N.GE.MNTHR ) THEN
IF( WNTVN ) THEN
*
* Path 1t(N much larger than M, JOBVT='N')
*
- MAXWRK = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1,
- $ -1 )
- MAXWRK = MAX( MAXWRK, 2*M+2*M*
- $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
+ MAXWRK = M + LWORK_ZGELQF
+ MAXWRK = MAX( MAXWRK, 2*M+LWORK_ZGEBRD )
IF( WNTUO .OR. WNTUAS )
- $ MAXWRK = MAX( MAXWRK, 2*M+M*
- $ ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+ $ MAXWRK = MAX( MAXWRK, 2*M+LWORK_ZUNGBR_Q )
MINWRK = 3*M
ELSE IF( WNTVO .AND. WNTUN ) THEN
*
* Path 2t(N much larger than M, JOBU='N', JOBVT='O')
*
- WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
+ WRKBL = M + LWORK_ZGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_ZUNGLQ_M )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_P )
MAXWRK = MAX( M*M+WRKBL, M*M+M*N )
MINWRK = 2*M + N
ELSE IF( WNTVO .AND. WNTUAS ) THEN
* Path 3t(N much larger than M, JOBU='S' or 'A',
* JOBVT='O')
*
- WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+M*
- $ ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_ZGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_ZUNGLQ_M )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_P )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_Q )
MAXWRK = MAX( M*M+WRKBL, M*M+M*N )
MINWRK = 2*M + N
ELSE IF( WNTVS .AND. WNTUN ) THEN
*
* Path 4t(N much larger than M, JOBU='N', JOBVT='S')
*
- WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
+ WRKBL = M + LWORK_ZGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_ZUNGLQ_M )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_P )
MAXWRK = M*M + WRKBL
MINWRK = 2*M + N
ELSE IF( WNTVS .AND. WNTUO ) THEN
*
* Path 5t(N much larger than M, JOBU='O', JOBVT='S')
*
- WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+M*
- $ ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_ZGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_ZUNGLQ_M )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_P )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_Q )
MAXWRK = 2*M*M + WRKBL
MINWRK = 2*M + N
ELSE IF( WNTVS .AND. WNTUAS ) THEN
* Path 6t(N much larger than M, JOBU='S' or 'A',
* JOBVT='S')
*
- WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+M*
- $ ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_ZGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_ZUNGLQ_M )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_P )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_Q )
MAXWRK = M*M + WRKBL
MINWRK = 2*M + N
ELSE IF( WNTVA .AND. WNTUN ) THEN
*
* Path 7t(N much larger than M, JOBU='N', JOBVT='A')
*
- WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'ZUNGLQ', ' ', N,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
+ WRKBL = M + LWORK_ZGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_ZUNGLQ_N )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_P )
MAXWRK = M*M + WRKBL
MINWRK = 2*M + N
ELSE IF( WNTVA .AND. WNTUO ) THEN
*
* Path 8t(N much larger than M, JOBU='O', JOBVT='A')
*
- WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'ZUNGLQ', ' ', N,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+M*
- $ ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_ZGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_ZUNGLQ_N )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_P )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_Q )
MAXWRK = 2*M*M + WRKBL
MINWRK = 2*M + N
ELSE IF( WNTVA .AND. WNTUAS ) THEN
* Path 9t(N much larger than M, JOBU='S' or 'A',
* JOBVT='A')
*
- WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
- WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'ZUNGLQ', ' ', N,
- $ N, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+2*M*
- $ ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+( M-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) )
- WRKBL = MAX( WRKBL, 2*M+M*
- $ ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+ WRKBL = M + LWORK_ZGELQF
+ WRKBL = MAX( WRKBL, M+LWORK_ZUNGLQ_N )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZGEBRD )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_P )
+ WRKBL = MAX( WRKBL, 2*M+LWORK_ZUNGBR_Q )
MAXWRK = M*M + WRKBL
MINWRK = 2*M + N
END IF
*
* Path 10t(N greater than M, but not much larger)
*
- MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
- $ -1, -1 )
- IF( WNTVS .OR. WNTVO )
- $ MAXWRK = MAX( MAXWRK, 2*M+M*
- $ ILAENV( 1, 'ZUNGBR', 'P', M, N, M, -1 ) )
- IF( WNTVA )
- $ MAXWRK = MAX( MAXWRK, 2*M+N*
- $ ILAENV( 1, 'ZUNGBR', 'P', N, N, M, -1 ) )
- IF( .NOT.WNTUN )
- $ MAXWRK = MAX( MAXWRK, 2*M+( M-1 )*
- $ ILAENV( 1, 'ZUNGBR', 'Q', M, M, M, -1 ) )
+ CALL ZGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
+ $ DUM(1), DUM(1), -1, IERR )
+ LWORK_ZGEBRD=DUM(1)
+ MAXWRK = 2*M + LWORK_ZGEBRD
+ IF( WNTVS .OR. WNTVO ) THEN
+* Compute space needed for ZUNGBR P
+ CALL ZUNGBR( 'P', M, N, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_ZUNGBR_P=DUM(1)
+ MAXWRK = MAX( MAXWRK, 2*M+LWORK_ZUNGBR_P )
+ END IF
+ IF( WNTVA ) THEN
+ CALL ZUNGBR( 'P', N, N, M, A, N, DUM(1),
+ $ DUM(1), -1, IERR )
+ LWORK_ZUNGBR_P=DUM(1)
+ MAXWRK = MAX( MAXWRK, 2*M+LWORK_ZUNGBR_P )
+ END IF
+ IF( .NOT.WNTUN ) THEN
+ MAXWRK = MAX( MAXWRK, 2*M+LWORK_ZUNGBR_Q )
MINWRK = 2*M + N
+ END IF
END IF
END IF
MAXWRK = MAX( MAXWRK, MINWRK )
*
IF( INFO.EQ.0 ) THEN
IF( WANTQ ) THEN
- NB = ILAENV( 1, 'ZUNGQR', ' ', M, N, K, -1 )
+ IF( M.GE.K ) THEN
+ CALL ZUNGQR( M, N, K, A, LDA, TAU, WORK, -1, IINFO )
+ ELSE
+ CALL ZUNGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK,
+ $ -1, IINFO )
+ END IF
ELSE
- NB = ILAENV( 1, 'ZUNGLQ', ' ', M, N, K, -1 )
+ IF( K.LT.N ) THEN
+ CALL ZUNGLQ( M, N, K, A, LDA, TAU, WORK, -1, IINFO )
+ ELSE
+ CALL ZUNGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,
+ $ -1, IINFO )
+ END IF
END IF
- LWKOPT = MAX( 1, MN )*NB
- WORK( 1 ) = LWKOPT
+ LWKOPT = WORK( 1 )
END IF
*
IF( INFO.NE.0 ) THEN