473 SUBROUTINE dgejsv( JOBA, JOBU, JOBV, JOBR, JOBT, JOBP,
474 $ M, N, A, LDA, SVA, U, LDU, V, LDV,
475 $ WORK, LWORK, IWORK, INFO )
483 INTEGER INFO, LDA, LDU, LDV, LWORK, M, N
486 DOUBLE PRECISION A( LDA, * ), SVA( N ), U( LDU, * ), V( LDV, * ),
489 CHARACTER*1 JOBA, JOBP, JOBR, JOBT, JOBU, JOBV
495 DOUBLE PRECISION ZERO, ONE
496 PARAMETER ( ZERO = 0.0d0, one = 1.0d0 )
499 DOUBLE PRECISION AAPP, AAQQ, AATMAX, AATMIN, BIG, BIG1, COND_OK,
500 $ CONDR1, CONDR2, ENTRA, ENTRAT, EPSLN, MAXPRJ, SCALEM,
501 $ sconda, sfmin, small, temp1, uscal1, uscal2, xsc
502 INTEGER IERR, N1, NR, NUMRANK, p, q, WARNING
503 LOGICAL ALMORT, DEFR, ERREST, GOSCAL, JRACC, KILL, LSVEC,
504 $ l2aber, l2kill, l2pert, l2rank, l2tran,
505 $ noscal, rowpiv, rsvec, transp
508 INTRINSIC dabs, dlog, max, min, dble, idnint, dsign, dsqrt
511 DOUBLE PRECISION DLAMCH, DNRM2
514 EXTERNAL idamax, lsame, dlamch, dnrm2
526 lsvec = lsame( jobu,
'U' ) .OR. lsame( jobu,
'F' )
527 jracc = lsame( jobv,
'J' )
528 rsvec = lsame( jobv,
'V' ) .OR. jracc
529 rowpiv = lsame( joba,
'F' ) .OR. lsame( joba,
'G' )
530 l2rank = lsame( joba,
'R' )
531 l2aber = lsame( joba,
'A' )
532 errest = lsame( joba,
'E' ) .OR. lsame( joba,
'G' )
533 l2tran = lsame( jobt,
'T' )
534 l2kill = lsame( jobr,
'R' )
535 defr = lsame( jobr,
'N' )
536 l2pert = lsame( jobp,
'P' )
538 IF ( .NOT.(rowpiv .OR. l2rank .OR. l2aber .OR.
539 $ errest .OR. lsame( joba,
'C' ) ))
THEN
541 ELSE IF ( .NOT.( lsvec .OR. lsame( jobu,
'N' ) .OR.
542 $ lsame( jobu,
'W' )) )
THEN
544 ELSE IF ( .NOT.( rsvec .OR. lsame( jobv,
'N' ) .OR.
545 $ lsame( jobv,
'W' )) .OR. ( jracc .AND. (.NOT.lsvec) ) )
THEN
547 ELSE IF ( .NOT. ( l2kill .OR. defr ) )
THEN
549 ELSE IF ( .NOT. ( l2tran .OR. lsame( jobt,
'N' ) ) )
THEN
551 ELSE IF ( .NOT. ( l2pert .OR. lsame( jobp,
'N' ) ) )
THEN
553 ELSE IF ( m .LT. 0 )
THEN
555 ELSE IF ( ( n .LT. 0 ) .OR. ( n .GT. m ) )
THEN
557 ELSE IF ( lda .LT. m )
THEN
559 ELSE IF ( lsvec .AND. ( ldu .LT. m ) )
THEN
561 ELSE IF ( rsvec .AND. ( ldv .LT. n ) )
THEN
563 ELSE IF ( (.NOT.(lsvec .OR. rsvec .OR. errest).AND.
564 & (lwork .LT. max(7,4*n+1,2*m+n))) .OR.
565 & (.NOT.(lsvec .OR. rsvec) .AND. errest .AND.
566 & (lwork .LT. max(7,4*n+n*n,2*m+n))) .OR.
567 & (lsvec .AND. (.NOT.rsvec) .AND. (lwork .LT. max(7,2*m+n,4*n+1)))
569 & (rsvec .AND. (.NOT.lsvec) .AND. (lwork .LT. max(7,2*m+n,4*n+1)))
571 & (lsvec .AND. rsvec .AND. (.NOT.jracc) .AND.
572 & (lwork.LT.max(2*m+n,6*n+2*n*n)))
573 & .OR. (lsvec .AND. rsvec .AND. jracc .AND.
574 & lwork.LT.max(2*m+n,4*n+n*n,2*n+n*n+6)))
582 IF ( info .NE. 0 )
THEN
584 CALL xerbla(
'DGEJSV', - info )
590 IF ( ( m .EQ. 0 ) .OR. ( n .EQ. 0 ) )
THEN
600 IF ( lsame( jobu,
'F' ) ) n1 = m
607 epsln = dlamch(
'Epsilon')
608 sfmin = dlamch(
'SafeMinimum')
609 small = sfmin / epsln
619 scalem = one / dsqrt(dble(m)*dble(n))
625 CALL dlassq( m, a(1,p), 1, aapp, aaqq )
626 IF ( aapp .GT. big )
THEN
628 CALL xerbla(
'DGEJSV', -info )
632 IF ( ( aapp .LT. (big / aaqq) ) .AND. noscal )
THEN
636 sva(p) = aapp * ( aaqq * scalem )
639 CALL dscal( p-1, scalem, sva, 1 )
644 IF ( noscal ) scalem = one
649 aapp = max( aapp, sva(p) )
650 IF ( sva(p) .NE. zero ) aaqq = min( aaqq, sva(p) )
655 IF ( aapp .EQ. zero )
THEN
656 IF ( lsvec )
CALL dlaset(
'G', m, n1, zero, one, u, ldu )
657 IF ( rsvec )
CALL dlaset(
'G', n, n, zero, one, v, ldv )
660 IF ( errest ) work(3) = one
661 IF ( lsvec .AND. rsvec )
THEN
680 IF ( aaqq .LE. sfmin )
THEN
691 CALL dlascl(
'G',0,0,sva(1),scalem, m,1,a(1,1),lda,ierr )
692 CALL dlacpy(
'A', m, 1, a, lda, u, ldu )
694 IF ( n1 .NE. n )
THEN
695 CALL dgeqrf( m, n, u,ldu, work, work(n+1),lwork-n,ierr )
696 CALL dorgqr( m,n1,1, u,ldu,work,work(n+1),lwork-n,ierr )
697 CALL dcopy( m, a(1,1), 1, u(1,1), 1 )
703 IF ( sva(1) .LT. (big*scalem) )
THEN
704 sva(1) = sva(1) / scalem
707 work(1) = one / scalem
709 IF ( sva(1) .NE. zero )
THEN
711 IF ( ( sva(1) / scalem) .GE. sfmin )
THEN
721 IF ( errest ) work(3) = one
722 IF ( lsvec .AND. rsvec )
THEN
735 l2tran = l2tran .AND. ( m .EQ. n )
739 IF ( rowpiv .OR. l2tran )
THEN
750 CALL dlassq( n, a(p,1), lda, xsc, temp1 )
753 work(m+n+p) = xsc * scalem
754 work(n+p) = xsc * (scalem*dsqrt(temp1))
755 aatmax = max( aatmax, work(n+p) )
756 IF (work(n+p) .NE. zero) aatmin = min(aatmin,work(n+p))
760 work(m+n+p) = scalem*dabs( a(p,idamax(n,a(p,1),lda)) )
761 aatmax = max( aatmax, work(m+n+p) )
762 aatmin = min( aatmin, work(m+n+p) )
781 CALL dlassq( n, sva, 1, xsc, temp1 )
786 big1 = ( ( sva(p) / xsc )**2 ) * temp1
787 IF ( big1 .NE. zero ) entra = entra + big1 * dlog(big1)
789 entra = - entra / dlog(dble(n))
799 big1 = ( ( work(p) / xsc )**2 ) * temp1
800 IF ( big1 .NE. zero ) entrat = entrat + big1 * dlog(big1)
802 entrat = - entrat / dlog(dble(m))
807 transp = ( entrat .LT. entra )
853 temp1 = dsqrt( big / dble(n) )
855 CALL dlascl(
'G', 0, 0, aapp, temp1, n, 1, sva, n, ierr )
856 IF ( aaqq .GT. (aapp * sfmin) )
THEN
857 aaqq = ( aaqq / aapp ) * temp1
859 aaqq = ( aaqq * temp1 ) / aapp
861 temp1 = temp1 * scalem
862 CALL dlascl(
'G', 0, 0, aapp, temp1, m, n, a, lda, ierr )
886 IF ( ( aaqq.LT.dsqrt(sfmin) ) .AND. lsvec .AND. rsvec )
THEN
891 IF ( aaqq .LT. xsc )
THEN
893 IF ( sva(p) .LT. xsc )
THEN
894 CALL dlaset(
'A', m, 1, zero, zero, a(1,p), lda )
909 q = idamax( m-p+1, work(m+n+p), 1 ) + p - 1
913 work(m+n+p) = work(m+n+q)
917 CALL dlaswp( n, a, lda, 1, m-1, iwork(2*n+1), 1 )
939 CALL dgeqp3( m,n,a,lda, iwork,work, work(n+1),lwork-n, ierr )
955 temp1 = dsqrt(dble(n))*epsln
957 IF ( dabs(a(p,p)) .GE. (temp1*dabs(a(1,1))) )
THEN
964 ELSE IF ( l2rank )
THEN
970 IF ( ( dabs(a(p,p)) .LT. (epsln*dabs(a(p-1,p-1))) ) .OR.
971 $ ( dabs(a(p,p)) .LT. small ) .OR.
972 $ ( l2kill .AND. (dabs(a(p,p)) .LT. temp1) ) )
GO TO 3402
987 IF ( ( dabs(a(p,p)) .LT. small ) .OR.
988 $ ( l2kill .AND. (dabs(a(p,p)) .LT. temp1) ) )
GO TO 3302
996 IF ( nr .EQ. n )
THEN
999 temp1 = dabs(a(p,p)) / sva(iwork(p))
1000 maxprj = min( maxprj, temp1 )
1002 IF ( maxprj**2 .GE. one - dble(n)*epsln ) almort = .true.
1011 IF ( n .EQ. nr )
THEN
1014 CALL dlacpy(
'U', n, n, a, lda, v, ldv )
1016 temp1 = sva(iwork(p))
1017 CALL dscal( p, one/temp1, v(1,p), 1 )
1019 CALL dpocon(
'U', n, v, ldv, one, temp1,
1020 $ work(n+1), iwork(2*n+m+1), ierr )
1021 ELSE IF ( lsvec )
THEN
1023 CALL dlacpy(
'U', n, n, a, lda, u, ldu )
1025 temp1 = sva(iwork(p))
1026 CALL dscal( p, one/temp1, u(1,p), 1 )
1028 CALL dpocon(
'U', n, u, ldu, one, temp1,
1029 $ work(n+1), iwork(2*n+m+1), ierr )
1031 CALL dlacpy(
'U', n, n, a, lda, work(n+1), n )
1033 temp1 = sva(iwork(p))
1034 CALL dscal( p, one/temp1, work(n+(p-1)*n+1), 1 )
1037 CALL dpocon(
'U', n, work(n+1), n, one, temp1,
1038 $ work(n+n*n+1), iwork(2*n+m+1), ierr )
1040 sconda = one / dsqrt(temp1)
1048 l2pert = l2pert .AND. ( dabs( a(1,1)/a(nr,nr) ) .GT. dsqrt(big1) )
1053 IF ( .NOT. ( rsvec .OR. lsvec ) )
THEN
1058 DO 1946 p = 1, min( n-1, nr )
1059 CALL dcopy( n-p, a(p,p+1), lda, a(p+1,p), 1 )
1074 IF ( .NOT. almort )
THEN
1078 xsc = epsln / dble(n)
1080 temp1 = xsc*dabs(a(q,q))
1082 IF ( ( (p.GT.q) .AND. (dabs(a(p,q)).LE.temp1) )
1083 $ .OR. ( p .LT. q ) )
1084 $ a(p,q) = dsign( temp1, a(p,q) )
1088 CALL dlaset(
'U', nr-1,nr-1, zero,zero, a(1,2),lda )
1093 CALL dgeqrf( n,nr, a,lda, work, work(n+1),lwork-n, ierr )
1096 DO 1948 p = 1, nr - 1
1097 CALL dcopy( nr-p, a(p,p+1), lda, a(p+1,p), 1 )
1108 xsc = epsln / dble(n)
1110 temp1 = xsc*dabs(a(q,q))
1112 IF ( ( (p.GT.q) .AND. (dabs(a(p,q)).LE.temp1) )
1113 $ .OR. ( p .LT. q ) )
1114 $ a(p,q) = dsign( temp1, a(p,q) )
1118 CALL dlaset(
'U', nr-1, nr-1, zero, zero, a(1,2), lda )
1125 CALL dgesvj(
'L',
'NoU',
'NoV', nr, nr, a, lda, sva,
1126 $ n, v, ldv, work, lwork, info )
1129 numrank = idnint(work(2))
1132 ELSE IF ( rsvec .AND. ( .NOT. lsvec ) )
THEN
1140 CALL dcopy( n-p+1, a(p,p), lda, v(p,p), 1 )
1142 CALL dlaset(
'Upper', nr-1, nr-1, zero, zero, v(1,2), ldv )
1144 CALL dgesvj(
'L',
'U',
'N', n, nr, v,ldv, sva, nr, a,lda,
1145 $ work, lwork, info )
1147 numrank = idnint(work(2))
1154 CALL dlaset(
'Lower', nr-1, nr-1, zero, zero, a(2,1), lda )
1155 CALL dgelqf( nr, n, a, lda, work, work(n+1), lwork-n, ierr)
1156 CALL dlacpy(
'Lower', nr, nr, a, lda, v, ldv )
1157 CALL dlaset(
'Upper', nr-1, nr-1, zero, zero, v(1,2), ldv )
1158 CALL dgeqrf( nr, nr, v, ldv, work(n+1), work(2*n+1),
1161 CALL dcopy( nr-p+1, v(p,p), ldv, v(p,p), 1 )
1163 CALL dlaset(
'Upper', nr-1, nr-1, zero, zero, v(1,2), ldv )
1165 CALL dgesvj(
'Lower',
'U',
'N', nr, nr, v,ldv, sva, nr, u,
1166 $ ldu, work(n+1), lwork, info )
1168 numrank = idnint(work(n+2))
1169 IF ( nr .LT. n )
THEN
1170 CALL dlaset(
'A',n-nr, nr, zero,zero, v(nr+1,1), ldv )
1171 CALL dlaset(
'A',nr, n-nr, zero,zero, v(1,nr+1), ldv )
1172 CALL dlaset(
'A',n-nr,n-nr,zero,one, v(nr+1,nr+1), ldv )
1175 CALL dormlq(
'Left',
'Transpose', n, n, nr, a, lda, work,
1176 $ v, ldv, work(n+1), lwork-n, ierr )
1181 CALL dcopy( n, v(p,1), ldv, a(iwork(p),1), lda )
1183 CALL dlacpy(
'All', n, n, a, lda, v, ldv )
1186 CALL dlacpy(
'All', n, n, v, ldv, u, ldu )
1189 ELSE IF ( lsvec .AND. ( .NOT. rsvec ) )
THEN
1196 CALL dcopy( n-p+1, a(p,p), lda, u(p,p), 1 )
1198 CALL dlaset(
'Upper', nr-1, nr-1, zero, zero, u(1,2), ldu )
1200 CALL dgeqrf( n, nr, u, ldu, work(n+1), work(2*n+1),
1203 DO 1967 p = 1, nr - 1
1204 CALL dcopy( nr-p, u(p,p+1), ldu, u(p+1,p), 1 )
1206 CALL dlaset(
'Upper', nr-1, nr-1, zero, zero, u(1,2), ldu )
1208 CALL dgesvj(
'Lower',
'U',
'N', nr,nr, u, ldu, sva, nr, a,
1209 $ lda, work(n+1), lwork-n, info )
1211 numrank = idnint(work(n+2))
1213 IF ( nr .LT. m )
THEN
1214 CALL dlaset(
'A', m-nr, nr,zero, zero, u(nr+1,1), ldu )
1215 IF ( nr .LT. n1 )
THEN
1216 CALL dlaset(
'A',nr, n1-nr, zero, zero, u(1,nr+1), ldu )
1217 CALL dlaset(
'A',m-nr,n1-nr,zero,one,u(nr+1,nr+1), ldu )
1221 CALL dormqr(
'Left',
'No Tr', m, n1, n, a, lda, work, u,
1222 $ ldu, work(n+1), lwork-n, ierr )
1225 $
CALL dlaswp( n1, u, ldu, 1, m-1, iwork(2*n+1), -1 )
1228 xsc = one / dnrm2( m, u(1,p), 1 )
1229 CALL dscal( m, xsc, u(1,p), 1 )
1233 CALL dlacpy(
'All', n, n, u, ldu, v, ldv )
1240 IF ( .NOT. jracc )
THEN
1242 IF ( .NOT. almort )
THEN
1252 CALL dcopy( n-p+1, a(p,p), lda, v(p,p), 1 )
1270 temp1 = xsc*dabs( v(q,q) )
1272 IF ( ( p .GT. q ) .AND. ( dabs(v(p,q)) .LE. temp1 )
1273 $ .OR. ( p .LT. q ) )
1274 $ v(p,q) = dsign( temp1, v(p,q) )
1275 IF ( p .LT. q ) v(p,q) = - v(p,q)
1279 CALL dlaset(
'U', nr-1, nr-1, zero, zero, v(1,2), ldv )
1286 CALL dlacpy(
'L', nr, nr, v, ldv, work(2*n+1), nr )
1288 temp1 = dnrm2(nr-p+1,work(2*n+(p-1)*nr+p),1)
1289 CALL dscal(nr-p+1,one/temp1,work(2*n+(p-1)*nr+p),1)
1291 CALL dpocon(
'Lower',nr,work(2*n+1),nr,one,temp1,
1292 $ work(2*n+nr*nr+1),iwork(m+2*n+1),ierr)
1293 condr1 = one / dsqrt(temp1)
1299 cond_ok = dsqrt(dble(nr))
1302 IF ( condr1 .LT. cond_ok )
THEN
1307 CALL dgeqrf( n, nr, v, ldv, work(n+1), work(2*n+1),
1311 xsc = dsqrt(small)/epsln
1313 DO 3958 q = 1, p - 1
1314 temp1 = xsc * min(dabs(v(p,p)),dabs(v(q,q)))
1315 IF ( dabs(v(q,p)) .LE. temp1 )
1316 $ v(q,p) = dsign( temp1, v(q,p) )
1322 $
CALL dlacpy(
'A', n, nr, v, ldv, work(2*n+1), n )
1326 DO 1969 p = 1, nr - 1
1327 CALL dcopy( nr-p, v(p,p+1), ldv, v(p+1,p), 1 )
1345 CALL dgeqp3( n, nr, v, ldv, iwork(n+1), work(n+1),
1346 $ work(2*n+1), lwork-2*n, ierr )
1352 DO 3968 q = 1, p - 1
1353 temp1 = xsc * min(dabs(v(p,p)),dabs(v(q,q)))
1354 IF ( dabs(v(q,p)) .LE. temp1 )
1355 $ v(q,p) = dsign( temp1, v(q,p) )
1360 CALL dlacpy(
'A', n, nr, v, ldv, work(2*n+1), n )
1365 DO 8971 q = 1, p - 1
1366 temp1 = xsc * min(dabs(v(p,p)),dabs(v(q,q)))
1367 v(p,q) = - dsign( temp1, v(q,p) )
1371 CALL dlaset(
'L',nr-1,nr-1,zero,zero,v(2,1),ldv )
1374 CALL dgelqf( nr, nr, v, ldv, work(2*n+n*nr+1),
1375 $ work(2*n+n*nr+nr+1), lwork-2*n-n*nr-nr, ierr )
1377 CALL dlacpy(
'L',nr,nr,v,ldv,work(2*n+n*nr+nr+1),nr )
1379 temp1 = dnrm2( p, work(2*n+n*nr+nr+p), nr )
1380 CALL dscal( p, one/temp1, work(2*n+n*nr+nr+p), nr )
1382 CALL dpocon(
'L',nr,work(2*n+n*nr+nr+1),nr,one,temp1,
1383 $ work(2*n+n*nr+nr+nr*nr+1),iwork(m+2*n+1),ierr )
1384 condr2 = one / dsqrt(temp1)
1386 IF ( condr2 .GE. cond_ok )
THEN
1391 CALL dlacpy(
'U', nr, nr, v, ldv, work(2*n+1), n )
1401 temp1 = xsc * v(q,q)
1402 DO 4969 p = 1, q - 1
1404 v(p,q) = - dsign( temp1, v(p,q) )
1408 CALL dlaset(
'U', nr-1,nr-1, zero,zero, v(1,2), ldv )
1417 IF ( condr1 .LT. cond_ok )
THEN
1419 CALL dgesvj(
'L',
'U',
'N',nr,nr,v,ldv,sva,nr,u,
1420 $ ldu,work(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,info )
1421 scalem = work(2*n+n*nr+nr+1)
1422 numrank = idnint(work(2*n+n*nr+nr+2))
1424 CALL dcopy( nr, v(1,p), 1, u(1,p), 1 )
1425 CALL dscal( nr, sva(p), v(1,p), 1 )
1430 IF ( nr .EQ. n )
THEN
1435 CALL dtrsm(
'L',
'U',
'N',
'N', nr,nr,one, a,lda, v,ldv )
1441 CALL dtrsm(
'L',
'U',
'T',
'N',nr,nr,one,work(2*n+1),
1443 IF ( nr .LT. n )
THEN
1444 CALL dlaset(
'A',n-nr,nr,zero,zero,v(nr+1,1),ldv)
1445 CALL dlaset(
'A',nr,n-nr,zero,zero,v(1,nr+1),ldv)
1446 CALL dlaset(
'A',n-nr,n-nr,zero,one,v(nr+1,nr+1),ldv)
1448 CALL dormqr(
'L',
'N',n,n,nr,work(2*n+1),n,work(n+1),
1449 $ v,ldv,work(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr)
1452 ELSE IF ( condr2 .LT. cond_ok )
THEN
1460 CALL dgesvj(
'L',
'U',
'N', nr, nr, v, ldv, sva, nr, u,
1461 $ ldu, work(2*n+n*nr+nr+1), lwork-2*n-n*nr-nr, info )
1462 scalem = work(2*n+n*nr+nr+1)
1463 numrank = idnint(work(2*n+n*nr+nr+2))
1465 CALL dcopy( nr, v(1,p), 1, u(1,p), 1 )
1466 CALL dscal( nr, sva(p), u(1,p), 1 )
1468 CALL dtrsm(
'L',
'U',
'N',
'N',nr,nr,one,work(2*n+1),n,u,ldu)
1472 work(2*n+n*nr+nr+iwork(n+p)) = u(p,q)
1475 u(p,q) = work(2*n+n*nr+nr+p)
1478 IF ( nr .LT. n )
THEN
1479 CALL dlaset(
'A',n-nr,nr,zero,zero,v(nr+1,1),ldv )
1480 CALL dlaset(
'A',nr,n-nr,zero,zero,v(1,nr+1),ldv )
1481 CALL dlaset(
'A',n-nr,n-nr,zero,one,v(nr+1,nr+1),ldv )
1483 CALL dormqr(
'L',
'N',n,n,nr,work(2*n+1),n,work(n+1),
1484 $ v,ldv,work(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr )
1497 CALL dgesvj(
'L',
'U',
'V', nr, nr, v, ldv, sva, nr, u,
1498 $ ldu, work(2*n+n*nr+nr+1), lwork-2*n-n*nr-nr, info )
1499 scalem = work(2*n+n*nr+nr+1)
1500 numrank = idnint(work(2*n+n*nr+nr+2))
1501 IF ( nr .LT. n )
THEN
1502 CALL dlaset(
'A',n-nr,nr,zero,zero,v(nr+1,1),ldv )
1503 CALL dlaset(
'A',nr,n-nr,zero,zero,v(1,nr+1),ldv )
1504 CALL dlaset(
'A',n-nr,n-nr,zero,one,v(nr+1,nr+1),ldv )
1506 CALL dormqr(
'L',
'N',n,n,nr,work(2*n+1),n,work(n+1),
1507 $ v,ldv,work(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr )
1509 CALL dormlq(
'L',
'T', nr, nr, nr, work(2*n+1), n,
1510 $ work(2*n+n*nr+1), u, ldu, work(2*n+n*nr+nr+1),
1511 $ lwork-2*n-n*nr-nr, ierr )
1514 work(2*n+n*nr+nr+iwork(n+p)) = u(p,q)
1517 u(p,q) = work(2*n+n*nr+nr+p)
1527 temp1 = dsqrt(dble(n)) * epsln
1530 work(2*n+n*nr+nr+iwork(p)) = v(p,q)
1533 v(p,q) = work(2*n+n*nr+nr+p)
1535 xsc = one / dnrm2( n, v(1,q), 1 )
1536 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1537 $
CALL dscal( n, xsc, v(1,q), 1 )
1541 IF ( nr .LT. m )
THEN
1542 CALL dlaset(
'A', m-nr, nr, zero, zero, u(nr+1,1), ldu )
1543 IF ( nr .LT. n1 )
THEN
1544 CALL dlaset(
'A',nr,n1-nr,zero,zero,u(1,nr+1),ldu)
1545 CALL dlaset(
'A',m-nr,n1-nr,zero,one,u(nr+1,nr+1),ldu)
1552 CALL dormqr(
'Left',
'No_Tr', m, n1, n, a, lda, work, u,
1553 $ ldu, work(n+1), lwork-n, ierr )
1556 temp1 = dsqrt(dble(m)) * epsln
1558 xsc = one / dnrm2( m, u(1,p), 1 )
1559 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1560 $
CALL dscal( m, xsc, u(1,p), 1 )
1567 $
CALL dlaswp( n1, u, ldu, 1, m-1, iwork(2*n+1), -1 )
1574 CALL dlacpy(
'Upper', n, n, a, lda, work(n+1), n )
1578 temp1 = xsc * work( n + (p-1)*n + p )
1579 DO 5971 q = 1, p - 1
1580 work(n+(q-1)*n+p)=-dsign(temp1,work(n+(p-1)*n+q))
1584 CALL dlaset(
'Lower',n-1,n-1,zero,zero,work(n+2),n )
1587 CALL dgesvj(
'Upper',
'U',
'N', n, n, work(n+1), n, sva,
1588 $ n, u, ldu, work(n+n*n+1), lwork-n-n*n, info )
1590 scalem = work(n+n*n+1)
1591 numrank = idnint(work(n+n*n+2))
1593 CALL dcopy( n, work(n+(p-1)*n+1), 1, u(1,p), 1 )
1594 CALL dscal( n, sva(p), work(n+(p-1)*n+1), 1 )
1597 CALL dtrsm(
'Left',
'Upper',
'NoTrans',
'No UD', n, n,
1598 $ one, a, lda, work(n+1), n )
1600 CALL dcopy( n, work(n+p), n, v(iwork(p),1), ldv )
1602 temp1 = dsqrt(dble(n))*epsln
1604 xsc = one / dnrm2( n, v(1,p), 1 )
1605 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1606 $
CALL dscal( n, xsc, v(1,p), 1 )
1611 IF ( n .LT. m )
THEN
1612 CALL dlaset(
'A', m-n, n, zero, zero, u(n+1,1), ldu )
1613 IF ( n .LT. n1 )
THEN
1614 CALL dlaset(
'A',n, n1-n, zero, zero, u(1,n+1),ldu )
1615 CALL dlaset(
'A',m-n,n1-n, zero, one,u(n+1,n+1),ldu )
1618 CALL dormqr(
'Left',
'No Tr', m, n1, n, a, lda, work, u,
1619 $ ldu, work(n+1), lwork-n, ierr )
1620 temp1 = dsqrt(dble(m))*epsln
1622 xsc = one / dnrm2( m, u(1,p), 1 )
1623 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1624 $
CALL dscal( m, xsc, u(1,p), 1 )
1628 $
CALL dlaswp( n1, u, ldu, 1, m-1, iwork(2*n+1), -1 )
1647 CALL dcopy( n-p+1, a(p,p), lda, v(p,p), 1 )
1651 xsc = dsqrt(small/epsln)
1653 temp1 = xsc*dabs( v(q,q) )
1655 IF ( ( p .GT. q ) .AND. ( dabs(v(p,q)) .LE. temp1 )
1656 $ .OR. ( p .LT. q ) )
1657 $ v(p,q) = dsign( temp1, v(p,q) )
1658 IF ( p .LT. q ) v(p,q) = - v(p,q)
1662 CALL dlaset(
'U', nr-1, nr-1, zero, zero, v(1,2), ldv )
1665 CALL dgeqrf( n, nr, v, ldv, work(n+1), work(2*n+1),
1667 CALL dlacpy(
'L', n, nr, v, ldv, work(2*n+1), n )
1670 CALL dcopy( nr-p+1, v(p,p), ldv, u(p,p), 1 )
1674 xsc = dsqrt(small/epsln)
1676 DO 9971 p = 1, q - 1
1677 temp1 = xsc * min(dabs(u(p,p)),dabs(u(q,q)))
1678 u(p,q) = - dsign( temp1, u(q,p) )
1682 CALL dlaset(
'U', nr-1, nr-1, zero, zero, u(1,2), ldu )
1685 CALL dgesvj(
'G',
'U',
'V', nr, nr, u, ldu, sva,
1686 $ n, v, ldv, work(2*n+n*nr+1), lwork-2*n-n*nr, info )
1687 scalem = work(2*n+n*nr+1)
1688 numrank = idnint(work(2*n+n*nr+2))
1690 IF ( nr .LT. n )
THEN
1691 CALL dlaset(
'A',n-nr,nr,zero,zero,v(nr+1,1),ldv )
1692 CALL dlaset(
'A',nr,n-nr,zero,zero,v(1,nr+1),ldv )
1693 CALL dlaset(
'A',n-nr,n-nr,zero,one,v(nr+1,nr+1),ldv )
1696 CALL dormqr(
'L',
'N',n,n,nr,work(2*n+1),n,work(n+1),
1697 $ v,ldv,work(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr )
1703 temp1 = dsqrt(dble(n)) * epsln
1706 work(2*n+n*nr+nr+iwork(p)) = v(p,q)
1709 v(p,q) = work(2*n+n*nr+nr+p)
1711 xsc = one / dnrm2( n, v(1,q), 1 )
1712 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1713 $
CALL dscal( n, xsc, v(1,q), 1 )
1719 IF ( nr .LT. m )
THEN
1720 CALL dlaset(
'A', m-nr, nr, zero, zero, u(nr+1,1), ldu )
1721 IF ( nr .LT. n1 )
THEN
1722 CALL dlaset(
'A',nr, n1-nr, zero, zero, u(1,nr+1),ldu )
1723 CALL dlaset(
'A',m-nr,n1-nr, zero, one,u(nr+1,nr+1),ldu )
1727 CALL dormqr(
'Left',
'No Tr', m, n1, n, a, lda, work, u,
1728 $ ldu, work(n+1), lwork-n, ierr )
1731 $
CALL dlaswp( n1, u, ldu, 1, m-1, iwork(2*n+1), -1 )
1738 CALL dswap( n, u(1,p), 1, v(1,p), 1 )
1747 IF ( uscal2 .LE. (big/sva(1))*uscal1 )
THEN
1748 CALL dlascl(
'G', 0, 0, uscal1, uscal2, nr, 1, sva, n, ierr )
1753 IF ( nr .LT. n )
THEN
1759 work(1) = uscal2 * scalem
1761 IF ( errest ) work(3) = sconda
1762 IF ( lsvec .AND. rsvec )
THEN
subroutine xerbla(srname, info)
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
subroutine dgejsv(joba, jobu, jobv, jobr, jobt, jobp, m, n, a, lda, sva, u, ldu, v, ldv, work, lwork, iwork, info)
DGEJSV
subroutine dgelqf(m, n, a, lda, tau, work, lwork, info)
DGELQF
subroutine dgeqp3(m, n, a, lda, jpvt, tau, work, lwork, info)
DGEQP3
subroutine dgeqrf(m, n, a, lda, tau, work, lwork, info)
DGEQRF
subroutine dgesvj(joba, jobu, jobv, m, n, a, lda, sva, mv, v, ldv, work, lwork, info)
DGESVJ
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
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 dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine dlassq(n, x, incx, scale, sumsq)
DLASSQ updates a sum of squares represented in scaled form.
subroutine dlaswp(n, a, lda, k1, k2, ipiv, incx)
DLASWP performs a series of row interchanges on a general rectangular matrix.
subroutine dpocon(uplo, n, a, lda, anorm, rcond, work, iwork, info)
DPOCON
subroutine dscal(n, da, dx, incx)
DSCAL
subroutine dswap(n, dx, incx, dy, incy)
DSWAP
subroutine dtrsm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
DTRSM
subroutine dorgqr(m, n, k, a, lda, tau, work, lwork, info)
DORGQR
subroutine dormlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMLQ
subroutine dormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMQR