267 SUBROUTINE zgesvdx( 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
278 DOUBLE PRECISION VL, VU
282 DOUBLE PRECISION S( * ), RWORK( * )
283 COMPLEX*16 A( lda, * ), U( ldu, * ), VT( ldvt, * ),
290 COMPLEX*16 CZERO, CONE
291 parameter( czero = ( 0.0d0, 0.0d0 ),
292 $ cone = ( 1.0d0, 0.0d0 ) )
293 DOUBLE PRECISION ZERO, ONE
294 parameter( zero = 0.0d0, one = 1.0d0 )
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 DOUBLE PRECISION ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
305 DOUBLE PRECISION DUM( 1 )
314 DOUBLE PRECISION DLAMCH, ZLANGE
315 EXTERNAL lsame, ilaenv, dlamch, zlange
318 INTRINSIC max, min, sqrt
326 abstol = 2*dlamch(
'S')
327 lquery = ( lwork.EQ.-1 )
330 wantu = lsame( jobu,
'V' )
331 wantvt = lsame( jobvt,
'V' )
332 IF( wantu .OR. wantvt )
THEN 337 alls = lsame( range,
'A' )
338 vals = lsame( range,
'V' )
339 inds = lsame( range,
'I' )
342 IF( .NOT.lsame( jobu,
'V' ) .AND.
343 $ .NOT.lsame( jobu,
'N' ) )
THEN 345 ELSE IF( .NOT.lsame( jobvt,
'V' ) .AND.
346 $ .NOT.lsame( jobvt,
'N' ) )
THEN 348 ELSE IF( .NOT.( alls .OR. vals .OR. inds ) )
THEN 350 ELSE IF( m.LT.0 )
THEN 352 ELSE IF( n.LT.0 )
THEN 354 ELSE IF( m.GT.lda )
THEN 356 ELSE IF( minmn.GT.0 )
THEN 358 IF( vl.LT.zero )
THEN 360 ELSE IF( vu.LE.vl )
THEN 364 IF( il.LT.1 .OR. il.GT.max( 1, minmn ) )
THEN 366 ELSE IF( iu.LT.min( minmn, il ) .OR. iu.GT.minmn )
THEN 371 IF( wantu .AND. ldu.LT.m )
THEN 373 ELSE IF( wantvt )
THEN 375 IF( ldvt.LT.iu-il+1 )
THEN 378 ELSE IF( ldvt.LT.minmn )
THEN 395 IF( minmn.GT.0 )
THEN 397 mnthr = ilaenv( 6,
'ZGESVD', jobu // jobvt, m, n, 0, 0 )
398 IF( m.GE.mnthr )
THEN 403 maxwrk = n + n*ilaenv(1,
'ZGEQRF',
' ',m,n,-1,-1)
405 $ n*n+2*n+2*n*ilaenv(1,
'ZGEBRD',
' ',n,n,-1,-1))
406 IF (wantu .OR. wantvt)
THEN 408 $ n*n+2*n+n*ilaenv(1,
'ZUNMQR',
'LN',n,n,n,-1))
415 maxwrk = 2*n + (m+n)*ilaenv(1,
'ZGEBRD',
' ',m,n,-1,-1)
416 IF (wantu .OR. wantvt)
THEN 418 $ 2*n+n*ilaenv(1,
'ZUNMQR',
'LN',n,n,n,-1))
422 mnthr = ilaenv( 6,
'ZGESVD', jobu // jobvt, m, n, 0, 0 )
423 IF( n.GE.mnthr )
THEN 428 maxwrk = m + m*ilaenv(1,
'ZGELQF',
' ',m,n,-1,-1)
430 $ m*m+2*m+2*m*ilaenv(1,
'ZGEBRD',
' ',m,m,-1,-1))
431 IF (wantu .OR. wantvt)
THEN 433 $ m*m+2*m+m*ilaenv(1,
'ZUNMQR',
'LN',m,m,m,-1))
441 maxwrk = 2*m + (m+n)*ilaenv(1,
'ZGEBRD',
' ',m,n,-1,-1)
442 IF (wantu .OR. wantvt)
THEN 444 $ 2*m+m*ilaenv(1,
'ZUNMQR',
'LN',m,m,m,-1))
449 maxwrk = max( maxwrk, minwrk )
450 work( 1 ) = dcmplx( dble( maxwrk ), zero )
452 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN 458 CALL xerbla(
'ZGESVDX', -info )
460 ELSE IF( lquery )
THEN 466 IF( m.EQ.0 .OR. n.EQ.0 )
THEN 489 smlnum = sqrt( dlamch(
'S' ) ) / eps
490 bignum = one / smlnum
494 anrm = zlange(
'M', m, n, a, lda, dum )
496 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN 498 CALL zlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
499 ELSE IF( anrm.GT.bignum )
THEN 501 CALL zlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
510 IF( m.GE.mnthr )
THEN 522 CALL zgeqrf( m, n, a, lda, work( itau ), work( itemp ),
523 $ lwork-itemp+1, info )
535 CALL zlacpy(
'U', n, n, a, lda, work( iqrf ), n )
536 CALL zlaset(
'L', n-1, n-1, czero, czero,
537 $ work( iqrf+1 ), n )
538 CALL zgebrd( n, n, work( iqrf ), n, rwork( id ),
539 $ rwork( ie ), work( itauq ), work( itaup ),
540 $ work( itemp ), lwork-itemp+1, info )
541 itempr = itgkz + n*(n*2+1)
546 CALL dbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
547 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
548 $ rwork( itgkz ), n*2, rwork( itempr ),
557 u( j, i ) = dcmplx( rwork( k ), zero )
562 CALL zlaset(
'A', m-n, ns, czero, czero, u( n+1,1 ), ldu)
567 CALL zunmbr(
'Q',
'L',
'N', n, ns, n, work( iqrf ), n,
568 $ work( itauq ), u, ldu, work( itemp ),
569 $ lwork-itemp+1, info )
574 CALL zunmqr(
'L',
'N', m, ns, n, a, lda,
575 $ work( itau ), u, ldu, work( itemp ),
576 $ lwork-itemp+1, info )
585 vt( i, j ) = dcmplx( rwork( k ), zero )
594 CALL zunmbr(
'P',
'R',
'C', ns, n, n, work( iqrf ), n,
595 $ work( itaup ), vt, ldvt, work( itemp ),
596 $ lwork-itemp+1, info )
614 CALL zgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
615 $ work( itauq ), work( itaup ), work( itemp ),
616 $ lwork-itemp+1, info )
617 itempr = itgkz + n*(n*2+1)
622 CALL dbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
623 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
624 $ rwork( itgkz ), n*2, rwork( itempr ),
633 u( j, i ) = dcmplx( rwork( k ), zero )
638 CALL zlaset(
'A', m-n, ns, czero, czero, u( n+1,1 ), ldu)
643 CALL zunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
644 $ work( itauq ), u, ldu, work( itemp ),
645 $ lwork-itemp+1, ierr )
654 vt( i, j ) = dcmplx( rwork( k ), zero )
663 CALL zunmbr(
'P',
'R',
'C', ns, n, n, a, lda,
664 $ work( itaup ), vt, ldvt, work( itemp ),
665 $ lwork-itemp+1, ierr )
673 IF( n.GE.mnthr )
THEN 685 CALL zgelqf( m, n, a, lda, work( itau ), work( itemp ),
686 $ lwork-itemp+1, info )
698 CALL zlacpy(
'L', m, m, a, lda, work( ilqf ), m )
699 CALL zlaset(
'U', m-1, m-1, czero, czero,
700 $ work( ilqf+m ), m )
701 CALL zgebrd( m, m, work( ilqf ), m, rwork( id ),
702 $ rwork( ie ), work( itauq ), work( itaup ),
703 $ work( itemp ), lwork-itemp+1, info )
704 itempr = itgkz + m*(m*2+1)
709 CALL dbdsvdx(
'U', jobz, rngtgk, m, rwork( id ),
710 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
711 $ rwork( itgkz ), m*2, rwork( itempr ),
720 u( j, i ) = dcmplx( rwork( k ), zero )
729 CALL zunmbr(
'Q',
'L',
'N', m, ns, m, work( ilqf ), m,
730 $ work( itauq ), u, ldu, work( itemp ),
731 $ lwork-itemp+1, info )
740 vt( i, j ) = dcmplx( rwork( k ), zero )
745 CALL zlaset(
'A', ns, n-m, czero, czero,
746 $ vt( 1,m+1 ), ldvt )
751 CALL zunmbr(
'P',
'R',
'C', ns, m, m, work( ilqf ), m,
752 $ work( itaup ), vt, ldvt, work( itemp ),
753 $ lwork-itemp+1, info )
758 CALL zunmlq(
'R',
'N', ns, n, m, a, lda,
759 $ work( itau ), vt, ldvt, work( itemp ),
760 $ lwork-itemp+1, info )
778 CALL zgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
779 $ work( itauq ), work( itaup ), work( itemp ),
780 $ lwork-itemp+1, info )
781 itempr = itgkz + m*(m*2+1)
786 CALL dbdsvdx(
'L', jobz, rngtgk, m, rwork( id ),
787 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
788 $ rwork( itgkz ), m*2, rwork( itempr ),
797 u( j, i ) = dcmplx( rwork( k ), zero )
806 CALL zunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
807 $ work( itauq ), u, ldu, work( itemp ),
808 $ lwork-itemp+1, info )
817 vt( i, j ) = dcmplx( rwork( k ), zero )
822 CALL zlaset(
'A', ns, n-m, czero, czero,
823 $ vt( 1,m+1 ), ldvt )
828 CALL zunmbr(
'P',
'R',
'C', ns, n, m, a, lda,
829 $ work( itaup ), vt, ldvt, work( itemp ),
830 $ lwork-itemp+1, info )
839 $
CALL dlascl(
'G', 0, 0, bignum, anrm, minmn, 1,
842 $
CALL dlascl(
'G', 0, 0, smlnum, anrm, minmn, 1,
848 work( 1 ) = dcmplx( dble( maxwrk ), zero )
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine zunmlq(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMLQ
subroutine zgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
ZGEQRF
subroutine zgelqf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
ZGELQF
subroutine zlascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
ZLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine zlacpy(UPLO, M, N, A, LDA, B, LDB)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
subroutine zunmqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMQR
subroutine dlascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine zunmbr(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMBR
subroutine zgebrd(M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK, INFO)
ZGEBRD
subroutine zgesvdx(JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU, IL, IU, NS, S, U, LDU, VT, LDVT, WORK, LWORK, RWORK, IWORK, INFO)
ZGESVDX computes the singular value decomposition (SVD) for GE matrices
subroutine dbdsvdx(UPLO, JOBZ, RANGE, N, D, E, VL, VU, IL, IU, NS, S, Z, LDZ, WORK, IWORK, INFO)
DBDSVDX