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)
subroutine dbdsvdx(uplo, jobz, range, n, d, e, vl, vu, il, iu, ns, s, z, ldz, work, iwork, info)
DBDSVDX
subroutine zgebrd(m, n, a, lda, d, e, tauq, taup, work, lwork, info)
ZGEBRD
subroutine zgelqf(m, n, a, lda, tau, work, lwork, info)
ZGELQF
subroutine zgeqrf(m, n, a, lda, tau, work, lwork, info)
ZGEQRF
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 zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
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 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 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 zunmbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
ZUNMBR
subroutine zunmlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
ZUNMLQ
subroutine zunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
ZUNMQR