265 SUBROUTINE zgesvdx( JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU,
266 $ IL, IU, NS, S, U, LDU, VT, LDVT, WORK,
267 $ LWORK, RWORK, IWORK, INFO )
274 CHARACTER JOBU, JOBVT, RANGE
275 INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
276 DOUBLE PRECISION VL, VU
280 DOUBLE PRECISION S( * ), RWORK( * )
281 COMPLEX*16 A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
288 COMPLEX*16 CZERO, CONE
289 PARAMETER ( CZERO = ( 0.0d0, 0.0d0 ),
290 $ cone = ( 1.0d0, 0.0d0 ) )
291 DOUBLE PRECISION ZERO, ONE
292 PARAMETER ( ZERO = 0.0d0, one = 1.0d0 )
295 CHARACTER JOBZ, RNGTGK
296 LOGICAL ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
297 INTEGER I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
298 $ itau, itaup, itauq, itemp, itempr, itgkz,
299 $ iutgk, j, k, maxwrk, minmn, minwrk, mnthr
300 DOUBLE PRECISION ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
303 DOUBLE PRECISION DUM( 1 )
313 DOUBLE PRECISION DLAMCH, ZLANGE
314 EXTERNAL lsame, ilaenv, dlamch, zlange
317 INTRINSIC max, min, sqrt
325 abstol = 2*dlamch(
'S')
326 lquery = ( lwork.EQ.-1 )
329 wantu = lsame( jobu,
'V' )
330 wantvt = lsame( jobvt,
'V' )
331 IF( wantu .OR. wantvt )
THEN
336 alls = lsame( range,
'A' )
337 vals = lsame( range,
'V' )
338 inds = lsame( range,
'I' )
341 IF( .NOT.lsame( jobu,
'V' ) .AND.
342 $ .NOT.lsame( jobu,
'N' ) )
THEN
344 ELSE IF( .NOT.lsame( jobvt,
'V' ) .AND.
345 $ .NOT.lsame( jobvt,
'N' ) )
THEN
347 ELSE IF( .NOT.( alls .OR. vals .OR. inds ) )
THEN
349 ELSE IF( m.LT.0 )
THEN
351 ELSE IF( n.LT.0 )
THEN
353 ELSE IF( m.GT.lda )
THEN
355 ELSE IF( minmn.GT.0 )
THEN
357 IF( vl.LT.zero )
THEN
359 ELSE IF( vu.LE.vl )
THEN
363 IF( il.LT.1 .OR. il.GT.max( 1, minmn ) )
THEN
365 ELSE IF( iu.LT.min( minmn, il ) .OR. iu.GT.minmn )
THEN
370 IF( wantu .AND. ldu.LT.m )
THEN
372 ELSE IF( wantvt )
THEN
374 IF( ldvt.LT.iu-il+1 )
THEN
377 ELSE IF( ldvt.LT.minmn )
THEN
394 IF( minmn.GT.0 )
THEN
396 mnthr = ilaenv( 6,
'ZGESVD', jobu // jobvt, m, n, 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,
407 IF (wantu .OR. wantvt)
THEN
409 $ n*n+2*n+n*ilaenv(1,
'ZUNMQR',
'LN',n,n,n,
417 maxwrk = 2*n + (m+n)*ilaenv(1,
'ZGEBRD',
' ',m,n,-1,
419 IF (wantu .OR. wantvt)
THEN
421 $ 2*n+n*ilaenv(1,
'ZUNMQR',
'LN',n,n,n,-1))
425 mnthr = ilaenv( 6,
'ZGESVD', jobu // jobvt, m, n, 0,
427 IF( n.GE.mnthr )
THEN
432 maxwrk = m + m*ilaenv(1,
'ZGELQF',
' ',m,n,-1,-1)
434 $ m*m+2*m+2*m*ilaenv(1,
'ZGEBRD',
' ',m,m,-1,
436 IF (wantu .OR. wantvt)
THEN
438 $ m*m+2*m+m*ilaenv(1,
'ZUNMQR',
'LN',m,m,m,
447 maxwrk = 2*m + (m+n)*ilaenv(1,
'ZGEBRD',
' ',m,n,-1,
449 IF (wantu .OR. wantvt)
THEN
451 $ 2*m+m*ilaenv(1,
'ZUNMQR',
'LN',m,m,m,-1))
456 maxwrk = max( maxwrk, minwrk )
457 work( 1 ) = dcmplx( dble( maxwrk ), zero )
459 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
465 CALL xerbla(
'ZGESVDX', -info )
467 ELSE IF( lquery )
THEN
473 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
496 smlnum = sqrt( dlamch(
'S' ) ) / eps
497 bignum = one / smlnum
501 anrm = zlange(
'M', m, n, a, lda, dum )
503 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
505 CALL zlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
506 ELSE IF( anrm.GT.bignum )
THEN
508 CALL zlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
517 IF( m.GE.mnthr )
THEN
529 CALL zgeqrf( m, n, a, lda, work( itau ), work( itemp ),
530 $ lwork-itemp+1, info )
542 CALL zlacpy(
'U', n, n, a, lda, work( iqrf ), n )
543 CALL zlaset(
'L', n-1, n-1, czero, czero,
544 $ work( iqrf+1 ), n )
545 CALL zgebrd( n, n, work( iqrf ), n, rwork( id ),
546 $ rwork( ie ), work( itauq ), work( itaup ),
547 $ work( itemp ), lwork-itemp+1, info )
548 itempr = itgkz + n*(n*2+1)
553 CALL dbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
554 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
555 $ rwork( itgkz ), n*2, rwork( itempr ),
564 u( j, i ) = dcmplx( rwork( k ), zero )
569 CALL zlaset(
'A', m-n, ns, czero, czero, u( n+1,1 ),
575 CALL zunmbr(
'Q',
'L',
'N', n, ns, n, work( iqrf ), n,
576 $ work( itauq ), u, ldu, work( itemp ),
577 $ lwork-itemp+1, info )
582 CALL zunmqr(
'L',
'N', m, ns, n, a, lda,
583 $ work( itau ), u, ldu, work( itemp ),
584 $ lwork-itemp+1, info )
593 vt( i, j ) = dcmplx( rwork( k ), zero )
602 CALL zunmbr(
'P',
'R',
'C', ns, n, n, work( iqrf ), n,
603 $ work( itaup ), vt, ldvt, work( itemp ),
604 $ lwork-itemp+1, info )
622 CALL zgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
623 $ work( itauq ), work( itaup ), work( itemp ),
624 $ lwork-itemp+1, info )
625 itempr = itgkz + n*(n*2+1)
630 CALL dbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
631 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
632 $ rwork( itgkz ), n*2, rwork( itempr ),
641 u( j, i ) = dcmplx( rwork( k ), zero )
646 CALL zlaset(
'A', m-n, ns, czero, czero, u( n+1,1 ),
652 CALL zunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
653 $ work( itauq ), u, ldu, work( itemp ),
654 $ lwork-itemp+1, ierr )
663 vt( i, j ) = dcmplx( rwork( k ), zero )
672 CALL zunmbr(
'P',
'R',
'C', ns, n, n, a, lda,
673 $ work( itaup ), vt, ldvt, work( itemp ),
674 $ lwork-itemp+1, ierr )
682 IF( n.GE.mnthr )
THEN
694 CALL zgelqf( m, n, a, lda, work( itau ), work( itemp ),
695 $ lwork-itemp+1, info )
707 CALL zlacpy(
'L', m, m, a, lda, work( ilqf ), m )
708 CALL zlaset(
'U', m-1, m-1, czero, czero,
709 $ work( ilqf+m ), m )
710 CALL zgebrd( m, m, work( ilqf ), m, rwork( id ),
711 $ rwork( ie ), work( itauq ), work( itaup ),
712 $ work( itemp ), lwork-itemp+1, info )
713 itempr = itgkz + m*(m*2+1)
718 CALL dbdsvdx(
'U', jobz, rngtgk, m, rwork( id ),
719 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
720 $ rwork( itgkz ), m*2, rwork( itempr ),
729 u( j, i ) = dcmplx( rwork( k ), zero )
738 CALL zunmbr(
'Q',
'L',
'N', m, ns, m, work( ilqf ), m,
739 $ work( itauq ), u, ldu, work( itemp ),
740 $ lwork-itemp+1, info )
749 vt( i, j ) = dcmplx( rwork( k ), zero )
754 CALL zlaset(
'A', ns, n-m, czero, czero,
755 $ vt( 1,m+1 ), ldvt )
760 CALL zunmbr(
'P',
'R',
'C', ns, m, m, work( ilqf ), m,
761 $ work( itaup ), vt, ldvt, work( itemp ),
762 $ lwork-itemp+1, info )
767 CALL zunmlq(
'R',
'N', ns, n, m, a, lda,
768 $ work( itau ), vt, ldvt, work( itemp ),
769 $ lwork-itemp+1, info )
787 CALL zgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
788 $ work( itauq ), work( itaup ), work( itemp ),
789 $ lwork-itemp+1, info )
790 itempr = itgkz + m*(m*2+1)
795 CALL dbdsvdx(
'L', jobz, rngtgk, m, rwork( id ),
796 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
797 $ rwork( itgkz ), m*2, rwork( itempr ),
806 u( j, i ) = dcmplx( rwork( k ), zero )
815 CALL zunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
816 $ work( itauq ), u, ldu, work( itemp ),
817 $ lwork-itemp+1, info )
826 vt( i, j ) = dcmplx( rwork( k ), zero )
831 CALL zlaset(
'A', ns, n-m, czero, czero,
832 $ vt( 1,m+1 ), ldvt )
837 CALL zunmbr(
'P',
'R',
'C', ns, n, m, a, lda,
838 $ work( itaup ), vt, ldvt, work( itemp ),
839 $ lwork-itemp+1, info )
848 $
CALL dlascl(
'G', 0, 0, bignum, anrm, minmn, 1,
851 $
CALL dlascl(
'G', 0, 0, smlnum, anrm, minmn, 1,
857 work( 1 ) = dcmplx( dble( maxwrk ), zero )