566 SUBROUTINE zgejsv( JOBA, JOBU, JOBV, JOBR, JOBT, JOBP,
567 $ M, N, A, LDA, SVA, U, LDU, V, LDV,
568 $ CWORK, LWORK, RWORK, LRWORK, IWORK, INFO )
576 INTEGER INFO, LDA, LDU, LDV, LWORK, LRWORK, M, N
579 COMPLEX*16 A( lda, * ), U( ldu, * ), V( ldv, * ),
581 DOUBLE PRECISION SVA( n ), RWORK( lrwork )
583 CHARACTER*1 JOBA, JOBP, JOBR, JOBT, JOBU, JOBV
589 DOUBLE PRECISION ZERO, ONE
590 parameter( zero = 0.0d0, one = 1.0d0 )
591 COMPLEX*16 CZERO, CONE
592 parameter( czero = ( 0.0d0, 0.0d0 ), cone = ( 1.0d0, 0.0d0 ) )
596 DOUBLE PRECISION AAPP, AAQQ, AATMAX, AATMIN, BIG, BIG1,
597 $ cond_ok, condr1, condr2, entra, entrat, epsln,
598 $ maxprj, scalem, sconda, sfmin, small, temp1,
599 $ uscal1, uscal2, xsc
600 INTEGER IERR, N1, NR, NUMRANK, p, q, WARNING
601 LOGICAL ALMORT, DEFR, ERREST, GOSCAL, JRACC, KILL, LQUERY,
602 $ lsvec, l2aber, l2kill, l2pert, l2rank, l2tran, noscal,
603 $ rowpiv, rsvec, transp
605 INTEGER OPTWRK, MINWRK, MINRWRK, MINIWRK
606 INTEGER LWCON, LWLQF, LWQP3, LWQRF, LWUNMLQ, LWUNMQR, LWUNMQRM,
607 $ lwsvdj, lwsvdjv, lrwqp3, lrwcon, lrwsvdj, iwoff
608 INTEGER LWRK_ZGELQF, LWRK_ZGEQP3, LWRK_ZGEQP3N, LWRK_ZGEQRF,
609 $ lwrk_zgesvj, lwrk_zgesvjv, lwrk_zgesvju, lwrk_zunmlq,
610 $ lwrk_zunmqr, lwrk_zunmqrm
614 DOUBLE PRECISION RDUMMY(1)
617 INTRINSIC abs, dcmplx, conjg, dlog, max, min, dble, nint, sqrt
620 DOUBLE PRECISION DLAMCH, DZNRM2
621 INTEGER IDAMAX, IZAMAX
623 EXTERNAL idamax, izamax, lsame, dlamch, dznrm2
636 lsvec = lsame( jobu,
'U' ) .OR. lsame( jobu,
'F' )
637 jracc = lsame( jobv,
'J' )
638 rsvec = lsame( jobv,
'V' ) .OR. jracc
639 rowpiv = lsame( joba,
'F' ) .OR. lsame( joba,
'G' )
640 l2rank = lsame( joba,
'R' )
641 l2aber = lsame( joba,
'A' )
642 errest = lsame( joba,
'E' ) .OR. lsame( joba,
'G' )
643 l2tran = lsame( jobt,
'T' ) .AND. ( m .EQ. n )
644 l2kill = lsame( jobr,
'R' )
645 defr = lsame( jobr,
'N' )
646 l2pert = lsame( jobp,
'P' )
648 lquery = ( lwork .EQ. -1 ) .OR. ( lrwork .EQ. -1 )
650 IF ( .NOT.(rowpiv .OR. l2rank .OR. l2aber .OR.
651 $ errest .OR. lsame( joba,
'C' ) ))
THEN 653 ELSE IF ( .NOT.( lsvec .OR. lsame( jobu,
'N' ) .OR.
654 $ ( lsame( jobu,
'W' ) .AND. rsvec .AND. l2tran ) ) )
THEN 656 ELSE IF ( .NOT.( rsvec .OR. lsame( jobv,
'N' ) .OR.
657 $ ( lsame( jobv,
'W' ) .AND. lsvec .AND. l2tran ) ) )
THEN 659 ELSE IF ( .NOT. ( l2kill .OR. defr ) )
THEN 661 ELSE IF ( .NOT. ( lsame(jobt,
'T') .OR. lsame(jobt,
'N') ) )
THEN 663 ELSE IF ( .NOT. ( l2pert .OR. lsame( jobp,
'N' ) ) )
THEN 665 ELSE IF ( m .LT. 0 )
THEN 667 ELSE IF ( ( n .LT. 0 ) .OR. ( n .GT. m ) )
THEN 669 ELSE IF ( lda .LT. m )
THEN 671 ELSE IF ( lsvec .AND. ( ldu .LT. m ) )
THEN 673 ELSE IF ( rsvec .AND. ( ldv .LT. n ) )
THEN 680 IF ( info .EQ. 0 )
THEN 694 lwunmlq = max( 1, n )
695 lwunmqr = max( 1, n )
696 lwunmqrm = max( 1, m )
701 lwsvdj = max( 2 * n, 1 )
702 lwsvdjv = max( 2 * n, 1 )
708 CALL zgeqp3( m, n, a, lda, iwork, cdummy, cdummy, -1,
710 lwrk_zgeqp3 = int( cdummy(1) )
711 CALL zgeqrf( n, n, a, lda, cdummy, cdummy,-1, ierr )
712 lwrk_zgeqrf = int( cdummy(1) )
713 CALL zgelqf( n, n, a, lda, cdummy, cdummy,-1, ierr )
714 lwrk_zgelqf = int( cdummy(1) )
719 IF ( .NOT. (lsvec .OR. rsvec ) )
THEN 723 minwrk = max( n+lwqp3, n**2+lwcon, n+lwqrf, lwsvdj )
725 minwrk = max( n+lwqp3, n+lwqrf, lwsvdj )
728 CALL zgesvj(
'L',
'N',
'N', n, n, a, lda, sva, n, v,
729 $ ldv, cdummy, -1, rdummy, -1, ierr )
730 lwrk_zgesvj = int( cdummy(1) )
732 optwrk = max( n+lwrk_zgeqp3, n**2+lwcon,
733 $ n+lwrk_zgeqrf, lwrk_zgesvj )
735 optwrk = max( n+lwrk_zgeqp3, n+lwrk_zgeqrf,
739 IF ( l2tran .OR. rowpiv )
THEN 741 minrwrk = max( 7, 2*m, lrwqp3, lrwcon, lrwsvdj )
743 minrwrk = max( 7, 2*m, lrwqp3, lrwsvdj )
747 minrwrk = max( 7, lrwqp3, lrwcon, lrwsvdj )
749 minrwrk = max( 7, lrwqp3, lrwsvdj )
752 IF ( rowpiv .OR. l2tran ) miniwrk = miniwrk + m
753 ELSE IF ( rsvec .AND. (.NOT.lsvec) )
THEN 757 minwrk = max( n+lwqp3, lwcon, lwsvdj, n+lwlqf,
758 $ 2*n+lwqrf, n+lwsvdj, n+lwunmlq )
760 minwrk = max( n+lwqp3, lwsvdj, n+lwlqf, 2*n+lwqrf,
761 $ n+lwsvdj, n+lwunmlq )
764 CALL zgesvj(
'L',
'U',
'N', n,n, u, ldu, sva, n, a,
765 $ lda, cdummy, -1, rdummy, -1, ierr )
766 lwrk_zgesvj = int( cdummy(1) )
767 CALL zunmlq(
'L',
'C', n, n, n, a, lda, cdummy,
768 $ v, ldv, cdummy, -1, ierr )
769 lwrk_zunmlq = int( cdummy(1) )
771 optwrk = max( n+lwrk_zgeqp3, lwcon, lwrk_zgesvj,
772 $ n+lwrk_zgelqf, 2*n+lwrk_zgeqrf,
773 $ n+lwrk_zgesvj, n+lwrk_zunmlq )
775 optwrk = max( n+lwrk_zgeqp3, lwrk_zgesvj,n+lwrk_zgelqf,
776 $ 2*n+lwrk_zgeqrf, n+lwrk_zgesvj,
780 IF ( l2tran .OR. rowpiv )
THEN 782 minrwrk = max( 7, 2*m, lrwqp3, lrwsvdj, lrwcon )
784 minrwrk = max( 7, 2*m, lrwqp3, lrwsvdj )
788 minrwrk = max( 7, lrwqp3, lrwsvdj, lrwcon )
790 minrwrk = max( 7, lrwqp3, lrwsvdj )
793 IF ( rowpiv .OR. l2tran ) miniwrk = miniwrk + m
794 ELSE IF ( lsvec .AND. (.NOT.rsvec) )
THEN 798 minwrk = n + max( lwqp3,lwcon,n+lwqrf,lwsvdj,lwunmqrm )
800 minwrk = n + max( lwqp3, n+lwqrf, lwsvdj, lwunmqrm )
803 CALL zgesvj(
'L',
'U',
'N', n,n, u, ldu, sva, n, a,
804 $ lda, cdummy, -1, rdummy, -1, ierr )
805 lwrk_zgesvj = int( cdummy(1) )
806 CALL zunmqr(
'L',
'N', m, n, n, a, lda, cdummy, u,
807 $ ldu, cdummy, -1, ierr )
808 lwrk_zunmqrm = int( cdummy(1) )
810 optwrk = n + max( lwrk_zgeqp3, lwcon, n+lwrk_zgeqrf,
811 $ lwrk_zgesvj, lwrk_zunmqrm )
813 optwrk = n + max( lwrk_zgeqp3, n+lwrk_zgeqrf,
814 $ lwrk_zgesvj, lwrk_zunmqrm )
817 IF ( l2tran .OR. rowpiv )
THEN 819 minrwrk = max( 7, 2*m, lrwqp3, lrwsvdj, lrwcon )
821 minrwrk = max( 7, 2*m, lrwqp3, lrwsvdj )
825 minrwrk = max( 7, lrwqp3, lrwsvdj, lrwcon )
827 minrwrk = max( 7, lrwqp3, lrwsvdj )
830 IF ( rowpiv .OR. l2tran ) miniwrk = miniwrk + m
834 IF ( .NOT. jracc )
THEN 836 minwrk = max( n+lwqp3, n+lwcon, 2*n+n**2+lwcon,
837 $ 2*n+lwqrf, 2*n+lwqp3,
838 $ 2*n+n**2+n+lwlqf, 2*n+n**2+n+n**2+lwcon,
839 $ 2*n+n**2+n+lwsvdj, 2*n+n**2+n+lwsvdjv,
840 $ 2*n+n**2+n+lwunmqr,2*n+n**2+n+lwunmlq,
841 $ n+n**2+lwsvdj, n+lwunmqrm )
843 minwrk = max( n+lwqp3, 2*n+n**2+lwcon,
844 $ 2*n+lwqrf, 2*n+lwqp3,
845 $ 2*n+n**2+n+lwlqf, 2*n+n**2+n+n**2+lwcon,
846 $ 2*n+n**2+n+lwsvdj, 2*n+n**2+n+lwsvdjv,
847 $ 2*n+n**2+n+lwunmqr,2*n+n**2+n+lwunmlq,
848 $ n+n**2+lwsvdj, n+lwunmqrm )
850 miniwrk = miniwrk + n
851 IF ( rowpiv .OR. l2tran ) miniwrk = miniwrk + m
854 minwrk = max( n+lwqp3, n+lwcon, 2*n+lwqrf,
855 $ 2*n+n**2+lwsvdjv, 2*n+n**2+n+lwunmqr,
858 minwrk = max( n+lwqp3, 2*n+lwqrf,
859 $ 2*n+n**2+lwsvdjv, 2*n+n**2+n+lwunmqr,
862 IF ( rowpiv .OR. l2tran ) miniwrk = miniwrk + m
865 CALL zunmqr(
'L',
'N', m, n, n, a, lda, cdummy, u,
866 $ ldu, cdummy, -1, ierr )
867 lwrk_zunmqrm = int( cdummy(1) )
868 CALL zunmqr(
'L',
'N', n, n, n, a, lda, cdummy, u,
869 $ ldu, cdummy, -1, ierr )
870 lwrk_zunmqr = int( cdummy(1) )
871 IF ( .NOT. jracc )
THEN 872 CALL zgeqp3( n,n, a, lda, iwork, cdummy,cdummy, -1,
874 lwrk_zgeqp3n = int( cdummy(1) )
875 CALL zgesvj(
'L',
'U',
'N', n, n, u, ldu, sva,
876 $ n, v, ldv, cdummy, -1, rdummy, -1, ierr )
877 lwrk_zgesvj = int( cdummy(1) )
878 CALL zgesvj(
'U',
'U',
'N', n, n, u, ldu, sva,
879 $ n, v, ldv, cdummy, -1, rdummy, -1, ierr )
880 lwrk_zgesvju = int( cdummy(1) )
881 CALL zgesvj(
'L',
'U',
'V', n, n, u, ldu, sva,
882 $ n, v, ldv, cdummy, -1, rdummy, -1, ierr )
883 lwrk_zgesvjv = int( cdummy(1) )
884 CALL zunmlq(
'L',
'C', n, n, n, a, lda, cdummy,
885 $ v, ldv, cdummy, -1, ierr )
886 lwrk_zunmlq = int( cdummy(1) )
888 optwrk = max( n+lwrk_zgeqp3, n+lwcon,
889 $ 2*n+n**2+lwcon, 2*n+lwrk_zgeqrf,
891 $ 2*n+n**2+n+lwrk_zgelqf,
892 $ 2*n+n**2+n+n**2+lwcon,
893 $ 2*n+n**2+n+lwrk_zgesvj,
894 $ 2*n+n**2+n+lwrk_zgesvjv,
895 $ 2*n+n**2+n+lwrk_zunmqr,
896 $ 2*n+n**2+n+lwrk_zunmlq,
897 $ n+n**2+lwrk_zgesvju,
900 optwrk = max( n+lwrk_zgeqp3,
901 $ 2*n+n**2+lwcon, 2*n+lwrk_zgeqrf,
903 $ 2*n+n**2+n+lwrk_zgelqf,
904 $ 2*n+n**2+n+n**2+lwcon,
905 $ 2*n+n**2+n+lwrk_zgesvj,
906 $ 2*n+n**2+n+lwrk_zgesvjv,
907 $ 2*n+n**2+n+lwrk_zunmqr,
908 $ 2*n+n**2+n+lwrk_zunmlq,
909 $ n+n**2+lwrk_zgesvju,
913 CALL zgesvj(
'L',
'U',
'V', n, n, u, ldu, sva,
914 $ n, v, ldv, cdummy, -1, rdummy, -1, ierr )
915 lwrk_zgesvjv = int( cdummy(1) )
916 CALL zunmqr(
'L',
'N', n, n, n, cdummy, n, cdummy,
917 $ v, ldv, cdummy, -1, ierr )
918 lwrk_zunmqr = int( cdummy(1) )
919 CALL zunmqr(
'L',
'N', m, n, n, a, lda, cdummy, u,
920 $ ldu, cdummy, -1, ierr )
921 lwrk_zunmqrm = int( cdummy(1) )
923 optwrk = max( n+lwrk_zgeqp3, n+lwcon,
924 $ 2*n+lwrk_zgeqrf, 2*n+n**2,
925 $ 2*n+n**2+lwrk_zgesvjv,
926 $ 2*n+n**2+n+lwrk_zunmqr,n+lwrk_zunmqrm )
928 optwrk = max( n+lwrk_zgeqp3, 2*n+lwrk_zgeqrf,
929 $ 2*n+n**2, 2*n+n**2+lwrk_zgesvjv,
930 $ 2*n+n**2+n+lwrk_zunmqr,
935 IF ( l2tran .OR. rowpiv )
THEN 936 minrwrk = max( 7, 2*m, lrwqp3, lrwsvdj, lrwcon )
938 minrwrk = max( 7, lrwqp3, lrwsvdj, lrwcon )
941 minwrk = max( 2, minwrk )
942 optwrk = max( minwrk, optwrk )
943 IF ( lwork .LT. minwrk .AND. (.NOT.lquery) ) info = - 17
944 IF ( lrwork .LT. minrwrk .AND. (.NOT.lquery) ) info = - 19
947 IF ( info .NE. 0 )
THEN 949 CALL xerbla(
'ZGEJSV', - info )
951 ELSE IF ( lquery )
THEN 955 iwork(1) = max( 4, miniwrk )
961 IF ( ( m .EQ. 0 ) .OR. ( n .EQ. 0 ) )
THEN 971 IF ( lsame( jobu,
'F' ) ) n1 = m
978 epsln = dlamch(
'Epsilon')
979 sfmin = dlamch(
'SafeMinimum')
980 small = sfmin / epsln
990 scalem = one / sqrt(dble(m)*dble(n))
996 CALL zlassq( m, a(1,p), 1, aapp, aaqq )
997 IF ( aapp .GT. big )
THEN 999 CALL xerbla(
'ZGEJSV', -info )
1003 IF ( ( aapp .LT. (big / aaqq) ) .AND. noscal )
THEN 1004 sva(p) = aapp * aaqq
1007 sva(p) = aapp * ( aaqq * scalem )
1010 CALL dscal( p-1, scalem, sva, 1 )
1015 IF ( noscal ) scalem = one
1020 aapp = max( aapp, sva(p) )
1021 IF ( sva(p) .NE. zero ) aaqq = min( aaqq, sva(p) )
1026 IF ( aapp .EQ. zero )
THEN 1027 IF ( lsvec )
CALL zlaset(
'G', m, n1, czero, cone, u, ldu )
1028 IF ( rsvec )
CALL zlaset(
'G', n, n, czero, cone, v, ldv )
1031 IF ( errest ) rwork(3) = one
1032 IF ( lsvec .AND. rsvec )
THEN 1052 IF ( aaqq .LE. sfmin )
THEN 1060 IF ( n .EQ. 1 )
THEN 1063 CALL zlascl(
'G',0,0,sva(1),scalem, m,1,a(1,1),lda,ierr )
1064 CALL zlacpy(
'A', m, 1, a, lda, u, ldu )
1066 IF ( n1 .NE. n )
THEN 1067 CALL zgeqrf( m, n, u,ldu, cwork, cwork(n+1),lwork-n,ierr )
1068 CALL zungqr( m,n1,1, u,ldu,cwork,cwork(n+1),lwork-n,ierr )
1069 CALL zcopy( m, a(1,1), 1, u(1,1), 1 )
1075 IF ( sva(1) .LT. (big*scalem) )
THEN 1076 sva(1) = sva(1) / scalem
1079 rwork(1) = one / scalem
1081 IF ( sva(1) .NE. zero )
THEN 1083 IF ( ( sva(1) / scalem) .GE. sfmin )
THEN 1094 IF ( errest ) rwork(3) = one
1095 IF ( lsvec .AND. rsvec )
THEN 1111 IF ( rowpiv .OR. l2tran )
THEN 1122 CALL zlassq( n, a(p,1), lda, xsc, temp1 )
1125 rwork(m+p) = xsc * scalem
1126 rwork(p) = xsc * (scalem*sqrt(temp1))
1127 aatmax = max( aatmax, rwork(p) )
1128 IF (rwork(p) .NE. zero)
1129 $ aatmin = min(aatmin,rwork(p))
1133 rwork(m+p) = scalem*abs( a(p,izamax(n,a(p,1),lda)) )
1134 aatmax = max( aatmax, rwork(m+p) )
1135 aatmin = min( aatmin, rwork(m+p) )
1154 CALL dlassq( n, sva, 1, xsc, temp1 )
1159 big1 = ( ( sva(p) / xsc )**2 ) * temp1
1160 IF ( big1 .NE. zero ) entra = entra + big1 * dlog(big1)
1162 entra = - entra / dlog(dble(n))
1172 big1 = ( ( rwork(p) / xsc )**2 ) * temp1
1173 IF ( big1 .NE. zero ) entrat = entrat + big1 * dlog(big1)
1175 entrat = - entrat / dlog(dble(m))
1180 transp = ( entrat .LT. entra )
1187 DO 1115 p = 1, n - 1
1188 a(p,p) = conjg(a(p,p))
1189 DO 1116 q = p + 1, n
1190 ctemp = conjg(a(q,p))
1191 a(q,p) = conjg(a(p,q))
1195 a(n,n) = conjg(a(n,n))
1231 temp1 = sqrt( big / dble(n) )
1234 CALL dlascl(
'G', 0, 0, aapp, temp1, n, 1, sva, n, ierr )
1235 IF ( aaqq .GT. (aapp * sfmin) )
THEN 1236 aaqq = ( aaqq / aapp ) * temp1
1238 aaqq = ( aaqq * temp1 ) / aapp
1240 temp1 = temp1 * scalem
1241 CALL zlascl(
'G', 0, 0, aapp, temp1, m, n, a, lda, ierr )
1265 IF ( ( aaqq.LT.sqrt(sfmin) ) .AND. lsvec .AND. rsvec )
THEN 1270 IF ( aaqq .LT. xsc )
THEN 1272 IF ( sva(p) .LT. xsc )
THEN 1273 CALL zlaset(
'A', m, 1, czero, czero, a(1,p), lda )
1287 IF ( ( lsvec .AND. rsvec ) .AND. .NOT.( jracc ) )
THEN 1292 DO 1952 p = 1, m - 1
1293 q = idamax( m-p+1, rwork(m+p), 1 ) + p - 1
1295 IF ( p .NE. q )
THEN 1297 rwork(m+p) = rwork(m+q)
1301 CALL zlaswp( n, a, lda, 1, m-1, iwork(iwoff+1), 1 )
1323 CALL zgeqp3( m, n, a, lda, iwork, cwork, cwork(n+1), lwork-n,
1340 temp1 = sqrt(dble(n))*epsln
1342 IF ( abs(a(p,p)) .GE. (temp1*abs(a(1,1))) )
THEN 1349 ELSE IF ( l2rank )
THEN 1355 IF ( ( abs(a(p,p)) .LT. (epsln*abs(a(p-1,p-1))) ) .OR.
1356 $ ( abs(a(p,p)) .LT. small ) .OR.
1357 $ ( l2kill .AND. (abs(a(p,p)) .LT. temp1) ) )
GO TO 3402
1372 IF ( ( abs(a(p,p)) .LT. small ) .OR.
1373 $ ( l2kill .AND. (abs(a(p,p)) .LT. temp1) ) )
GO TO 3302
1381 IF ( nr .EQ. n )
THEN 1384 temp1 = abs(a(p,p)) / sva(iwork(p))
1385 maxprj = min( maxprj, temp1 )
1387 IF ( maxprj**2 .GE. one - dble(n)*epsln ) almort = .true.
1396 IF ( n .EQ. nr )
THEN 1399 CALL zlacpy(
'U', n, n, a, lda, v, ldv )
1401 temp1 = sva(iwork(p))
1402 CALL zdscal( p, one/temp1, v(1,p), 1 )
1405 CALL zpocon(
'U', n, v, ldv, one, temp1,
1406 $ cwork(n+1), rwork, ierr )
1408 CALL zpocon(
'U', n, v, ldv, one, temp1,
1409 $ cwork, rwork, ierr )
1412 ELSE IF ( lsvec )
THEN 1414 CALL zlacpy(
'U', n, n, a, lda, u, ldu )
1416 temp1 = sva(iwork(p))
1417 CALL zdscal( p, one/temp1, u(1,p), 1 )
1419 CALL zpocon(
'U', n, u, ldu, one, temp1,
1420 $ cwork(n+1), rwork, ierr )
1422 CALL zlacpy(
'U', n, n, a, lda, cwork, n )
1427 temp1 = sva(iwork(p))
1429 CALL zdscal( p, one/temp1, cwork((p-1)*n+1), 1 )
1434 CALL zpocon(
'U', n, cwork, n, one, temp1,
1435 $ cwork(n*n+1), rwork, ierr )
1438 IF ( temp1 .NE. zero )
THEN 1439 sconda = one / sqrt(temp1)
1450 l2pert = l2pert .AND. ( abs( a(1,1)/a(nr,nr) ) .GT. sqrt(big1) )
1455 IF ( .NOT. ( rsvec .OR. lsvec ) )
THEN 1460 DO 1946 p = 1, min( n-1, nr )
1461 CALL zcopy( n-p, a(p,p+1), lda, a(p+1,p), 1 )
1462 CALL zlacgv( n-p+1, a(p,p), 1 )
1464 IF ( nr .EQ. n ) a(n,n) = conjg(a(n,n))
1478 IF ( .NOT. almort )
THEN 1482 xsc = epsln / dble(n)
1484 ctemp = dcmplx(xsc*abs(a(q,q)),zero)
1486 IF ( ( (p.GT.q) .AND. (abs(a(p,q)).LE.temp1) )
1487 $ .OR. ( p .LT. q ) )
1493 CALL zlaset(
'U', nr-1,nr-1, czero,czero, a(1,2),lda )
1498 CALL zgeqrf( n,nr, a,lda, cwork, cwork(n+1),lwork-n, ierr )
1501 DO 1948 p = 1, nr - 1
1502 CALL zcopy( nr-p, a(p,p+1), lda, a(p+1,p), 1 )
1503 CALL zlacgv( nr-p+1, a(p,p), 1 )
1514 xsc = epsln / dble(n)
1516 ctemp = dcmplx(xsc*abs(a(q,q)),zero)
1518 IF ( ( (p.GT.q) .AND. (abs(a(p,q)).LE.temp1) )
1519 $ .OR. ( p .LT. q ) )
1525 CALL zlaset(
'U', nr-1, nr-1, czero, czero, a(1,2), lda )
1532 CALL zgesvj(
'L',
'N',
'N', nr, nr, a, lda, sva,
1533 $ n, v, ldv, cwork, lwork, rwork, lrwork, info )
1536 numrank = nint(rwork(2))
1539 ELSE IF ( ( rsvec .AND. ( .NOT. lsvec ) .AND. ( .NOT. jracc ) )
1541 $ ( jracc .AND. ( .NOT. lsvec ) .AND. ( nr .NE. n ) ) )
THEN 1549 CALL zcopy( n-p+1, a(p,p), lda, v(p,p), 1 )
1550 CALL zlacgv( n-p+1, v(p,p), 1 )
1552 CALL zlaset(
'U', nr-1,nr-1, czero, czero, v(1,2), ldv )
1554 CALL zgesvj(
'L',
'U',
'N', n, nr, v, ldv, sva, nr, a, lda,
1555 $ cwork, lwork, rwork, lrwork, info )
1557 numrank = nint(rwork(2))
1564 CALL zlaset(
'L', nr-1,nr-1, czero, czero, a(2,1), lda )
1565 CALL zgelqf( nr,n, a, lda, cwork, cwork(n+1), lwork-n, ierr)
1566 CALL zlacpy(
'L', nr, nr, a, lda, v, ldv )
1567 CALL zlaset(
'U', nr-1,nr-1, czero, czero, v(1,2), ldv )
1568 CALL zgeqrf( nr, nr, v, ldv, cwork(n+1), cwork(2*n+1),
1571 CALL zcopy( nr-p+1, v(p,p), ldv, v(p,p), 1 )
1572 CALL zlacgv( nr-p+1, v(p,p), 1 )
1574 CALL zlaset(
'U', nr-1, nr-1, czero, czero, v(1,2), ldv)
1576 CALL zgesvj(
'L',
'U',
'N', nr, nr, v,ldv, sva, nr, u,
1577 $ ldu, cwork(n+1), lwork-n, rwork, lrwork, info )
1579 numrank = nint(rwork(2))
1580 IF ( nr .LT. n )
THEN 1581 CALL zlaset(
'A',n-nr, nr, czero,czero, v(nr+1,1), ldv )
1582 CALL zlaset(
'A',nr, n-nr, czero,czero, v(1,nr+1), ldv )
1583 CALL zlaset(
'A',n-nr,n-nr,czero,cone, v(nr+1,nr+1),ldv )
1586 CALL zunmlq(
'L',
'C', n, n, nr, a, lda, cwork,
1587 $ v, ldv, cwork(n+1), lwork-n, ierr )
1595 CALL zlapmr( .false., n, n, v, ldv, iwork )
1598 CALL zlacpy(
'A', n, n, v, ldv, u, ldu )
1601 ELSE IF ( jracc .AND. (.NOT. lsvec) .AND. ( nr.EQ. n ) )
THEN 1603 CALL zlaset(
'L', n-1,n-1, czero, czero, a(2,1), lda )
1605 CALL zgesvj(
'U',
'N',
'V', n, n, a, lda, sva, n, v, ldv,
1606 $ cwork, lwork, rwork, lrwork, info )
1608 numrank = nint(rwork(2))
1609 CALL zlapmr( .false., n, n, v, ldv, iwork )
1611 ELSE IF ( lsvec .AND. ( .NOT. rsvec ) )
THEN 1618 CALL zcopy( n-p+1, a(p,p), lda, u(p,p), 1 )
1619 CALL zlacgv( n-p+1, u(p,p), 1 )
1621 CALL zlaset(
'U', nr-1, nr-1, czero, czero, u(1,2), ldu )
1623 CALL zgeqrf( n, nr, u, ldu, cwork(n+1), cwork(2*n+1),
1626 DO 1967 p = 1, nr - 1
1627 CALL zcopy( nr-p, u(p,p+1), ldu, u(p+1,p), 1 )
1628 CALL zlacgv( n-p+1, u(p,p), 1 )
1630 CALL zlaset(
'U', nr-1, nr-1, czero, czero, u(1,2), ldu )
1632 CALL zgesvj(
'L',
'U',
'N', nr,nr, u, ldu, sva, nr, a,
1633 $ lda, cwork(n+1), lwork-n, rwork, lrwork, info )
1635 numrank = nint(rwork(2))
1637 IF ( nr .LT. m )
THEN 1638 CALL zlaset(
'A', m-nr, nr,czero, czero, u(nr+1,1), ldu )
1639 IF ( nr .LT. n1 )
THEN 1640 CALL zlaset(
'A',nr, n1-nr, czero, czero, u(1,nr+1),ldu )
1641 CALL zlaset(
'A',m-nr,n1-nr,czero,cone,u(nr+1,nr+1),ldu )
1645 CALL zunmqr(
'L',
'N', m, n1, n, a, lda, cwork, u,
1646 $ ldu, cwork(n+1), lwork-n, ierr )
1649 $
CALL zlaswp( n1, u, ldu, 1, m-1, iwork(iwoff+1), -1 )
1652 xsc = one / dznrm2( m, u(1,p), 1 )
1653 CALL zdscal( m, xsc, u(1,p), 1 )
1657 CALL zlacpy(
'A', n, n, u, ldu, v, ldv )
1664 IF ( .NOT. jracc )
THEN 1666 IF ( .NOT. almort )
THEN 1676 CALL zcopy( n-p+1, a(p,p), lda, v(p,p), 1 )
1677 CALL zlacgv( n-p+1, v(p,p), 1 )
1695 ctemp = dcmplx(xsc*abs( v(q,q) ),zero)
1697 IF ( ( p .GT. q ) .AND. ( abs(v(p,q)) .LE. temp1 )
1698 $ .OR. ( p .LT. q ) )
1701 IF ( p .LT. q ) v(p,q) = - v(p,q)
1705 CALL zlaset(
'U', nr-1, nr-1, czero, czero, v(1,2), ldv )
1712 CALL zlacpy(
'L', nr, nr, v, ldv, cwork(2*n+1), nr )
1714 temp1 = dznrm2(nr-p+1,cwork(2*n+(p-1)*nr+p),1)
1715 CALL zdscal(nr-p+1,one/temp1,cwork(2*n+(p-1)*nr+p),1)
1717 CALL zpocon(
'L',nr,cwork(2*n+1),nr,one,temp1,
1718 $ cwork(2*n+nr*nr+1),rwork,ierr)
1719 condr1 = one / sqrt(temp1)
1725 cond_ok = sqrt(sqrt(dble(nr)))
1728 IF ( condr1 .LT. cond_ok )
THEN 1733 CALL zgeqrf( n, nr, v, ldv, cwork(n+1), cwork(2*n+1),
1737 xsc = sqrt(small)/epsln
1739 DO 3958 q = 1, p - 1
1740 ctemp=dcmplx(xsc*min(abs(v(p,p)),abs(v(q,q))),
1742 IF ( abs(v(q,p)) .LE. temp1 )
1750 $
CALL zlacpy(
'A', n, nr, v, ldv, cwork(2*n+1), n )
1754 DO 1969 p = 1, nr - 1
1755 CALL zcopy( nr-p, v(p,p+1), ldv, v(p+1,p), 1 )
1756 CALL zlacgv(nr-p+1, v(p,p), 1 )
1758 v(nr,nr)=conjg(v(nr,nr))
1775 CALL zgeqp3( n, nr, v, ldv, iwork(n+1), cwork(n+1),
1776 $ cwork(2*n+1), lwork-2*n, rwork, ierr )
1782 DO 3968 q = 1, p - 1
1783 ctemp=dcmplx(xsc*min(abs(v(p,p)),abs(v(q,q))),
1785 IF ( abs(v(q,p)) .LE. temp1 )
1792 CALL zlacpy(
'A', n, nr, v, ldv, cwork(2*n+1), n )
1797 DO 8971 q = 1, p - 1
1798 ctemp=dcmplx(xsc*min(abs(v(p,p)),abs(v(q,q))),
1805 CALL zlaset(
'L',nr-1,nr-1,czero,czero,v(2,1),ldv )
1808 CALL zgelqf( nr, nr, v, ldv, cwork(2*n+n*nr+1),
1809 $ cwork(2*n+n*nr+nr+1), lwork-2*n-n*nr-nr, ierr )
1811 CALL zlacpy(
'L',nr,nr,v,ldv,cwork(2*n+n*nr+nr+1),nr )
1813 temp1 = dznrm2( p, cwork(2*n+n*nr+nr+p), nr )
1814 CALL zdscal( p, one/temp1, cwork(2*n+n*nr+nr+p), nr )
1816 CALL zpocon(
'L',nr,cwork(2*n+n*nr+nr+1),nr,one,temp1,
1817 $ cwork(2*n+n*nr+nr+nr*nr+1),rwork,ierr )
1818 condr2 = one / sqrt(temp1)
1821 IF ( condr2 .GE. cond_ok )
THEN 1826 CALL zlacpy(
'U', nr, nr, v, ldv, cwork(2*n+1), n )
1836 ctemp = xsc * v(q,q)
1837 DO 4969 p = 1, q - 1
1843 CALL zlaset(
'U', nr-1,nr-1, czero,czero, v(1,2), ldv )
1852 IF ( condr1 .LT. cond_ok )
THEN 1854 CALL zgesvj(
'L',
'U',
'N',nr,nr,v,ldv,sva,nr,u, ldu,
1855 $ cwork(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,rwork,
1858 numrank = nint(rwork(2))
1860 CALL zcopy( nr, v(1,p), 1, u(1,p), 1 )
1861 CALL zdscal( nr, sva(p), v(1,p), 1 )
1866 IF ( nr .EQ. n )
THEN 1871 CALL ztrsm(
'L',
'U',
'N',
'N', nr,nr,cone, a,lda, v,ldv)
1877 CALL ztrsm(
'L',
'U',
'C',
'N',nr,nr,cone,cwork(2*n+1),
1879 IF ( nr .LT. n )
THEN 1880 CALL zlaset(
'A',n-nr,nr,czero,czero,v(nr+1,1),ldv)
1881 CALL zlaset(
'A',nr,n-nr,czero,czero,v(1,nr+1),ldv)
1882 CALL zlaset(
'A',n-nr,n-nr,czero,cone,v(nr+1,nr+1),ldv)
1884 CALL zunmqr(
'L',
'N',n,n,nr,cwork(2*n+1),n,cwork(n+1),
1885 $ v,ldv,cwork(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr)
1888 ELSE IF ( condr2 .LT. cond_ok )
THEN 1894 CALL zgesvj(
'L',
'U',
'N', nr, nr, v, ldv, sva, nr, u,
1895 $ ldu, cwork(2*n+n*nr+nr+1), lwork-2*n-n*nr-nr,
1896 $ rwork, lrwork, info )
1898 numrank = nint(rwork(2))
1900 CALL zcopy( nr, v(1,p), 1, u(1,p), 1 )
1901 CALL zdscal( nr, sva(p), u(1,p), 1 )
1903 CALL ztrsm(
'L',
'U',
'N',
'N',nr,nr,cone,cwork(2*n+1),n,
1908 cwork(2*n+n*nr+nr+iwork(n+p)) = u(p,q)
1911 u(p,q) = cwork(2*n+n*nr+nr+p)
1914 IF ( nr .LT. n )
THEN 1915 CALL zlaset(
'A',n-nr,nr,czero,czero,v(nr+1,1),ldv )
1916 CALL zlaset(
'A',nr,n-nr,czero,czero,v(1,nr+1),ldv )
1917 CALL zlaset(
'A',n-nr,n-nr,czero,cone,v(nr+1,nr+1),ldv)
1919 CALL zunmqr(
'L',
'N',n,n,nr,cwork(2*n+1),n,cwork(n+1),
1920 $ v,ldv,cwork(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr )
1933 CALL zgesvj(
'L',
'U',
'V', nr, nr, v, ldv, sva, nr, u,
1934 $ ldu, cwork(2*n+n*nr+nr+1), lwork-2*n-n*nr-nr,
1935 $ rwork, lrwork, info )
1937 numrank = nint(rwork(2))
1938 IF ( nr .LT. n )
THEN 1939 CALL zlaset(
'A',n-nr,nr,czero,czero,v(nr+1,1),ldv )
1940 CALL zlaset(
'A',nr,n-nr,czero,czero,v(1,nr+1),ldv )
1941 CALL zlaset(
'A',n-nr,n-nr,czero,cone,v(nr+1,nr+1),ldv)
1943 CALL zunmqr(
'L',
'N',n,n,nr,cwork(2*n+1),n,cwork(n+1),
1944 $ v,ldv,cwork(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr )
1946 CALL zunmlq(
'L',
'C', nr, nr, nr, cwork(2*n+1), n,
1947 $ cwork(2*n+n*nr+1), u, ldu, cwork(2*n+n*nr+nr+1),
1948 $ lwork-2*n-n*nr-nr, ierr )
1951 cwork(2*n+n*nr+nr+iwork(n+p)) = u(p,q)
1954 u(p,q) = cwork(2*n+n*nr+nr+p)
1964 temp1 = sqrt(dble(n)) * epsln
1967 cwork(2*n+n*nr+nr+iwork(p)) = v(p,q)
1970 v(p,q) = cwork(2*n+n*nr+nr+p)
1972 xsc = one / dznrm2( n, v(1,q), 1 )
1973 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1974 $
CALL zdscal( n, xsc, v(1,q), 1 )
1978 IF ( nr .LT. m )
THEN 1979 CALL zlaset(
'A', m-nr, nr, czero, czero, u(nr+1,1), ldu)
1980 IF ( nr .LT. n1 )
THEN 1981 CALL zlaset(
'A',nr,n1-nr,czero,czero,u(1,nr+1),ldu)
1982 CALL zlaset(
'A',m-nr,n1-nr,czero,cone,
1990 CALL zunmqr(
'L',
'N', m, n1, n, a, lda, cwork, u,
1991 $ ldu, cwork(n+1), lwork-n, ierr )
1994 temp1 = sqrt(dble(m)) * epsln
1996 xsc = one / dznrm2( m, u(1,p), 1 )
1997 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1998 $
CALL zdscal( m, xsc, u(1,p), 1 )
2005 $
CALL zlaswp( n1, u, ldu, 1, m-1, iwork(iwoff+1), -1 )
2012 CALL zlacpy(
'U', n, n, a, lda, cwork(n+1), n )
2016 ctemp = xsc * cwork( n + (p-1)*n + p )
2017 DO 5971 q = 1, p - 1
2020 cwork(n+(q-1)*n+p)=-ctemp
2024 CALL zlaset(
'L',n-1,n-1,czero,czero,cwork(n+2),n )
2027 CALL zgesvj(
'U',
'U',
'N', n, n, cwork(n+1), n, sva,
2028 $ n, u, ldu, cwork(n+n*n+1), lwork-n-n*n, rwork, lrwork,
2032 numrank = nint(rwork(2))
2034 CALL zcopy( n, cwork(n+(p-1)*n+1), 1, u(1,p), 1 )
2035 CALL zdscal( n, sva(p), cwork(n+(p-1)*n+1), 1 )
2038 CALL ztrsm(
'L',
'U',
'N',
'N', n, n,
2039 $ cone, a, lda, cwork(n+1), n )
2041 CALL zcopy( n, cwork(n+p), n, v(iwork(p),1), ldv )
2043 temp1 = sqrt(dble(n))*epsln
2045 xsc = one / dznrm2( n, v(1,p), 1 )
2046 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
2047 $
CALL zdscal( n, xsc, v(1,p), 1 )
2052 IF ( n .LT. m )
THEN 2053 CALL zlaset(
'A', m-n, n, czero, czero, u(n+1,1), ldu )
2054 IF ( n .LT. n1 )
THEN 2055 CALL zlaset(
'A',n, n1-n, czero, czero, u(1,n+1),ldu)
2056 CALL zlaset(
'A',m-n,n1-n, czero, cone,u(n+1,n+1),ldu)
2059 CALL zunmqr(
'L',
'N', m, n1, n, a, lda, cwork, u,
2060 $ ldu, cwork(n+1), lwork-n, ierr )
2061 temp1 = sqrt(dble(m))*epsln
2063 xsc = one / dznrm2( m, u(1,p), 1 )
2064 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
2065 $
CALL zdscal( m, xsc, u(1,p), 1 )
2069 $
CALL zlaswp( n1, u, ldu, 1, m-1, iwork(iwoff+1), -1 )
2089 CALL zcopy( n-p+1, a(p,p), lda, v(p,p), 1 )
2090 CALL zlacgv( n-p+1, v(p,p), 1 )
2094 xsc = sqrt(small/epsln)
2096 ctemp = dcmplx(xsc*abs( v(q,q) ),zero)
2098 IF ( ( p .GT. q ) .AND. ( abs(v(p,q)) .LE. temp1 )
2099 $ .OR. ( p .LT. q ) )
2102 IF ( p .LT. q ) v(p,q) = - v(p,q)
2106 CALL zlaset(
'U', nr-1, nr-1, czero, czero, v(1,2), ldv )
2109 CALL zgeqrf( n, nr, v, ldv, cwork(n+1), cwork(2*n+1),
2111 CALL zlacpy(
'L', n, nr, v, ldv, cwork(2*n+1), n )
2114 CALL zcopy( nr-p+1, v(p,p), ldv, u(p,p), 1 )
2115 CALL zlacgv( nr-p+1, u(p,p), 1 )
2119 xsc = sqrt(small/epsln)
2121 DO 9971 p = 1, q - 1
2122 ctemp = dcmplx(xsc * min(abs(u(p,p)),abs(u(q,q))),
2129 CALL zlaset(
'U', nr-1, nr-1, czero, czero, u(1,2), ldu )
2132 CALL zgesvj(
'L',
'U',
'V', nr, nr, u, ldu, sva,
2133 $ n, v, ldv, cwork(2*n+n*nr+1), lwork-2*n-n*nr,
2134 $ rwork, lrwork, info )
2136 numrank = nint(rwork(2))
2138 IF ( nr .LT. n )
THEN 2139 CALL zlaset(
'A',n-nr,nr,czero,czero,v(nr+1,1),ldv )
2140 CALL zlaset(
'A',nr,n-nr,czero,czero,v(1,nr+1),ldv )
2141 CALL zlaset(
'A',n-nr,n-nr,czero,cone,v(nr+1,nr+1),ldv )
2144 CALL zunmqr(
'L',
'N',n,n,nr,cwork(2*n+1),n,cwork(n+1),
2145 $ v,ldv,cwork(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr )
2151 temp1 = sqrt(dble(n)) * epsln
2154 cwork(2*n+n*nr+nr+iwork(p)) = v(p,q)
2157 v(p,q) = cwork(2*n+n*nr+nr+p)
2159 xsc = one / dznrm2( n, v(1,q), 1 )
2160 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
2161 $
CALL zdscal( n, xsc, v(1,q), 1 )
2167 IF ( nr .LT. m )
THEN 2168 CALL zlaset(
'A', m-nr, nr, czero, czero, u(nr+1,1), ldu )
2169 IF ( nr .LT. n1 )
THEN 2170 CALL zlaset(
'A',nr, n1-nr, czero, czero, u(1,nr+1),ldu)
2171 CALL zlaset(
'A',m-nr,n1-nr, czero, cone,u(nr+1,nr+1),ldu)
2175 CALL zunmqr(
'L',
'N', m, n1, n, a, lda, cwork, u,
2176 $ ldu, cwork(n+1), lwork-n, ierr )
2179 $
CALL zlaswp( n1, u, ldu, 1, m-1, iwork(iwoff+1), -1 )
2186 CALL zswap( n, u(1,p), 1, v(1,p), 1 )
2195 IF ( uscal2 .LE. (big/sva(1))*uscal1 )
THEN 2196 CALL dlascl(
'G', 0, 0, uscal1, uscal2, nr, 1, sva, n, ierr )
2201 IF ( nr .LT. n )
THEN 2207 rwork(1) = uscal2 * scalem
2209 IF ( errest ) rwork(3) = sconda
2210 IF ( lsvec .AND. rsvec )
THEN subroutine zlapmr(FORWRD, M, N, X, LDX, K)
ZLAPMR rearranges rows of a matrix as specified by a permutation vector.
subroutine zdscal(N, DA, ZX, INCX)
ZDSCAL
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine zunmlq(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMLQ
subroutine ztrsm(SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, B, LDB)
ZTRSM
subroutine zgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
ZGEQRF
subroutine zpocon(UPLO, N, A, LDA, ANORM, RCOND, WORK, RWORK, INFO)
ZPOCON
subroutine zcopy(N, ZX, INCX, ZY, INCY)
ZCOPY
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 zgesvj(JOBA, JOBU, JOBV, M, N, A, LDA, SVA, MV, V, LDV, CWORK, LWORK, RWORK, LRWORK, INFO)
ZGESVJ
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 dscal(N, DA, DX, INCX)
DSCAL
subroutine zlacgv(N, X, INCX)
ZLACGV conjugates a complex vector.
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 zgejsv(JOBA, JOBU, JOBV, JOBR, JOBT, JOBP, M, N, A, LDA, SVA, U, LDU, V, LDV, CWORK, LWORK, RWORK, LRWORK, IWORK, INFO)
ZGEJSV
subroutine zlaswp(N, A, LDA, K1, K2, IPIV, INCX)
ZLASWP performs a series of row interchanges on a general rectangular matrix.
subroutine zgeqp3(M, N, A, LDA, JPVT, TAU, WORK, LWORK, RWORK, INFO)
ZGEQP3
subroutine zungqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
ZUNGQR
subroutine zswap(N, ZX, INCX, ZY, INCY)
ZSWAP