267 SUBROUTINE cgesvdx( JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU,
268 $ IL, IU, NS, S, U, LDU, VT, LDVT, WORK,
269 $ LWORK, RWORK, IWORK, INFO )
276 CHARACTER JOBU, JOBVT, RANGE
277 INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, , N, NS
282 REAL S( * ), RWORK( * )
283 COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
291 PARAMETER ( CZERO = ( 0.0e0, 0.0e0 ),
292 $ cone = ( 1.0e0, 0.0e0 ) )
294 PARAMETER ( ZERO = 0.0e0, one = 1.0e0 )
297 CHARACTER JOBZ, RNGTGK
298 LOGICAL ALLS, , LQUERY, VALS, WANTU, WANTVT
299 INTEGER I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
300 $ itau, itaup, itauq, itemp, itempr, itgkz,
301 $ iutgk, j, k, maxwrk, minmn, minwrk, mnthr
302 REAL ABSTOL, ANRM, , EPS, SMLNUM
316 EXTERNAL lsame, ilaenv, slamch, clange
327 abstol = 2*slamch('s
')
328.EQ.
LQUERY = ( LWORK-1 )
331 WANTU = LSAME( JOBU, 'v
' )
332 WANTVT = LSAME( JOBVT, 'v
' )
333.OR.
IF( WANTU WANTVT ) THEN
338 ALLS = LSAME( RANGE, 'a
' )
339 VALS = LSAME( RANGE, 'v
' )
340 INDS = LSAME( RANGE, 'i
' )
343.NOT.
IF( LSAME( JOBU, 'v.AND.
' )
344.NOT.
$ LSAME( JOBU, 'n
' ) ) THEN
346.NOT.
ELSE IF( LSAME( JOBVT, 'v.AND.
' )
347.NOT.
$ LSAME( JOBVT, 'n
' ) ) THEN
349.NOT..OR..OR.
ELSE IF( ( ALLS VALS INDS ) ) THEN
351.LT.
ELSE IF( M0 ) THEN
353.LT.
ELSE IF( N0 ) THEN
355.GT.
ELSE IF( MLDA ) THEN
357.GT.
ELSE IF( MINMN0 ) THEN
359.LT.
IF( VLZERO ) THEN
361.LE.
ELSE IF( VUVL ) THEN
365.LT..OR..GT.
IF( IL1 ILMAX( 1, MINMN ) ) THEN
367.LT..OR..GT.
ELSE IF( IUMIN( MINMN, IL ) IUMINMN ) THEN
372.AND..LT.
IF( WANTU LDUM ) THEN
374 ELSE IF( WANTVT ) THEN
376.LT.
IF( LDVTIU-IL+1 ) THEN
379.LT.
ELSE IF( LDVTMINMN ) THEN
396.GT.
IF( MINMN0 ) THEN
398 MNTHR = ILAENV( 6, 'cgesvd', JOBU // JOBVT, M, N, 0, 0 )
399.GE.
IF( MMNTHR ) THEN
404 MAXWRK = N + N*ILAENV(1,'cgeqrf',' ',M,N,-1,-1)
406 $ N*N+2*N+2*N*ILAENV(1,'cgebrd',' ',N,N,-1,-1))
407.OR.
IF (WANTU WANTVT) THEN
409 $ N*N+2*N+N*ILAENV(1,'cunmqr','ln
',N,N,N,-1))
416 MAXWRK = 2*N + (M+N)*ILAENV(1,'cgebrd',
' ',m,n,-1,-1)
417 IF (wantu .OR. wantvt)
THEN
419 $ 2*n+n*ilaenv(1,
'CUNMQR',
'LN',n,n,n,-1))
423 mnthr = ilaenv( 6,
'CGESVD', jobu // jobvt, m, n, 0, 0 )
424 IF( n.GE.mnthr )
THEN
429 maxwrk = m + m*ilaenv(1,
'CGELQF',
' ',m,n,-1,-1)
431 $ m*m+2*m+2*m*ilaenv(1,
'CGEBRD',
' ',m,m,-1,-1))
432 IF (wantu .OR. wantvt)
THEN
434 $ m*m+2*m+m*ilaenv(1,
'CUNMQR',
'LN',m,m,m,-1))
442 maxwrk = 2*m + (m+n)*ilaenv(1,
'CGEBRD',
' ',m,n,-1,-1)
443 IF (wantu .OR. wantvt)
THEN
445 $ 2*m+m*ilaenv(1,
'CUNMQR',
'LN',m,m,m,-1))
450 maxwrk =
max( maxwrk, minwrk )
451 work( 1 ) =
cmplx( real( maxwrk ), zero )
453 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
459 CALL xerbla(
'CGESVDX', -info )
461 ELSE IF( lquery )
THEN
467 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
490 smlnum = sqrt( slamch(
'S' ) ) / eps
491 bignum = one / smlnum
495 anrm = clange(
'M', m, n, a, lda, dum )
497 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
499 CALL clascl( 'g
', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
500.GT.
ELSE IF( ANRMBIGNUM ) THEN
502 CALL CLASCL( 'g
', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
511.GE.
IF( MMNTHR ) THEN
523 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( ITEMP ),
524 $ LWORK-ITEMP+1, INFO )
536 CALL CLACPY( 'u
', N, N, A, LDA, WORK( IQRF ), N )
537 CALL CLASET( 'l
', N-1, N-1, CZERO, CZERO,
538 $ WORK( IQRF+1 ), N )
539 CALL CGEBRD( N, N, WORK( IQRF ), N, RWORK( ID ),
540 $ RWORK( IE ), WORK( ITAUQ ), WORK( ITAUP ),
541 $ WORK( ITEMP ), LWORK-ITEMP+1, INFO )
542 ITEMPR = ITGKZ + N*(N*2+1)
547 CALL SBDSVDX( 'u
', JOBZ, RNGTGK, N, RWORK( ID ),
548 $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
549 $ RWORK( ITGKZ ), N*2, RWORK( ITEMPR ),
558 U( J, I ) = CMPLX( RWORK( K ), ZERO )
563 CALL CLASET( 'a
', M-N, NS, CZERO, CZERO, U( N+1,1 ), LDU)
568 CALL CUNMBR( 'q
', 'l
', 'n
', N, NS, N, WORK( IQRF ), N,
569 $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
570 $ LWORK-ITEMP+1, INFO )
575 CALL CUNMQR( 'l
', 'n
', M, NS, N, A, LDA,
576 $ WORK( ITAU ), U, LDU, WORK( ITEMP ),
577 $ LWORK-ITEMP+1, INFO )
586 VT( I, J ) = CMPLX( RWORK( K ), ZERO )
595 CALL CUNMBR( 'p
', 'r
', 'c
', NS, N, N, WORK( IQRF ), N,
596 $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
597 $ LWORK-ITEMP+1, INFO )
615 CALL CGEBRD( M, N, A, LDA, RWORK( ID ), RWORK( IE ),
616 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( ITEMP ),
617 $ LWORK-ITEMP+1, INFO )
618 ITEMPR = ITGKZ + N*(N*2+1)
623 CALL SBDSVDX( 'u
', JOBZ, RNGTGK, N, RWORK( ID ),
624 $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
625 $ RWORK( ITGKZ ), N*2, RWORK( ITEMPR ),
634 U( J, I ) = CMPLX( RWORK( K ), ZERO )
639 CALL CLASET( 'a
', M-N, NS, CZERO, CZERO, U( N+1,1 ), LDU)
644 CALL CUNMBR( 'q
', 'l
', 'n
', M, NS, N, A, LDA,
645 $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
646 $ LWORK-ITEMP+1, IERR )
655 VT( I, J ) = CMPLX( RWORK( K ), ZERO )
664 CALL CUNMBR( 'p
', 'r
', 'c
', NS, N, N, A, LDA,
665 $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
666 $ LWORK-ITEMP+1, IERR )
674.GE.
IF( NMNTHR ) THEN
686 CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( ITEMP ),
687 $ LWORK-ITEMP+1, INFO )
699 CALL CLACPY( 'l
', M, M, A, LDA, WORK( ILQF ), M )
700 CALL CLASET( 'u
', M-1, M-1, CZERO, CZERO,
701 $ WORK( ILQF+M ), M )
702 CALL CGEBRD( M, M, WORK( ILQF ), M, RWORK( ID ),
703 $ RWORK( IE ), WORK( ITAUQ ), WORK( ITAUP ),
704 $ WORK( ITEMP ), LWORK-ITEMP+1, INFO )
705 ITEMPR = ITGKZ + M*(M*2+1)
710 CALL SBDSVDX( 'u
', JOBZ, RNGTGK, M, RWORK( ID ),
711 $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
712 $ RWORK( ITGKZ ), M*2, RWORK( ITEMPR ),
721 U( J, I ) = CMPLX( RWORK( K ), ZERO )
730 CALL CUNMBR( 'q
', 'l
', 'n
', M, NS, M, WORK( ILQF ), M,
731 $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
732 $ LWORK-ITEMP+1, INFO )
741 VT( I, J ) = CMPLX( RWORK( K ), ZERO )
746 CALL CLASET( 'a
', NS, N-M, CZERO, CZERO,
747 $ VT( 1,M+1 ), LDVT )
752 CALL CUNMBR( 'p
', 'r
', 'c
', NS, M, M, WORK( ILQF ), M,
753 $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
754 $ LWORK-ITEMP+1, INFO )
759 CALL CUNMLQ( 'r
', 'n
', NS, N, M, A, LDA,
760 $ WORK( ITAU ), VT, LDVT, WORK( ITEMP ),
761 $ LWORK-ITEMP+1, INFO )
779 CALL CGEBRD( M, N, A, LDA, RWORK( ID ), RWORK( IE ),
780 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( ITEMP ),
781 $ LWORK-ITEMP+1, INFO )
782 ITEMPR = ITGKZ + M*(M*2+1)
787 CALL SBDSVDX( 'l
', JOBZ, RNGTGK, M, RWORK( ID ),
788 $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
789 $ RWORK( ITGKZ ), M*2, RWORK( ITEMPR ),
798 U( J, I ) = CMPLX( RWORK( K ), ZERO )
807 CALL CUNMBR( 'q
', 'l
', 'n
', M, NS, N, A, LDA,
808 $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
809 $ LWORK-ITEMP+1, INFO )
818 VT( I, J ) = CMPLX( RWORK( K ), ZERO )
823 CALL CLASET( 'a
', NS, N-M, CZERO, CZERO,
824 $ VT( 1,M+1 ), LDVT )
829 CALL CUNMBR( 'p
', 'r
', 'c
', NS, N, M, A, LDA,
830 $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
831 $ LWORK-ITEMP+1, INFO )
840 $ CALL SLASCL( 'g
', 0, 0, BIGNUM, ANRM, MINMN, 1,
843 $ CALL SLASCL( 'g
', 0, 0, SMLNUM, ANRM, MINMN, 1,
849 WORK( 1 ) = CMPLX( REAL( MAXWRK ), ZERO )
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine xerbla(srname, info)
XERBLA
subroutine cgeqrf(m, n, a, lda, tau, work, lwork, info)
CGEQRF
subroutine cgebrd(m, n, a, lda, d, e, tauq, taup, work, lwork, info)
CGEBRD
subroutine cgelqf(m, n, a, lda, tau, work, lwork, info)
CGELQF
subroutine cgesvdx(jobu, jobvt, range, m, n, a, lda, vl, vu, il, iu, ns, s, u, ldu, vt, ldvt, work, lwork, rwork, iwork, info)
CGESVDX computes the singular value decomposition (SVD) for GE matrices
subroutine cgesvd(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, info)
CGESVD computes the singular value decomposition (SVD) for GE matrices
subroutine clascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
subroutine claset(uplo, m, n, alpha, beta, a, lda)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine cunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMQR
subroutine cunmlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMLQ
subroutine cunmbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMBR
subroutine sbdsvdx(uplo, jobz, range, n, d, e, vl, vu, il, iu, ns, s, z, ldz, work, iwork, info)
SBDSVDX