269 SUBROUTINE zgesvdx( 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
281 DOUBLE PRECISION VL, VU
285 DOUBLE PRECISION S( * ), RWORK( * )
286 COMPLEX*16 A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
293 COMPLEX*16 CZERO, CONE
294 PARAMETER ( CZERO = ( 0.0d0, 0.0d0 ),
295 $ cone = ( 1.0d0, 0.0d0 ) )
296 DOUBLE PRECISION ZERO, ONE
297 PARAMETER ( ZERO = 0.0d0, one = 1.0d0 )
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 DOUBLE PRECISION ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
308 DOUBLE PRECISION DUM( 1 )
317 DOUBLE PRECISION DLAMCH, ZLANGE
318 EXTERNAL lsame, ilaenv, dlamch, zlange
321 INTRINSIC max, min, sqrt
329 abstol = 2*dlamch(
'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,
'ZGESVD', jobu // jobvt, m, n, 0, 0 )
401 IF( m.GE.mnthr )
THEN
406 maxwrk = n + n*ilaenv(1,
'ZGEQRF',
' ',m,n,-1,-1)
408 $ n*n+2*n+2*n*ilaenv(1,
'ZGEBRD',
' ',n,n,-1,-1))
409 IF (wantu .OR. wantvt)
THEN
411 $ n*n+2*n+n*ilaenv(1,
'ZUNMQR',
'LN',n,n,n,-1))
418 maxwrk = 2*n + (m+n)*ilaenv(1,
'ZGEBRD',
' ',m,n,-1,-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, 0 )
426 IF( n.GE.mnthr )
THEN
431 maxwrk = m + m*ilaenv(1,
'ZGELQF',
' ',m,n,-1,-1)
433 $ m*m+2*m+2*m*ilaenv(1,
'ZGEBRD',
' ',m,m,-1,-1))
434 IF (wantu .OR. wantvt)
THEN
436 $ m*m+2*m+m*ilaenv(1,
'ZUNMQR',
'LN',m,m,m,-1))
444 maxwrk = 2*m + (m+n)*ilaenv(1,
'ZGEBRD',
' ',m,n,-1,-1)
445 IF (wantu .OR. wantvt)
THEN
447 $ 2*m+m*ilaenv(1,
'ZUNMQR',
'LN',m,m,m,-1))
452 maxwrk = max( maxwrk, minwrk )
453 work( 1 ) = dcmplx( dble( maxwrk ), zero )
455 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
461 CALL xerbla(
'ZGESVDX', -info )
463 ELSE IF( lquery )
THEN
469 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
492 smlnum = sqrt( dlamch(
'S' ) ) / eps
493 bignum = one / smlnum
497 anrm = zlange(
'M', m, n, a, lda, dum )
499 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
501 CALL zlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
502 ELSE IF( anrm.GT.bignum )
THEN
504 CALL zlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
513 IF( m.GE.mnthr )
THEN
525 CALL zgeqrf( m, n, a, lda, work( itau ), work( itemp ),
526 $ lwork-itemp+1, info )
538 CALL zlacpy(
'U', n, n, a, lda, work( iqrf ), n )
539 CALL zlaset(
'L', n-1, n-1, czero, czero,
540 $ work( iqrf+1 ), n )
541 CALL zgebrd( 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 dbdsvdx(
'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 ) = dcmplx( rwork( k ), zero )
565 CALL zlaset(
'A', m-n, ns, czero, czero, u( n+1,1 ), ldu)
570 CALL zunmbr(
'Q',
'L',
'N', n, ns, n, work( iqrf ), n,
571 $ work( itauq ), u, ldu, work( itemp ),
572 $ lwork-itemp+1, info )
577 CALL zunmqr(
'L',
'N', m, ns, n, a, lda,
578 $ work( itau ), u, ldu, work( itemp ),
579 $ lwork-itemp+1, info )
588 vt( i, j ) = dcmplx( rwork( k ), zero )
597 CALL zunmbr(
'P',
'R',
'C', ns, n, n, work( iqrf ), n,
598 $ work( itaup ), vt, ldvt, work( itemp ),
599 $ lwork-itemp+1, info )
617 CALL zgebrd( 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 dbdsvdx(
'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 ) = dcmplx( rwork( k ), zero )
641 CALL zlaset(
'A', m-n, ns, czero, czero, u( n+1,1 ), ldu)
646 CALL zunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
647 $ work( itauq ), u, ldu, work( itemp ),
648 $ lwork-itemp+1, ierr )
657 vt( i, j ) = dcmplx( rwork( k ), zero )
666 CALL zunmbr(
'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 zgelqf( m, n, a, lda, work( itau ), work( itemp ),
689 $ lwork-itemp+1, info )
701 CALL zlacpy(
'L', m, m, a, lda, work( ilqf ), m )
702 CALL zlaset(
'U', m-1, m-1, czero, czero,
703 $ work( ilqf+m ), m )
704 CALL zgebrd( 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 dbdsvdx(
'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 ) = dcmplx( rwork( k ), zero )
732 CALL zunmbr(
'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 ) = dcmplx( rwork( k ), zero )
748 CALL zlaset(
'A', ns, n-m, czero, czero,
749 $ vt( 1,m+1 ), ldvt )
754 CALL zunmbr(
'P',
'R',
'C', ns, m, m, work( ilqf ), m,
755 $ work( itaup ), vt, ldvt, work( itemp ),
756 $ lwork-itemp+1, info )
761 CALL zunmlq(
'R',
'N', ns, n, m, a, lda,
762 $ work( itau ), vt, ldvt, work( itemp ),
763 $ lwork-itemp+1, info )
781 CALL zgebrd( 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 dbdsvdx(
'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 ) = dcmplx( rwork( k ), zero )
809 CALL zunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
810 $ work( itauq ), u, ldu, work( itemp ),
811 $ lwork-itemp+1, info )
820 vt( i, j ) = dcmplx( rwork( k ), zero )
825 CALL zlaset(
'A', ns, n-m, czero, czero,
826 $ vt( 1,m+1 ), ldvt )
831 CALL zunmbr(
'P',
'R',
'C', ns, n, m, a, lda,
832 $ work( itaup ), vt, ldvt, work( itemp ),
833 $ lwork-itemp+1, info )
842 $
CALL dlascl(
'G', 0, 0, bignum, anrm, minmn, 1,
845 $
CALL dlascl(
'G', 0, 0, smlnum, anrm, minmn, 1,
851 work( 1 ) = dcmplx( dble( maxwrk ), zero )