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, M, 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, INDS, 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, BIGNUM, EPS, SMLNUM
316 EXTERNAL lsame, ilaenv, slamch, clange
319 INTRINSIC max, min, sqrt
327 abstol = 2*slamch(
'S')
328 lquery = ( lwork.EQ.-1 )
331 wantu = lsame( jobu,
'V' )
332 wantvt = lsame( jobvt,
'V' )
333 IF( wantu .OR. wantvt )
THEN 338 alls = lsame( range,
'A' )
339 vals = lsame( range,
'V' )
340 inds = lsame( range,
'I' )
343 IF( .NOT.lsame( jobu,
'V' ) .AND.
344 $ .NOT.lsame( jobu,
'N' ) )
THEN 346 ELSE IF( .NOT.lsame( jobvt,
'V' ) .AND.
347 $ .NOT.lsame( jobvt,
'N' ) )
THEN 349 ELSE IF( .NOT.( alls .OR. vals .OR. inds ) )
THEN 351 ELSE IF( m.LT.0 )
THEN 353 ELSE IF( n.LT.0 )
THEN 355 ELSE IF( m.GT.lda )
THEN 357 ELSE IF( minmn.GT.0 )
THEN 359 IF( vl.LT.zero )
THEN 361 ELSE IF( vu.LE.vl )
THEN 365 IF( il.LT.1 .OR. il.GT.max( 1, minmn ) )
THEN 367 ELSE IF( iu.LT.min( minmn, il ) .OR. iu.GT.minmn )
THEN 372 IF( wantu .AND. ldu.LT.m )
THEN 374 ELSE IF( wantvt )
THEN 376 IF( ldvt.LT.iu-il+1 )
THEN 379 ELSE IF( ldvt.LT.minmn )
THEN 396 IF( minmn.GT.0 )
THEN 398 mnthr = ilaenv( 6,
'CGESVD', jobu // jobvt, m, n, 0, 0 )
399 IF( m.GE.mnthr )
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 IF (wantu .OR. 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 ELSE IF( anrm.GT.bignum )
THEN 502 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
511 IF( m.GE.mnthr )
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 IF( n.GE.mnthr )
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 clacpy(UPLO, M, N, A, LDA, B, LDB)
CLACPY copies all or part of one two-dimensional array to another.
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 cunmbr(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMBR
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 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 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 cgelqf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CGELQF
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 cunmqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMQR
subroutine cgebrd(M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK, INFO)
CGEBRD
subroutine cgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CGEQRF
subroutine cunmlq(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMLQ