567 SUBROUTINE cgejsv( JOBA, JOBU, JOBV, JOBR, JOBT, JOBP,
568 $ m, n, a, lda, sva, u, ldu, v, ldv,
569 $ cwork, lwork, rwork, lrwork, iwork, info )
578 INTEGER INFO, LDA, LDU, LDV, LWORK, LRWORK, M, N
581 COMPLEX A( lda, * ), U( ldu, * ), V( ldv, * ), CWORK( lwork )
582 REAL SVA( n ), RWORK( lrwork )
584 CHARACTER*1 JOBA, JOBP, JOBR, JOBT, JOBU, JOBV
591 parameter( zero = 0.0e0, one = 1.0e0 )
593 parameter( czero = ( 0.0e0, 0.0e0 ), cone = ( 1.0e0, 0.0e0 ) )
597 REAL AAPP, AAQQ, AATMAX, AATMIN, BIG, BIG1, COND_OK,
598 $ condr1, condr2, entra, entrat, epsln, maxprj, scalem,
599 $ sconda, sfmin, small, temp1, 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_CGELQF, LWRK_CGEQP3, LWRK_CGEQP3N, LWRK_CGEQRF,
609 $ lwrk_cgesvj, lwrk_cgesvjv, lwrk_cgesvju, lwrk_cunmlq,
610 $ lwrk_cunmqr, lwrk_cunmqrm
617 INTRINSIC abs, cmplx, conjg, alog, max, min,
REAL, NINT, SQRT
621 INTEGER ISAMAX, ICAMAX
623 EXTERNAL isamax, icamax, lsame, slamch, scnrm2
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 cgeqp3( m, n, a, lda, iwork, cdummy, cdummy, -1,
710 lwrk_cgeqp3 = cdummy(1)
711 CALL cgeqrf( n, n, a, lda, cdummy, cdummy,-1, ierr )
712 lwrk_cgeqrf = cdummy(1)
713 CALL cgelqf( n, n, a, lda, cdummy, cdummy,-1, ierr )
714 lwrk_cgelqf = 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 cgesvj(
'L',
'N',
'N', n, n, a, lda, sva, n, v,
729 $ ldv, cdummy, -1, rdummy, -1, ierr )
730 lwrk_cgesvj = cdummy(1)
732 optwrk = max( n+lwrk_cgeqp3, n**2+lwcon,
733 $ n+lwrk_cgeqrf, lwrk_cgesvj )
735 optwrk = max( n+lwrk_cgeqp3, n+lwrk_cgeqrf,
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 cgesvj(
'L',
'U',
'N', n,n, u, ldu, sva, n, a,
765 $ lda, cdummy, -1, rdummy, -1, ierr )
766 lwrk_cgesvj = cdummy(1)
767 CALL cunmlq(
'L',
'C', n, n, n, a, lda, cdummy,
768 $ v, ldv, cdummy, -1, ierr )
769 lwrk_cunmlq = cdummy(1)
771 optwrk = max( n+lwrk_cgeqp3, lwcon, lwrk_cgesvj,
772 $ n+lwrk_cgelqf, 2*n+lwrk_cgeqrf,
773 $ n+lwrk_cgesvj, n+lwrk_cunmlq )
775 optwrk = max( n+lwrk_cgeqp3, lwrk_cgesvj,n+lwrk_cgelqf,
776 $ 2*n+lwrk_cgeqrf, n+lwrk_cgesvj,
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 cgesvj(
'L',
'U',
'N', n,n, u, ldu, sva, n, a,
804 $ lda, cdummy, -1, rdummy, -1, ierr )
805 lwrk_cgesvj = cdummy(1)
806 CALL cunmqr(
'L',
'N', m, n, n, a, lda, cdummy, u,
807 $ ldu, cdummy, -1, ierr )
808 lwrk_cunmqrm = cdummy(1)
810 optwrk = n + max( lwrk_cgeqp3, lwcon, n+lwrk_cgeqrf,
811 $ lwrk_cgesvj, lwrk_cunmqrm )
813 optwrk = n + max( lwrk_cgeqp3, n+lwrk_cgeqrf,
814 $ lwrk_cgesvj, lwrk_cunmqrm )
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 cunmqr(
'L',
'N', m, n, n, a, lda, cdummy, u,
866 $ ldu, cdummy, -1, ierr )
867 lwrk_cunmqrm = cdummy(1)
868 CALL cunmqr(
'L',
'N', n, n, n, a, lda, cdummy, u,
869 $ ldu, cdummy, -1, ierr )
870 lwrk_cunmqr = cdummy(1)
871 IF ( .NOT. jracc )
THEN
872 CALL cgeqp3( n,n, a, lda, iwork, cdummy,cdummy, -1,
874 lwrk_cgeqp3n = cdummy(1)
875 CALL cgesvj(
'L',
'U',
'N', n, n, u, ldu, sva,
876 $ n, v, ldv, cdummy, -1, rdummy, -1, ierr )
877 lwrk_cgesvj = cdummy(1)
878 CALL cgesvj(
'U',
'U',
'N', n, n, u, ldu, sva,
879 $ n, v, ldv, cdummy, -1, rdummy, -1, ierr )
880 lwrk_cgesvju = cdummy(1)
881 CALL cgesvj(
'L',
'U',
'V', n, n, u, ldu, sva,
882 $ n, v, ldv, cdummy, -1, rdummy, -1, ierr )
883 lwrk_cgesvjv = cdummy(1)
884 CALL cunmlq(
'L',
'C', n, n, n, a, lda, cdummy,
885 $ v, ldv, cdummy, -1, ierr )
886 lwrk_cunmlq = cdummy(1)
888 optwrk = max( n+lwrk_cgeqp3, n+lwcon,
889 $ 2*n+n**2+lwcon, 2*n+lwrk_cgeqrf,
891 $ 2*n+n**2+n+lwrk_cgelqf,
892 $ 2*n+n**2+n+n**2+lwcon,
893 $ 2*n+n**2+n+lwrk_cgesvj,
894 $ 2*n+n**2+n+lwrk_cgesvjv,
895 $ 2*n+n**2+n+lwrk_cunmqr,
896 $ 2*n+n**2+n+lwrk_cunmlq,
897 $ n+n**2+lwrk_cgesvju,
900 optwrk = max( n+lwrk_cgeqp3,
901 $ 2*n+n**2+lwcon, 2*n+lwrk_cgeqrf,
903 $ 2*n+n**2+n+lwrk_cgelqf,
904 $ 2*n+n**2+n+n**2+lwcon,
905 $ 2*n+n**2+n+lwrk_cgesvj,
906 $ 2*n+n**2+n+lwrk_cgesvjv,
907 $ 2*n+n**2+n+lwrk_cunmqr,
908 $ 2*n+n**2+n+lwrk_cunmlq,
909 $ n+n**2+lwrk_cgesvju,
913 CALL cgesvj(
'L',
'U',
'V', n, n, u, ldu, sva,
914 $ n, v, ldv, cdummy, -1, rdummy, -1, ierr )
915 lwrk_cgesvjv = cdummy(1)
916 CALL cunmqr(
'L',
'N', n, n, n, cdummy, n, cdummy,
917 $ v, ldv, cdummy, -1, ierr )
918 lwrk_cunmqr = cdummy(1)
919 CALL cunmqr(
'L',
'N', m, n, n, a, lda, cdummy, u,
920 $ ldu, cdummy, -1, ierr )
921 lwrk_cunmqrm = cdummy(1)
923 optwrk = max( n+lwrk_cgeqp3, n+lwcon,
924 $ 2*n+lwrk_cgeqrf, 2*n+n**2,
925 $ 2*n+n**2+lwrk_cgesvjv,
926 $ 2*n+n**2+n+lwrk_cunmqr,n+lwrk_cunmqrm )
928 optwrk = max( n+lwrk_cgeqp3, 2*n+lwrk_cgeqrf,
929 $ 2*n+n**2, 2*n+n**2+lwrk_cgesvjv,
930 $ 2*n+n**2+n+lwrk_cunmqr,
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( 2, 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(
'CGEJSV', - 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 = slamch(
'Epsilon')
979 sfmin = slamch(
'SafeMinimum')
980 small = sfmin / epsln
990 scalem = one / sqrt(
REAL(m)*
REAL(n))
996 CALL classq( m, a(1,p), 1, aapp, aaqq )
997 IF ( aapp .GT. big )
THEN
999 CALL xerbla(
'CGEJSV', -info )
1003 IF ( ( aapp .LT. (big / aaqq) ) .AND. noscal )
THEN
1004 sva(p) = aapp * aaqq
1007 sva(p) = aapp * ( aaqq * scalem )
1010 CALL sscal( 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 claset(
'G', m, n1, czero, cone, u, ldu )
1028 IF ( rsvec )
CALL claset(
'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 clascl(
'G',0,0,sva(1),scalem, m,1,a(1,1),lda,ierr )
1064 CALL clacpy(
'A', m, 1, a, lda, u, ldu )
1066 IF ( n1 .NE. n )
THEN
1067 CALL cgeqrf( m, n, u,ldu, cwork, cwork(n+1),lwork-n,ierr )
1068 CALL cungqr( m,n1,1, u,ldu,cwork,cwork(n+1),lwork-n,ierr )
1069 CALL ccopy( 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 classq( 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,icamax(n,a(p,1),lda)) )
1134 aatmax = max( aatmax, rwork(m+p) )
1135 aatmin = min( aatmin, rwork(m+p) )
1154 CALL slassq( n, sva, 1, xsc, temp1 )
1159 big1 = ( ( sva(p) / xsc )**2 ) * temp1
1160 IF ( big1 .NE. zero ) entra = entra + big1 * alog(big1)
1162 entra = - entra / alog(
REAL(n))
1172 big1 = ( ( rwork(p) / xsc )**2 ) * temp1
1173 IF ( big1 .NE. zero ) entrat = entrat + big1 * alog(big1)
1175 entrat = - entrat / alog(
REAL(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))
1229 temp1 = sqrt( big /
REAL(N) )
1235 CALL slascl(
'G', 0, 0, aapp, temp1, n, 1, sva, n, ierr )
1236 IF ( aaqq .GT. (aapp * sfmin) )
THEN
1237 aaqq = ( aaqq / aapp ) * temp1
1239 aaqq = ( aaqq * temp1 ) / aapp
1241 temp1 = temp1 * scalem
1242 CALL clascl(
'G', 0, 0, aapp, temp1, m, n, a, lda, ierr )
1266 IF ( ( aaqq.LT.sqrt(sfmin) ) .AND. lsvec .AND. rsvec )
THEN
1271 IF ( aaqq .LT. xsc )
THEN
1273 IF ( sva(p) .LT. xsc )
THEN
1274 CALL claset(
'A', m, 1, czero, czero, a(1,p), lda )
1288 IF ( ( lsvec .AND. rsvec ) .AND. .NOT.( jracc ) )
THEN
1293 DO 1952 p = 1, m - 1
1294 q = isamax( m-p+1, rwork(m+p), 1 ) + p - 1
1296 IF ( p .NE. q )
THEN
1298 rwork(m+p) = rwork(m+q)
1302 CALL claswp( n, a, lda, 1, m-1, iwork(iwoff+1), 1 )
1324 CALL cgeqp3( m, n, a, lda, iwork, cwork, cwork(n+1), lwork-n,
1341 temp1 = sqrt(
REAL(n))*epsln
1343 IF ( abs(a(p,p)) .GE. (temp1*abs(a(1,1))) )
THEN
1350 ELSE IF ( l2rank )
THEN
1356 IF ( ( abs(a(p,p)) .LT. (epsln*abs(a(p-1,p-1))) ) .OR.
1357 $ ( abs(a(p,p)) .LT. small ) .OR.
1358 $ ( l2kill .AND. (abs(a(p,p)) .LT. temp1) ) )
GO TO 3402
1373 IF ( ( abs(a(p,p)) .LT. small ) .OR.
1374 $ ( l2kill .AND. (abs(a(p,p)) .LT. temp1) ) )
GO TO 3302
1382 IF ( nr .EQ. n )
THEN
1385 temp1 = abs(a(p,p)) / sva(iwork(p))
1386 maxprj = min( maxprj, temp1 )
1388 IF ( maxprj**2 .GE. one -
REAL(n)*EPSLN ) almort = .true.
1397 IF ( n .EQ. nr )
THEN
1400 CALL clacpy(
'U', n, n, a, lda, v, ldv )
1402 temp1 = sva(iwork(p))
1403 CALL csscal( p, one/temp1, v(1,p), 1 )
1406 CALL cpocon(
'U', n, v, ldv, one, temp1,
1407 $ cwork(n+1), rwork, ierr )
1409 CALL cpocon(
'U', n, v, ldv, one, temp1,
1410 $ cwork, rwork, ierr )
1413 ELSE IF ( lsvec )
THEN
1415 CALL clacpy(
'U', n, n, a, lda, u, ldu )
1417 temp1 = sva(iwork(p))
1418 CALL csscal( p, one/temp1, u(1,p), 1 )
1420 CALL cpocon(
'U', n, u, ldu, one, temp1,
1421 $ cwork(n+1), rwork, ierr )
1423 CALL clacpy(
'U', n, n, a, lda, cwork, n )
1428 temp1 = sva(iwork(p))
1430 CALL csscal( p, one/temp1, cwork((p-1)*n+1), 1 )
1435 CALL cpocon(
'U', n, cwork, n, one, temp1,
1436 $ cwork(n*n+1), rwork, ierr )
1439 IF ( temp1 .NE. zero )
THEN
1440 sconda = one / sqrt(temp1)
1451 l2pert = l2pert .AND. ( abs( a(1,1)/a(nr,nr) ) .GT. sqrt(big1) )
1456 IF ( .NOT. ( rsvec .OR. lsvec ) )
THEN
1461 DO 1946 p = 1, min( n-1, nr )
1462 CALL ccopy( n-p, a(p,p+1), lda, a(p+1,p), 1 )
1463 CALL clacgv( n-p+1, a(p,p), 1 )
1465 IF ( nr .EQ. n ) a(n,n) = conjg(a(n,n))
1479 IF ( .NOT. almort )
THEN
1483 xsc = epsln /
REAL(N)
1485 ctemp = cmplx(xsc*abs(a(q,q)),zero)
1487 IF ( ( (p.GT.q) .AND. (abs(a(p,q)).LE.temp1) )
1488 $ .OR. ( p .LT. q ) )
1494 CALL claset(
'U', nr-1,nr-1, czero,czero, a(1,2),lda )
1499 CALL cgeqrf( n,nr, a,lda, cwork, cwork(n+1),lwork-n, ierr )
1502 DO 1948 p = 1, nr - 1
1503 CALL ccopy( nr-p, a(p,p+1), lda, a(p+1,p), 1 )
1504 CALL clacgv( nr-p+1, a(p,p), 1 )
1515 xsc = epsln /
REAL(n)
1517 ctemp = cmplx(xsc*abs(a(q,q)),zero)
1519 IF ( ( (p.GT.q) .AND. (abs(a(p,q)).LE.temp1) )
1520 $ .OR. ( p .LT. q ) )
1526 CALL claset(
'U', nr-1, nr-1, czero, czero, a(1,2), lda )
1533 CALL cgesvj(
'L',
'N',
'N', nr, nr, a, lda, sva,
1534 $ n, v, ldv, cwork, lwork, rwork, lrwork, info )
1537 numrank = nint(rwork(2))
1540 ELSE IF ( ( rsvec .AND. ( .NOT. lsvec ) .AND. ( .NOT. jracc ) )
1542 $ ( jracc .AND. ( .NOT. lsvec ) .AND. ( nr .NE. n ) ) )
THEN
1550 CALL ccopy( n-p+1, a(p,p), lda, v(p,p), 1 )
1551 CALL clacgv( n-p+1, v(p,p), 1 )
1553 CALL claset(
'U', nr-1,nr-1, czero, czero, v(1,2), ldv )
1555 CALL cgesvj(
'L',
'U',
'N', n, nr, v, ldv, sva, nr, a, lda,
1556 $ cwork, lwork, rwork, lrwork, info )
1558 numrank = nint(rwork(2))
1565 CALL claset(
'L', nr-1,nr-1, czero, czero, a(2,1), lda )
1566 CALL cgelqf( nr,n, a, lda, cwork, cwork(n+1), lwork-n, ierr)
1567 CALL clacpy(
'L', nr, nr, a, lda, v, ldv )
1568 CALL claset(
'U', nr-1,nr-1, czero, czero, v(1,2), ldv )
1569 CALL cgeqrf( nr, nr, v, ldv, cwork(n+1), cwork(2*n+1),
1572 CALL ccopy( nr-p+1, v(p,p), ldv, v(p,p), 1 )
1573 CALL clacgv( nr-p+1, v(p,p), 1 )
1575 CALL claset(
'U', nr-1, nr-1, czero, czero, v(1,2), ldv)
1577 CALL cgesvj(
'L',
'U',
'N', nr, nr, v,ldv, sva, nr, u,
1578 $ ldu, cwork(n+1), lwork-n, rwork, lrwork, info )
1580 numrank = nint(rwork(2))
1581 IF ( nr .LT. n )
THEN
1582 CALL claset(
'A',n-nr, nr, czero,czero, v(nr+1,1), ldv )
1583 CALL claset(
'A',nr, n-nr, czero,czero, v(1,nr+1), ldv )
1584 CALL claset(
'A',n-nr,n-nr,czero,cone, v(nr+1,nr+1),ldv )
1587 CALL cunmlq(
'L',
'C', n, n, nr, a, lda, cwork,
1588 $ v, ldv, cwork(n+1), lwork-n, ierr )
1596 CALL clapmr( .false., n, n, v, ldv, iwork )
1599 CALL clacpy(
'A', n, n, v, ldv, u, ldu )
1602 ELSE IF ( jracc .AND. (.NOT. lsvec) .AND. ( nr.EQ. n ) )
THEN
1604 CALL claset(
'L', n-1,n-1, czero, czero, a(2,1), lda )
1606 CALL cgesvj(
'U',
'N',
'V', n, n, a, lda, sva, n, v, ldv,
1607 $ cwork, lwork, rwork, lrwork, info )
1609 numrank = nint(rwork(2))
1610 CALL clapmr( .false., n, n, v, ldv, iwork )
1612 ELSE IF ( lsvec .AND. ( .NOT. rsvec ) )
THEN
1619 CALL ccopy( n-p+1, a(p,p), lda, u(p,p), 1 )
1620 CALL clacgv( n-p+1, u(p,p), 1 )
1622 CALL claset(
'U', nr-1, nr-1, czero, czero, u(1,2), ldu )
1624 CALL cgeqrf( n, nr, u, ldu, cwork(n+1), cwork(2*n+1),
1627 DO 1967 p = 1, nr - 1
1628 CALL ccopy( nr-p, u(p,p+1), ldu, u(p+1,p), 1 )
1629 CALL clacgv( n-p+1, u(p,p), 1 )
1631 CALL claset(
'U', nr-1, nr-1, czero, czero, u(1,2), ldu )
1633 CALL cgesvj(
'L',
'U',
'N', nr,nr, u, ldu, sva, nr, a,
1634 $ lda, cwork(n+1), lwork-n, rwork, lrwork, info )
1636 numrank = nint(rwork(2))
1638 IF ( nr .LT. m )
THEN
1639 CALL claset(
'A', m-nr, nr,czero, czero, u(nr+1,1), ldu )
1640 IF ( nr .LT. n1 )
THEN
1641 CALL claset(
'A',nr, n1-nr, czero, czero, u(1,nr+1),ldu )
1642 CALL claset(
'A',m-nr,n1-nr,czero,cone,u(nr+1,nr+1),ldu )
1646 CALL cunmqr(
'L',
'N', m, n1, n, a, lda, cwork, u,
1647 $ ldu, cwork(n+1), lwork-n, ierr )
1650 $
CALL claswp( n1, u, ldu, 1, m-1, iwork(iwoff+1), -1 )
1653 xsc = one / scnrm2( m, u(1,p), 1 )
1654 CALL csscal( m, xsc, u(1,p), 1 )
1658 CALL clacpy(
'A', n, n, u, ldu, v, ldv )
1665 IF ( .NOT. jracc )
THEN
1667 IF ( .NOT. almort )
THEN
1677 CALL ccopy( n-p+1, a(p,p), lda, v(p,p), 1 )
1678 CALL clacgv( n-p+1, v(p,p), 1 )
1696 ctemp = cmplx(xsc*abs( v(q,q) ),zero)
1698 IF ( ( p .GT. q ) .AND. ( abs(v(p,q)) .LE. temp1 )
1699 $ .OR. ( p .LT. q ) )
1702 IF ( p .LT. q ) v(p,q) = - v(p,q)
1706 CALL claset(
'U', nr-1, nr-1, czero, czero, v(1,2), ldv )
1713 CALL clacpy(
'L', nr, nr, v, ldv, cwork(2*n+1), nr )
1715 temp1 = scnrm2(nr-p+1,cwork(2*n+(p-1)*nr+p),1)
1716 CALL csscal(nr-p+1,one/temp1,cwork(2*n+(p-1)*nr+p),1)
1718 CALL cpocon(
'L',nr,cwork(2*n+1),nr,one,temp1,
1719 $ cwork(2*n+nr*nr+1),rwork,ierr)
1720 condr1 = one / sqrt(temp1)
1726 cond_ok = sqrt(sqrt(
REAL(nr)))
1729 IF ( condr1 .LT. cond_ok )
THEN
1734 CALL cgeqrf( n, nr, v, ldv, cwork(n+1), cwork(2*n+1),
1738 xsc = sqrt(small)/epsln
1740 DO 3958 q = 1, p - 1
1741 ctemp=cmplx(xsc*min(abs(v(p,p)),abs(v(q,q))),
1743 IF ( abs(v(q,p)) .LE. temp1 )
1751 $
CALL clacpy(
'A', n, nr, v, ldv, cwork(2*n+1), n )
1755 DO 1969 p = 1, nr - 1
1756 CALL ccopy( nr-p, v(p,p+1), ldv, v(p+1,p), 1 )
1757 CALL clacgv(nr-p+1, v(p,p), 1 )
1759 v(nr,nr)=conjg(v(nr,nr))
1776 CALL cgeqp3( n, nr, v, ldv, iwork(n+1), cwork(n+1),
1777 $ cwork(2*n+1), lwork-2*n, rwork, ierr )
1783 DO 3968 q = 1, p - 1
1784 ctemp=cmplx(xsc*min(abs(v(p,p)),abs(v(q,q))),
1786 IF ( abs(v(q,p)) .LE. temp1 )
1793 CALL clacpy(
'A', n, nr, v, ldv, cwork(2*n+1), n )
1798 DO 8971 q = 1, p - 1
1799 ctemp=cmplx(xsc*min(abs(v(p,p)),abs(v(q,q))),
1806 CALL claset(
'L',nr-1,nr-1,czero,czero,v(2,1),ldv )
1809 CALL cgelqf( nr, nr, v, ldv, cwork(2*n+n*nr+1),
1810 $ cwork(2*n+n*nr+nr+1), lwork-2*n-n*nr-nr, ierr )
1812 CALL clacpy(
'L',nr,nr,v,ldv,cwork(2*n+n*nr+nr+1),nr )
1814 temp1 = scnrm2( p, cwork(2*n+n*nr+nr+p), nr )
1815 CALL csscal( p, one/temp1, cwork(2*n+n*nr+nr+p), nr )
1817 CALL cpocon(
'L',nr,cwork(2*n+n*nr+nr+1),nr,one,temp1,
1818 $ cwork(2*n+n*nr+nr+nr*nr+1),rwork,ierr )
1819 condr2 = one / sqrt(temp1)
1822 IF ( condr2 .GE. cond_ok )
THEN
1827 CALL clacpy(
'U', nr, nr, v, ldv, cwork(2*n+1), n )
1837 ctemp = xsc * v(q,q)
1838 DO 4969 p = 1, q - 1
1844 CALL claset(
'U', nr-1,nr-1, czero,czero, v(1,2), ldv )
1853 IF ( condr1 .LT. cond_ok )
THEN
1855 CALL cgesvj(
'L',
'U',
'N',nr,nr,v,ldv,sva,nr,u, ldu,
1856 $ cwork(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,rwork,
1859 numrank = nint(rwork(2))
1861 CALL ccopy( nr, v(1,p), 1, u(1,p), 1 )
1862 CALL csscal( nr, sva(p), v(1,p), 1 )
1867 IF ( nr .EQ. n )
THEN
1872 CALL ctrsm(
'L',
'U',
'N',
'N', nr,nr,cone, a,lda, v,ldv)
1878 CALL ctrsm(
'L',
'U',
'C',
'N',nr,nr,cone,cwork(2*n+1),
1880 IF ( nr .LT. n )
THEN
1881 CALL claset(
'A',n-nr,nr,czero,czero,v(nr+1,1),ldv)
1882 CALL claset(
'A',nr,n-nr,czero,czero,v(1,nr+1),ldv)
1883 CALL claset(
'A',n-nr,n-nr,czero,cone,v(nr+1,nr+1),ldv)
1885 CALL cunmqr(
'L',
'N',n,n,nr,cwork(2*n+1),n,cwork(n+1),
1886 $ v,ldv,cwork(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr)
1889 ELSE IF ( condr2 .LT. cond_ok )
THEN
1895 CALL cgesvj(
'L',
'U',
'N', nr, nr, v, ldv, sva, nr, u,
1896 $ ldu, cwork(2*n+n*nr+nr+1), lwork-2*n-n*nr-nr,
1897 $ rwork, lrwork, info )
1899 numrank = nint(rwork(2))
1901 CALL ccopy( nr, v(1,p), 1, u(1,p), 1 )
1902 CALL csscal( nr, sva(p), u(1,p), 1 )
1904 CALL ctrsm(
'L',
'U',
'N',
'N',nr,nr,cone,cwork(2*n+1),n,
1909 cwork(2*n+n*nr+nr+iwork(n+p)) = u(p,q)
1912 u(p,q) = cwork(2*n+n*nr+nr+p)
1915 IF ( nr .LT. n )
THEN
1916 CALL claset(
'A',n-nr,nr,czero,czero,v(nr+1,1),ldv )
1917 CALL claset(
'A',nr,n-nr,czero,czero,v(1,nr+1),ldv )
1918 CALL claset(
'A',n-nr,n-nr,czero,cone,v(nr+1,nr+1),ldv)
1920 CALL cunmqr(
'L',
'N',n,n,nr,cwork(2*n+1),n,cwork(n+1),
1921 $ v,ldv,cwork(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr )
1934 CALL cgesvj(
'L',
'U',
'V', nr, nr, v, ldv, sva, nr, u,
1935 $ ldu, cwork(2*n+n*nr+nr+1), lwork-2*n-n*nr-nr,
1936 $ rwork, lrwork, info )
1938 numrank = nint(rwork(2))
1939 IF ( nr .LT. n )
THEN
1940 CALL claset(
'A',n-nr,nr,czero,czero,v(nr+1,1),ldv )
1941 CALL claset(
'A',nr,n-nr,czero,czero,v(1,nr+1),ldv )
1942 CALL claset(
'A',n-nr,n-nr,czero,cone,v(nr+1,nr+1),ldv)
1944 CALL cunmqr(
'L',
'N',n,n,nr,cwork(2*n+1),n,cwork(n+1),
1945 $ v,ldv,cwork(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr )
1947 CALL cunmlq(
'L',
'C', nr, nr, nr, cwork(2*n+1), n,
1948 $ cwork(2*n+n*nr+1), u, ldu, cwork(2*n+n*nr+nr+1),
1949 $ lwork-2*n-n*nr-nr, ierr )
1952 cwork(2*n+n*nr+nr+iwork(n+p)) = u(p,q)
1955 u(p,q) = cwork(2*n+n*nr+nr+p)
1965 temp1 = sqrt(
REAL(n)) * epsln
1968 cwork(2*n+n*nr+nr+iwork(p)) = v(p,q)
1971 v(p,q) = cwork(2*n+n*nr+nr+p)
1973 xsc = one / scnrm2( n, v(1,q), 1 )
1974 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1975 $
CALL csscal( n, xsc, v(1,q), 1 )
1979 IF ( nr .LT. m )
THEN
1980 CALL claset(
'A', m-nr, nr, czero, czero, u(nr+1,1), ldu)
1981 IF ( nr .LT. n1 )
THEN
1982 CALL claset(
'A',nr,n1-nr,czero,czero,u(1,nr+1),ldu)
1983 CALL claset(
'A',m-nr,n1-nr,czero,cone,
1991 CALL cunmqr(
'L',
'N', m, n1, n, a, lda, cwork, u,
1992 $ ldu, cwork(n+1), lwork-n, ierr )
1995 temp1 = sqrt(
REAL(m)) * epsln
1997 xsc = one / scnrm2( m, u(1,p), 1 )
1998 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1999 $
CALL csscal( m, xsc, u(1,p), 1 )
2006 $
CALL claswp( n1, u, ldu, 1, m-1, iwork(iwoff+1), -1 )
2013 CALL clacpy(
'U', n, n, a, lda, cwork(n+1), n )
2017 ctemp = xsc * cwork( n + (p-1)*n + p )
2018 DO 5971 q = 1, p - 1
2021 cwork(n+(q-1)*n+p)=-ctemp
2025 CALL claset(
'L',n-1,n-1,czero,czero,cwork(n+2),n )
2028 CALL cgesvj(
'U',
'U',
'N', n, n, cwork(n+1), n, sva,
2029 $ n, u, ldu, cwork(n+n*n+1), lwork-n-n*n, rwork, lrwork,
2033 numrank = nint(rwork(2))
2035 CALL ccopy( n, cwork(n+(p-1)*n+1), 1, u(1,p), 1 )
2036 CALL csscal( n, sva(p), cwork(n+(p-1)*n+1), 1 )
2039 CALL ctrsm(
'L',
'U',
'N',
'N', n, n,
2040 $ cone, a, lda, cwork(n+1), n )
2042 CALL ccopy( n, cwork(n+p), n, v(iwork(p),1), ldv )
2044 temp1 = sqrt(
REAL(n))*epsln
2046 xsc = one / scnrm2( n, v(1,p), 1 )
2047 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
2048 $
CALL csscal( n, xsc, v(1,p), 1 )
2053 IF ( n .LT. m )
THEN
2054 CALL claset(
'A', m-n, n, czero, czero, u(n+1,1), ldu )
2055 IF ( n .LT. n1 )
THEN
2056 CALL claset(
'A',n, n1-n, czero, czero, u(1,n+1),ldu)
2057 CALL claset(
'A',m-n,n1-n, czero, cone,u(n+1,n+1),ldu)
2060 CALL cunmqr(
'L',
'N', m, n1, n, a, lda, cwork, u,
2061 $ ldu, cwork(n+1), lwork-n, ierr )
2062 temp1 = sqrt(
REAL(m))*epsln
2064 xsc = one / scnrm2( m, u(1,p), 1 )
2065 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
2066 $
CALL csscal( m, xsc, u(1,p), 1 )
2070 $
CALL claswp( n1, u, ldu, 1, m-1, iwork(iwoff+1), -1 )
2090 CALL ccopy( n-p+1, a(p,p), lda, v(p,p), 1 )
2091 CALL clacgv( n-p+1, v(p,p), 1 )
2095 xsc = sqrt(small/epsln)
2097 ctemp = cmplx(xsc*abs( v(q,q) ),zero)
2099 IF ( ( p .GT. q ) .AND. ( abs(v(p,q)) .LE. temp1 )
2100 $ .OR. ( p .LT. q ) )
2103 IF ( p .LT. q ) v(p,q) = - v(p,q)
2107 CALL claset(
'U', nr-1, nr-1, czero, czero, v(1,2), ldv )
2110 CALL cgeqrf( n, nr, v, ldv, cwork(n+1), cwork(2*n+1),
2112 CALL clacpy(
'L', n, nr, v, ldv, cwork(2*n+1), n )
2115 CALL ccopy( nr-p+1, v(p,p), ldv, u(p,p), 1 )
2116 CALL clacgv( nr-p+1, u(p,p), 1 )
2120 xsc = sqrt(small/epsln)
2122 DO 9971 p = 1, q - 1
2123 ctemp = cmplx(xsc * min(abs(u(p,p)),abs(u(q,q))),
2130 CALL claset(
'U', nr-1, nr-1, czero, czero, u(1,2), ldu )
2133 CALL cgesvj(
'L',
'U',
'V', nr, nr, u, ldu, sva,
2134 $ n, v, ldv, cwork(2*n+n*nr+1), lwork-2*n-n*nr,
2135 $ rwork, lrwork, info )
2137 numrank = nint(rwork(2))
2139 IF ( nr .LT. n )
THEN
2140 CALL claset(
'A',n-nr,nr,czero,czero,v(nr+1,1),ldv )
2141 CALL claset(
'A',nr,n-nr,czero,czero,v(1,nr+1),ldv )
2142 CALL claset(
'A',n-nr,n-nr,czero,cone,v(nr+1,nr+1),ldv )
2145 CALL cunmqr(
'L',
'N',n,n,nr,cwork(2*n+1),n,cwork(n+1),
2146 $ v,ldv,cwork(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr )
2152 temp1 = sqrt(
REAL(n)) * epsln
2155 cwork(2*n+n*nr+nr+iwork(p)) = v(p,q)
2158 v(p,q) = cwork(2*n+n*nr+nr+p)
2160 xsc = one / scnrm2( n, v(1,q), 1 )
2161 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
2162 $
CALL csscal( n, xsc, v(1,q), 1 )
2168 IF ( nr .LT. m )
THEN
2169 CALL claset(
'A', m-nr, nr, czero, czero, u(nr+1,1), ldu )
2170 IF ( nr .LT. n1 )
THEN
2171 CALL claset(
'A',nr, n1-nr, czero, czero, u(1,nr+1),ldu)
2172 CALL claset(
'A',m-nr,n1-nr, czero, cone,u(nr+1,nr+1),ldu)
2176 CALL cunmqr(
'L',
'N', m, n1, n, a, lda, cwork, u,
2177 $ ldu, cwork(n+1), lwork-n, ierr )
2180 $
CALL claswp( n1, u, ldu, 1, m-1, iwork(iwoff+1), -1 )
2187 CALL cswap( n, u(1,p), 1, v(1,p), 1 )
2196 IF ( uscal2 .LE. (big/sva(1))*uscal1 )
THEN
2197 CALL slascl(
'G', 0, 0, uscal1, uscal2, nr, 1, sva, n, ierr )
2202 IF ( nr .LT. n )
THEN
2208 rwork(1) = uscal2 * scalem
2210 IF ( errest ) rwork(3) = sconda
2211 IF ( lsvec .AND. rsvec )
THEN
subroutine cgesvj(JOBA, JOBU, JOBV, M, N, A, LDA, SVA, MV, V, LDV, CWORK, LWORK, RWORK, LRWORK, INFO)
CGESVJ
subroutine classq(N, X, INCX, SCALE, SUMSQ)
CLASSQ updates a sum of squares represented in scaled form.
subroutine claset(UPLO, M, N, ALPHA, BETA, A, LDA)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
subroutine claswp(N, A, LDA, K1, K2, IPIV, INCX)
CLASWP performs a series of row interchanges on a general rectangular matrix.
subroutine cungqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
CUNGQR
subroutine clapmr(FORWRD, M, N, X, LDX, K)
CLAPMR rearranges rows of a matrix as specified by a permutation vector.
subroutine clascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine cpocon(UPLO, N, A, LDA, ANORM, RCOND, WORK, RWORK, INFO)
CPOCON
subroutine ctrsm(SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, B, LDB)
CTRSM
subroutine cgelqf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CGELQF
subroutine cgeqp3(M, N, A, LDA, JPVT, TAU, WORK, LWORK, RWORK, INFO)
CGEQP3
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine cgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CGEQRF
subroutine cgejsv(JOBA, JOBU, JOBV, JOBR, JOBT, JOBP, M, N, A, LDA, SVA, U, LDU, V, LDV, CWORK, LWORK, RWORK, LRWORK, IWORK, INFO)
CGEJSV
subroutine slascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine clacpy(UPLO, M, N, A, LDA, B, LDB)
CLACPY copies all or part of one two-dimensional array to another.
subroutine clacgv(N, X, INCX)
CLACGV conjugates a complex vector.
subroutine cunmqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMQR
subroutine sscal(N, SA, SX, INCX)
SSCAL
subroutine ccopy(N, CX, INCX, CY, INCY)
CCOPY
subroutine cswap(N, CX, INCX, CY, INCY)
CSWAP
subroutine cunmlq(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMLQ
subroutine slassq(N, X, INCX, SCALE, SUMSQ)
SLASSQ updates a sum of squares represented in scaled form.
subroutine csscal(N, SA, CX, INCX)
CSSCAL