269 SUBROUTINE cgesvdx( JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU,
270 $ IL, IU, NS, S, U, LDU, VT, LDVT, WORK,
271 $ LWORK, RWORK, IWORK, INFO )
279 CHARACTER JOBU, JOBVT, RANGE
280 INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
285 REAL S( * ), RWORK( * )
286 COMPLEX A( lda, * ), U( ldu, * ), VT( ldvt, * ),
294 parameter( czero = ( 0.0e0, 0.0e0 ),
295 $ cone = ( 1.0e0, 0.0e0 ) )
297 parameter( zero = 0.0e0, one = 1.0e0 )
300 CHARACTER JOBZ, RNGTGK
301 LOGICAL ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
302 INTEGER I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
303 $ itau, itaup, itauq, itemp, itempr, itgkz,
304 $ iutgk, j, k, maxwrk, minmn, minwrk, mnthr
305 REAL ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
318 EXTERNAL lsame, ilaenv, slamch, clange
321 INTRINSIC max, min, sqrt
329 abstol = 2*slamch(
'S')
330 lquery = ( lwork.EQ.-1 )
333 wantu = lsame( jobu,
'V' )
334 wantvt = lsame( jobvt,
'V' )
335 IF( wantu .OR. wantvt )
THEN 340 alls = lsame( range,
'A' )
341 vals = lsame( range,
'V' )
342 inds = lsame( range,
'I' )
345 IF( .NOT.lsame( jobu,
'V' ) .AND.
346 $ .NOT.lsame( jobu,
'N' ) )
THEN 348 ELSE IF( .NOT.lsame( jobvt,
'V' ) .AND.
349 $ .NOT.lsame( jobvt,
'N' ) )
THEN 351 ELSE IF( .NOT.( alls .OR. vals .OR. inds ) )
THEN 353 ELSE IF( m.LT.0 )
THEN 355 ELSE IF( n.LT.0 )
THEN 357 ELSE IF( m.GT.lda )
THEN 359 ELSE IF( minmn.GT.0 )
THEN 361 IF( vl.LT.zero )
THEN 363 ELSE IF( vu.LE.vl )
THEN 367 IF( il.LT.1 .OR. il.GT.max( 1, minmn ) )
THEN 369 ELSE IF( iu.LT.min( minmn, il ) .OR. iu.GT.minmn )
THEN 374 IF( wantu .AND. ldu.LT.m )
THEN 376 ELSE IF( wantvt )
THEN 378 IF( ldvt.LT.iu-il+1 )
THEN 381 ELSE IF( ldvt.LT.minmn )
THEN 398 IF( minmn.GT.0 )
THEN 400 mnthr = ilaenv( 6,
'CGESVD', jobu // jobvt, m, n, 0, 0 )
401 IF( m.GE.mnthr )
THEN 406 maxwrk = n + n*ilaenv(1,
'CGEQRF',
' ',m,n,-1,-1)
408 $ n*n+2*n+2*n*ilaenv(1,
'CGEBRD',
' ',n,n,-1,-1))
409 IF (wantu .OR. wantvt)
THEN 411 $ n*n+2*n+n*ilaenv(1,
'CUNMQR',
'LN',n,n,n,-1))
418 maxwrk = 2*n + (m+n)*ilaenv(1,
'CGEBRD',
' ',m,n,-1,-1)
419 IF (wantu .OR. wantvt)
THEN 421 $ 2*n+n*ilaenv(1,
'CUNMQR',
'LN',n,n,n,-1))
425 mnthr = ilaenv( 6,
'CGESVD', jobu // jobvt, m, n, 0, 0 )
426 IF( n.GE.mnthr )
THEN 431 maxwrk = m + m*ilaenv(1,
'CGELQF',
' ',m,n,-1,-1)
433 $ m*m+2*m+2*m*ilaenv(1,
'CGEBRD',
' ',m,m,-1,-1))
434 IF (wantu .OR. wantvt)
THEN 436 $ m*m+2*m+m*ilaenv(1,
'CUNMQR',
'LN',m,m,m,-1))
444 maxwrk = 2*m + (m+n)*ilaenv(1,
'CGEBRD',
' ',m,n,-1,-1)
445 IF (wantu .OR. wantvt)
THEN 447 $ 2*m+m*ilaenv(1,
'CUNMQR',
'LN',m,m,m,-1))
452 maxwrk = max( maxwrk, minwrk )
453 work( 1 ) = cmplx(
REAL( MAXWRK ), ZERO )
455 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN 461 CALL xerbla(
'CGESVDX', -info )
463 ELSE IF( lquery )
THEN 469 IF( m.EQ.0 .OR. n.EQ.0 )
THEN 492 smlnum = sqrt( slamch(
'S' ) ) / eps
493 bignum = one / smlnum
497 anrm = clange(
'M', m, n, a, lda, dum )
499 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN 501 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
502 ELSE IF( anrm.GT.bignum )
THEN 504 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
513 IF( m.GE.mnthr )
THEN 525 CALL cgeqrf( m, n, a, lda, work( itau ), work( itemp ),
526 $ lwork-itemp+1, info )
538 CALL clacpy(
'U', n, n, a, lda, work( iqrf ), n )
539 CALL claset(
'L', n-1, n-1, czero, czero,
540 $ work( iqrf+1 ), n )
541 CALL cgebrd( n, n, work( iqrf ), n, rwork( id ),
542 $ rwork( ie ), work( itauq ), work( itaup ),
543 $ work( itemp ), lwork-itemp+1, info )
544 itempr = itgkz + n*(n*2+1)
549 CALL sbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
550 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
551 $ rwork( itgkz ), n*2, rwork( itempr ),
560 u( j, i ) = cmplx( rwork( k ), zero )
565 CALL claset(
'A', m-n, ns, czero, czero, u( n+1,1 ), ldu)
570 CALL cunmbr(
'Q',
'L',
'N', n, ns, n, work( iqrf ), n,
571 $ work( itauq ), u, ldu, work( itemp ),
572 $ lwork-itemp+1, info )
577 CALL cunmqr(
'L',
'N', m, ns, n, a, lda,
578 $ work( itau ), u, ldu, work( itemp ),
579 $ lwork-itemp+1, info )
588 vt( i, j ) = cmplx( rwork( k ), zero )
597 CALL cunmbr(
'P',
'R',
'C', ns, n, n, work( iqrf ), n,
598 $ work( itaup ), vt, ldvt, work( itemp ),
599 $ lwork-itemp+1, info )
617 CALL cgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
618 $ work( itauq ), work( itaup ), work( itemp ),
619 $ lwork-itemp+1, info )
620 itempr = itgkz + n*(n*2+1)
625 CALL sbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
626 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
627 $ rwork( itgkz ), n*2, rwork( itempr ),
636 u( j, i ) = cmplx( rwork( k ), zero )
641 CALL claset(
'A', m-n, ns, czero, czero, u( n+1,1 ), ldu)
646 CALL cunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
647 $ work( itauq ), u, ldu, work( itemp ),
648 $ lwork-itemp+1, ierr )
657 vt( i, j ) = cmplx( rwork( k ), zero )
666 CALL cunmbr(
'P',
'R',
'C', ns, n, n, a, lda,
667 $ work( itaup ), vt, ldvt, work( itemp ),
668 $ lwork-itemp+1, ierr )
676 IF( n.GE.mnthr )
THEN 688 CALL cgelqf( m, n, a, lda, work( itau ), work( itemp ),
689 $ lwork-itemp+1, info )
701 CALL clacpy(
'L', m, m, a, lda, work( ilqf ), m )
702 CALL claset(
'U', m-1, m-1, czero, czero,
703 $ work( ilqf+m ), m )
704 CALL cgebrd( m, m, work( ilqf ), m, rwork( id ),
705 $ rwork( ie ), work( itauq ), work( itaup ),
706 $ work( itemp ), lwork-itemp+1, info )
707 itempr = itgkz + m*(m*2+1)
712 CALL sbdsvdx(
'U', jobz, rngtgk, m, rwork( id ),
713 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
714 $ rwork( itgkz ), m*2, rwork( itempr ),
723 u( j, i ) = cmplx( rwork( k ), zero )
732 CALL cunmbr(
'Q',
'L',
'N', m, ns, m, work( ilqf ), m,
733 $ work( itauq ), u, ldu, work( itemp ),
734 $ lwork-itemp+1, info )
743 vt( i, j ) = cmplx( rwork( k ), zero )
748 CALL claset(
'A', ns, n-m, czero, czero,
749 $ vt( 1,m+1 ), ldvt )
754 CALL cunmbr(
'P',
'R',
'C', ns, m, m, work( ilqf ), m,
755 $ work( itaup ), vt, ldvt, work( itemp ),
756 $ lwork-itemp+1, info )
761 CALL cunmlq(
'R',
'N', ns, n, m, a, lda,
762 $ work( itau ), vt, ldvt, work( itemp ),
763 $ lwork-itemp+1, info )
781 CALL cgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
782 $ work( itauq ), work( itaup ), work( itemp ),
783 $ lwork-itemp+1, info )
784 itempr = itgkz + m*(m*2+1)
789 CALL sbdsvdx(
'L', jobz, rngtgk, m, rwork( id ),
790 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
791 $ rwork( itgkz ), m*2, rwork( itempr ),
800 u( j, i ) = cmplx( rwork( k ), zero )
809 CALL cunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
810 $ work( itauq ), u, ldu, work( itemp ),
811 $ lwork-itemp+1, info )
820 vt( i, j ) = cmplx( rwork( k ), zero )
825 CALL claset(
'A', ns, n-m, czero, czero,
826 $ vt( 1,m+1 ), ldvt )
831 CALL cunmbr(
'P',
'R',
'C', ns, n, m, a, lda,
832 $ work( itaup ), vt, ldvt, work( itemp ),
833 $ lwork-itemp+1, info )
842 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1,
845 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1,
851 work( 1 ) = cmplx(
REAL( MAXWRK ), ZERO )
subroutine cunmlq(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMLQ
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 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 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 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
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine cgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CGEQRF
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 cgebrd(M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK, INFO)
CGEBRD
subroutine clacpy(UPLO, M, N, A, LDA, B, LDB)
CLACPY copies all or part of one two-dimensional array to another.
subroutine cunmqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMQR