471 SUBROUTINE dgejsv( JOBA, JOBU, JOBV, JOBR, JOBT, JOBP,
472 $ M, N, A, LDA, SVA, U, LDU, V, LDV,
473 $ WORK, LWORK, IWORK, INFO )
481 INTEGER INFO, LDA, LDU, LDV, LWORK, M, N
484 DOUBLE PRECISION A( LDA, * ), SVA( N ), U( LDU, * ), V( LDV, * ),
487 CHARACTER*1 JOBA, JOBP, JOBR, JOBT, JOBU, JOBV
493 DOUBLE PRECISION ZERO, ONE
494 PARAMETER ( ZERO = 0.0d0, one = 1.0d0 )
497 DOUBLE PRECISION AAPP, AAQQ, AATMAX, AATMIN, BIG, BIG1, COND_OK,
498 $ CONDR1, CONDR2, ENTRA, ENTRAT, EPSLN, MAXPRJ, SCALEM,
499 $ sconda, sfmin, small, temp1, uscal1, uscal2, xsc
500 INTEGER IERR, N1, NR, NUMRANK, p, q, WARNING
501 LOGICAL ALMORT, DEFR, ERREST, GOSCAL, JRACC, KILL, LSVEC,
502 $ l2aber, l2kill, l2pert, l2rank, l2tran,
503 $ noscal, rowpiv, rsvec, transp
506 INTRINSIC dabs, dlog, max, min, dble, idnint, dsign, dsqrt
509 DOUBLE PRECISION DLAMCH, DNRM2
512 EXTERNAL idamax, lsame, dlamch, dnrm2
525 lsvec = lsame( jobu,
'U' ) .OR. lsame( jobu,
'F' )
526 jracc = lsame( jobv,
'J' )
527 rsvec = lsame( jobv,
'V' ) .OR. jracc
528 rowpiv = lsame( joba,
'F' ) .OR. lsame( joba,
'G' )
529 l2rank = lsame( joba,
'R' )
530 l2aber = lsame( joba,
'A' )
531 errest = lsame( joba,
'E' ) .OR. lsame( joba,
'G' )
532 l2tran = lsame( jobt,
'T' )
533 l2kill = lsame( jobr,
'R' )
534 defr = lsame( jobr,
'N' )
535 l2pert = lsame( jobp,
'P' )
537 IF ( .NOT.(rowpiv .OR. l2rank .OR. l2aber .OR.
538 $ errest .OR. lsame( joba,
'C' ) ))
THEN
540 ELSE IF ( .NOT.( lsvec .OR. lsame( jobu,
'N' ) .OR.
541 $ lsame( jobu,
'W' )) )
THEN
543 ELSE IF ( .NOT.( rsvec .OR. lsame( jobv,
'N' ) .OR.
544 $ lsame( jobv,
'W' )) .OR. ( jracc .AND. (.NOT.lsvec) ) )
THEN
546 ELSE IF ( .NOT. ( l2kill .OR. defr ) )
THEN
548 ELSE IF ( .NOT. ( l2tran .OR. lsame( jobt,
'N' ) ) )
THEN
550 ELSE IF ( .NOT. ( l2pert .OR. lsame( jobp,
'N' ) ) )
THEN
552 ELSE IF ( m .LT. 0 )
THEN
554 ELSE IF ( ( n .LT. 0 ) .OR. ( n .GT. m ) )
THEN
556 ELSE IF ( lda .LT. m )
THEN
558 ELSE IF ( lsvec .AND. ( ldu .LT. m ) )
THEN
560 ELSE IF ( rsvec .AND. ( ldv .LT. n ) )
THEN
562 ELSE IF ( (.NOT.(lsvec .OR. rsvec .OR. errest).AND.
563 & (lwork .LT. max(7,4*n+1,2*m+n))) .OR.
564 & (.NOT.(lsvec .OR. rsvec) .AND. errest .AND.
565 & (lwork .LT. max(7,4*n+n*n,2*m+n))) .OR.
566 & (lsvec .AND. (.NOT.rsvec) .AND. (lwork .LT. max(7,2*m+n,4*n+1)))
568 & (rsvec .AND. (.NOT.lsvec) .AND. (lwork .LT. max(7,2*m+n,4*n+1)))
570 & (lsvec .AND. rsvec .AND. (.NOT.jracc) .AND.
571 & (lwork.LT.max(2*m+n,6*n+2*n*n)))
572 & .OR. (lsvec .AND. rsvec .AND. jracc .AND.
573 & lwork.LT.max(2*m+n,4*n+n*n,2*n+n*n+6)))
581 IF ( info .NE. 0 )
THEN
583 CALL xerbla(
'DGEJSV', - info )
589 IF ( ( m .EQ. 0 ) .OR. ( n .EQ. 0 ) )
THEN
599 IF ( lsame( jobu,
'F' ) ) n1 = m
606 epsln = dlamch(
'Epsilon')
607 sfmin = dlamch(
'SafeMinimum')
608 small = sfmin / epsln
618 scalem = one / dsqrt(dble(m)*dble(n))
624 CALL dlassq( m, a(1,p), 1, aapp, aaqq )
625 IF ( aapp .GT. big )
THEN
627 CALL xerbla(
'DGEJSV', -info )
631 IF ( ( aapp .LT. (big / aaqq) ) .AND. noscal )
THEN
635 sva(p) = aapp * ( aaqq * scalem )
638 CALL dscal( p-1, scalem, sva, 1 )
643 IF ( noscal ) scalem = one
648 aapp = max( aapp, sva(p) )
649 IF ( sva(p) .NE. zero ) aaqq = min( aaqq, sva(p) )
654 IF ( aapp .EQ. zero )
THEN
655 IF ( lsvec )
CALL dlaset(
'G', m, n1, zero, one, u, ldu )
656 IF ( rsvec )
CALL dlaset(
'G', n, n, zero, one, v, ldv )
659 IF ( errest ) work(3) = one
660 IF ( lsvec .AND. rsvec )
THEN
679 IF ( aaqq .LE. sfmin )
THEN
690 CALL dlascl(
'G',0,0,sva(1),scalem, m,1,a(1,1),lda,ierr )
691 CALL dlacpy(
'A', m, 1, a, lda, u, ldu )
693 IF ( n1 .NE. n )
THEN
694 CALL dgeqrf( m, n, u,ldu, work, work(n+1),lwork-n,
696 CALL dorgqr( m,n1,1, u,ldu,work,work(n+1),lwork-n,
698 CALL dcopy( m, a(1,1), 1, u(1,1), 1 )
704 IF ( sva(1) .LT. (big*scalem) )
THEN
705 sva(1) = sva(1) / scalem
708 work(1) = one / scalem
710 IF ( sva(1) .NE. zero )
THEN
712 IF ( ( sva(1) / scalem) .GE. sfmin )
THEN
722 IF ( errest ) work(3) = one
723 IF ( lsvec .AND. rsvec )
THEN
736 l2tran = l2tran .AND. ( m .EQ. n )
740 IF ( rowpiv .OR. l2tran )
THEN
751 CALL dlassq( n, a(p,1), lda, xsc, temp1 )
754 work(m+n+p) = xsc * scalem
755 work(n+p) = xsc * (scalem*dsqrt(temp1))
756 aatmax = max( aatmax, work(n+p) )
757 IF (work(n+p) .NE. zero) aatmin = min(aatmin,work(n+p))
761 work(m+n+p) = scalem*dabs( a(p,idamax(n,a(p,1),lda)) )
762 aatmax = max( aatmax, work(m+n+p) )
763 aatmin = min( aatmin, work(m+n+p) )
782 CALL dlassq( n, sva, 1, xsc, temp1 )
787 big1 = ( ( sva(p) / xsc )**2 ) * temp1
788 IF ( big1 .NE. zero ) entra = entra + big1 * dlog(big1)
790 entra = - entra / dlog(dble(n))
800 big1 = ( ( work(p) / xsc )**2 ) * temp1
801 IF ( big1 .NE. zero ) entrat = entrat + big1 * dlog(big1)
803 entrat = - entrat / dlog(dble(m))
808 transp = ( entrat .LT. entra )
854 temp1 = dsqrt( big / dble(n) )
856 CALL dlascl(
'G', 0, 0, aapp, temp1, n, 1, sva, n, ierr )
857 IF ( aaqq .GT. (aapp * sfmin) )
THEN
858 aaqq = ( aaqq / aapp ) * temp1
860 aaqq = ( aaqq * temp1 ) / aapp
862 temp1 = temp1 * scalem
863 CALL dlascl(
'G', 0, 0, aapp, temp1, m, n, a, lda, ierr )
887 IF ( ( aaqq.LT.dsqrt(sfmin) ) .AND. lsvec .AND. rsvec )
THEN
892 IF ( aaqq .LT. xsc )
THEN
894 IF ( sva(p) .LT. xsc )
THEN
895 CALL dlaset(
'A', m, 1, zero, zero, a(1,p), lda )
910 q = idamax( m-p+1, work(m+n+p), 1 ) + p - 1
914 work(m+n+p) = work(m+n+q)
918 CALL dlaswp( n, a, lda, 1, m-1, iwork(2*n+1), 1 )
940 CALL dgeqp3( m,n,a,lda, iwork,work, work(n+1),lwork-n, ierr )
956 temp1 = dsqrt(dble(n))*epsln
958 IF ( dabs(a(p,p)) .GE. (temp1*dabs(a(1,1))) )
THEN
965 ELSE IF ( l2rank )
THEN
971 IF ( ( dabs(a(p,p)) .LT. (epsln*dabs(a(p-1,p-1))) ) .OR.
972 $ ( dabs(a(p,p)) .LT. small ) .OR.
973 $ ( l2kill .AND. (dabs(a(p,p)) .LT. temp1) ) )
GO TO 3402
988 IF ( ( dabs(a(p,p)) .LT. small ) .OR.
989 $ ( l2kill .AND. (dabs(a(p,p)) .LT. temp1) ) )
GO TO 3302
997 IF ( nr .EQ. n )
THEN
1000 temp1 = dabs(a(p,p)) / sva(iwork(p))
1001 maxprj = min( maxprj, temp1 )
1003 IF ( maxprj**2 .GE. one - dble(n)*epsln ) almort = .true.
1012 IF ( n .EQ. nr )
THEN
1015 CALL dlacpy(
'U', n, n, a, lda, v, ldv )
1017 temp1 = sva(iwork(p))
1018 CALL dscal( p, one/temp1, v(1,p), 1 )
1020 CALL dpocon(
'U', n, v, ldv, one, temp1,
1021 $ work(n+1), iwork(2*n+m+1), ierr )
1022 ELSE IF ( lsvec )
THEN
1024 CALL dlacpy(
'U', n, n, a, lda, u, ldu )
1026 temp1 = sva(iwork(p))
1027 CALL dscal( p, one/temp1, u(1,p), 1 )
1029 CALL dpocon(
'U', n, u, ldu, one, temp1,
1030 $ work(n+1), iwork(2*n+m+1), ierr )
1032 CALL dlacpy(
'U', n, n, a, lda, work(n+1), n )
1034 temp1 = sva(iwork(p))
1035 CALL dscal( p, one/temp1, work(n+(p-1)*n+1), 1 )
1038 CALL dpocon(
'U', n, work(n+1), n, one, temp1,
1039 $ work(n+n*n+1), iwork(2*n+m+1), ierr )
1041 sconda = one / dsqrt(temp1)
1049 l2pert = l2pert .AND. ( dabs( a(1,1)/a(nr,nr) ) .GT. dsqrt(big1) )
1054 IF ( .NOT. ( rsvec .OR. lsvec ) )
THEN
1059 DO 1946 p = 1, min( n-1, nr )
1060 CALL dcopy( n-p, a(p,p+1), lda, a(p+1,p), 1 )
1075 IF ( .NOT. almort )
THEN
1079 xsc = epsln / dble(n)
1081 temp1 = xsc*dabs(a(q,q))
1083 IF ( ( (p.GT.q) .AND. (dabs(a(p,q)).LE.temp1) )
1084 $ .OR. ( p .LT. q ) )
1085 $ a(p,q) = dsign( temp1, a(p,q) )
1089 CALL dlaset(
'U', nr-1,nr-1, zero,zero, a(1,2),lda )
1094 CALL dgeqrf( n,nr, a,lda, work, work(n+1),lwork-n, ierr )
1097 DO 1948 p = 1, nr - 1
1098 CALL dcopy( nr-p, a(p,p+1), lda, a(p+1,p), 1 )
1109 xsc = epsln / dble(n)
1111 temp1 = xsc*dabs(a(q,q))
1113 IF ( ( (p.GT.q) .AND. (dabs(a(p,q)).LE.temp1) )
1114 $ .OR. ( p .LT. q ) )
1115 $ a(p,q) = dsign( temp1, a(p,q) )
1119 CALL dlaset(
'U', nr-1, nr-1, zero, zero, a(1,2),
1127 CALL dgesvj(
'L',
'NoU',
'NoV', nr, nr, a, lda, sva,
1128 $ n, v, ldv, work, lwork, info )
1131 numrank = idnint(work(2))
1134 ELSE IF ( rsvec .AND. ( .NOT. lsvec ) )
THEN
1142 CALL dcopy( n-p+1, a(p,p), lda, v(p,p), 1 )
1144 CALL dlaset(
'Upper', nr-1, nr-1, zero, zero, v(1,2),
1147 CALL dgesvj(
'L',
'U',
'N', n, nr, v,ldv, sva, nr, a,lda,
1148 $ work, lwork, info )
1150 numrank = idnint(work(2))
1157 CALL dlaset(
'Lower', nr-1, nr-1, zero, zero, a(2,1),
1159 CALL dgelqf( nr, n, a, lda, work, work(n+1), lwork-n,
1161 CALL dlacpy(
'Lower', nr, nr, a, lda, v, ldv )
1162 CALL dlaset(
'Upper', nr-1, nr-1, zero, zero, v(1,2),
1164 CALL dgeqrf( nr, nr, v, ldv, work(n+1), work(2*n+1),
1167 CALL dcopy( nr-p+1, v(p,p), ldv, v(p,p), 1 )
1169 CALL dlaset(
'Upper', nr-1, nr-1, zero, zero, v(1,2),
1172 CALL dgesvj(
'Lower',
'U',
'N', nr, nr, v,ldv, sva, nr, u,
1173 $ ldu, work(n+1), lwork, info )
1175 numrank = idnint(work(n+2))
1176 IF ( nr .LT. n )
THEN
1177 CALL dlaset(
'A',n-nr, nr, zero,zero, v(nr+1,1),
1179 CALL dlaset(
'A',nr, n-nr, zero,zero, v(1,nr+1),
1181 CALL dlaset(
'A',n-nr,n-nr,zero,one, v(nr+1,nr+1),
1185 CALL dormlq(
'Left',
'Transpose', n, n, nr, a, lda, work,
1186 $ v, ldv, work(n+1), lwork-n, ierr )
1191 CALL dcopy( n, v(p,1), ldv, a(iwork(p),1), lda )
1193 CALL dlacpy(
'All', n, n, a, lda, v, ldv )
1196 CALL dlacpy(
'All', n, n, v, ldv, u, ldu )
1199 ELSE IF ( lsvec .AND. ( .NOT. rsvec ) )
THEN
1206 CALL dcopy( n-p+1, a(p,p), lda, u(p,p), 1 )
1208 CALL dlaset(
'Upper', nr-1, nr-1, zero, zero, u(1,2), ldu )
1210 CALL dgeqrf( n, nr, u, ldu, work(n+1), work(2*n+1),
1213 DO 1967 p = 1, nr - 1
1214 CALL dcopy( nr-p, u(p,p+1), ldu, u(p+1,p), 1 )
1216 CALL dlaset(
'Upper', nr-1, nr-1, zero, zero, u(1,2), ldu )
1218 CALL dgesvj(
'Lower',
'U',
'N', nr,nr, u, ldu, sva, nr, a,
1219 $ lda, work(n+1), lwork-n, info )
1221 numrank = idnint(work(n+2))
1223 IF ( nr .LT. m )
THEN
1224 CALL dlaset(
'A', m-nr, nr,zero, zero, u(nr+1,1), ldu )
1225 IF ( nr .LT. n1 )
THEN
1226 CALL dlaset(
'A',nr, n1-nr, zero, zero, u(1,nr+1),
1228 CALL dlaset(
'A',m-nr,n1-nr,zero,one,u(nr+1,nr+1),
1233 CALL dormqr(
'Left',
'No Tr', m, n1, n, a, lda, work, u,
1234 $ ldu, work(n+1), lwork-n, ierr )
1237 $
CALL dlaswp( n1, u, ldu, 1, m-1, iwork(2*n+1), -1 )
1240 xsc = one / dnrm2( m, u(1,p), 1 )
1241 CALL dscal( m, xsc, u(1,p), 1 )
1245 CALL dlacpy(
'All', n, n, u, ldu, v, ldv )
1252 IF ( .NOT. jracc )
THEN
1254 IF ( .NOT. almort )
THEN
1264 CALL dcopy( n-p+1, a(p,p), lda, v(p,p), 1 )
1282 temp1 = xsc*dabs( v(q,q) )
1284 IF ( ( p .GT. q ) .AND. ( dabs(v(p,q)) .LE. temp1 )
1285 $ .OR. ( p .LT. q ) )
1286 $ v(p,q) = dsign( temp1, v(p,q) )
1287 IF ( p .LT. q ) v(p,q) = - v(p,q)
1291 CALL dlaset(
'U', nr-1, nr-1, zero, zero, v(1,2),
1299 CALL dlacpy(
'L', nr, nr, v, ldv, work(2*n+1), nr )
1301 temp1 = dnrm2(nr-p+1,work(2*n+(p-1)*nr+p),1)
1302 CALL dscal(nr-p+1,one/temp1,work(2*n+(p-1)*nr+p),1)
1304 CALL dpocon(
'Lower',nr,work(2*n+1),nr,one,temp1,
1305 $ work(2*n+nr*nr+1),iwork(m+2*n+1),ierr)
1306 condr1 = one / dsqrt(temp1)
1312 cond_ok = dsqrt(dble(nr))
1315 IF ( condr1 .LT. cond_ok )
THEN
1320 CALL dgeqrf( n, nr, v, ldv, work(n+1), work(2*n+1),
1324 xsc = dsqrt(small)/epsln
1326 DO 3958 q = 1, p - 1
1327 temp1 = xsc * min(dabs(v(p,p)),dabs(v(q,q)))
1328 IF ( dabs(v(q,p)) .LE. temp1 )
1329 $ v(q,p) = dsign( temp1, v(q,p) )
1335 $
CALL dlacpy(
'A', n, nr, v, ldv, work(2*n+1), n )
1339 DO 1969 p = 1, nr - 1
1340 CALL dcopy( nr-p, v(p,p+1), ldv, v(p+1,p), 1 )
1358 CALL dgeqp3( n, nr, v, ldv, iwork(n+1), work(n+1),
1359 $ work(2*n+1), lwork-2*n, ierr )
1365 DO 3968 q = 1, p - 1
1366 temp1 = xsc * min(dabs(v(p,p)),dabs(v(q,q)))
1367 IF ( dabs(v(q,p)) .LE. temp1 )
1368 $ v(q,p) = dsign( temp1, v(q,p) )
1373 CALL dlacpy(
'A', n, nr, v, ldv, work(2*n+1), n )
1378 DO 8971 q = 1, p - 1
1379 temp1 = xsc * min(dabs(v(p,p)),dabs(v(q,q)))
1380 v(p,q) = - dsign( temp1, v(q,p) )
1384 CALL dlaset(
'L',nr-1,nr-1,zero,zero,v(2,1),ldv )
1387 CALL dgelqf( nr, nr, v, ldv, work(2*n+n*nr+1),
1388 $ work(2*n+n*nr+nr+1), lwork-2*n-n*nr-nr, ierr )
1390 CALL dlacpy(
'L',nr,nr,v,ldv,work(2*n+n*nr+nr+1),nr )
1392 temp1 = dnrm2( p, work(2*n+n*nr+nr+p), nr )
1393 CALL dscal( p, one/temp1, work(2*n+n*nr+nr+p), nr )
1395 CALL dpocon(
'L',nr,work(2*n+n*nr+nr+1),nr,one,temp1,
1396 $ work(2*n+n*nr+nr+nr*nr+1),iwork(m+2*n+1),ierr )
1397 condr2 = one / dsqrt(temp1)
1399 IF ( condr2 .GE. cond_ok )
THEN
1404 CALL dlacpy(
'U', nr, nr, v, ldv, work(2*n+1), n )
1414 temp1 = xsc * v(q,q)
1415 DO 4969 p = 1, q - 1
1417 v(p,q) = - dsign( temp1, v(p,q) )
1421 CALL dlaset(
'U', nr-1,nr-1, zero,zero, v(1,2), ldv )
1430 IF ( condr1 .LT. cond_ok )
THEN
1432 CALL dgesvj(
'L',
'U',
'N',nr,nr,v,ldv,sva,nr,u,
1433 $ ldu,work(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,info )
1434 scalem = work(2*n+n*nr+nr+1)
1435 numrank = idnint(work(2*n+n*nr+nr+2))
1437 CALL dcopy( nr, v(1,p), 1, u(1,p), 1 )
1438 CALL dscal( nr, sva(p), v(1,p), 1 )
1443 IF ( nr .EQ. n )
THEN
1448 CALL dtrsm(
'L',
'U',
'N',
'N', nr,nr,one, a,lda, v,
1455 CALL dtrsm(
'L',
'U',
'T',
'N',nr,nr,one,work(2*n+1),
1457 IF ( nr .LT. n )
THEN
1458 CALL dlaset(
'A',n-nr,nr,zero,zero,v(nr+1,1),ldv)
1459 CALL dlaset(
'A',nr,n-nr,zero,zero,v(1,nr+1),ldv)
1460 CALL dlaset(
'A',n-nr,n-nr,zero,one,v(nr+1,nr+1),
1463 CALL dormqr(
'L',
'N',n,n,nr,work(2*n+1),n,work(n+1),
1464 $ v,ldv,work(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr)
1467 ELSE IF ( condr2 .LT. cond_ok )
THEN
1475 CALL dgesvj(
'L',
'U',
'N', nr, nr, v, ldv, sva, nr,
1477 $ ldu, work(2*n+n*nr+nr+1), lwork-2*n-n*nr-nr, info )
1478 scalem = work(2*n+n*nr+nr+1)
1479 numrank = idnint(work(2*n+n*nr+nr+2))
1481 CALL dcopy( nr, v(1,p), 1, u(1,p), 1 )
1482 CALL dscal( nr, sva(p), u(1,p), 1 )
1484 CALL dtrsm(
'L',
'U',
'N',
'N',nr,nr,one,work(2*n+1),n,u,
1489 work(2*n+n*nr+nr+iwork(n+p)) = u(p,q)
1492 u(p,q) = work(2*n+n*nr+nr+p)
1495 IF ( nr .LT. n )
THEN
1496 CALL dlaset(
'A',n-nr,nr,zero,zero,v(nr+1,1),ldv )
1497 CALL dlaset(
'A',nr,n-nr,zero,zero,v(1,nr+1),ldv )
1498 CALL dlaset(
'A',n-nr,n-nr,zero,one,v(nr+1,nr+1),
1501 CALL dormqr(
'L',
'N',n,n,nr,work(2*n+1),n,work(n+1),
1502 $ v,ldv,work(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr )
1515 CALL dgesvj(
'L',
'U',
'V', nr, nr, v, ldv, sva, nr,
1517 $ ldu, work(2*n+n*nr+nr+1), lwork-2*n-n*nr-nr, info )
1518 scalem = work(2*n+n*nr+nr+1)
1519 numrank = idnint(work(2*n+n*nr+nr+2))
1520 IF ( nr .LT. n )
THEN
1521 CALL dlaset(
'A',n-nr,nr,zero,zero,v(nr+1,1),ldv )
1522 CALL dlaset(
'A',nr,n-nr,zero,zero,v(1,nr+1),ldv )
1523 CALL dlaset(
'A',n-nr,n-nr,zero,one,v(nr+1,nr+1),
1526 CALL dormqr(
'L',
'N',n,n,nr,work(2*n+1),n,work(n+1),
1527 $ v,ldv,work(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr )
1529 CALL dormlq(
'L',
'T', nr, nr, nr, work(2*n+1), n,
1530 $ work(2*n+n*nr+1), u, ldu, work(2*n+n*nr+nr+1),
1531 $ lwork-2*n-n*nr-nr, ierr )
1534 work(2*n+n*nr+nr+iwork(n+p)) = u(p,q)
1537 u(p,q) = work(2*n+n*nr+nr+p)
1547 temp1 = dsqrt(dble(n)) * epsln
1550 work(2*n+n*nr+nr+iwork(p)) = v(p,q)
1553 v(p,q) = work(2*n+n*nr+nr+p)
1555 xsc = one / dnrm2( n, v(1,q), 1 )
1556 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1557 $
CALL dscal( n, xsc, v(1,q), 1 )
1561 IF ( nr .LT. m )
THEN
1562 CALL dlaset(
'A', m-nr, nr, zero, zero, u(nr+1,1),
1564 IF ( nr .LT. n1 )
THEN
1565 CALL dlaset(
'A',nr,n1-nr,zero,zero,u(1,nr+1),ldu)
1566 CALL dlaset(
'A',m-nr,n1-nr,zero,one,u(nr+1,nr+1),
1574 CALL dormqr(
'Left',
'No_Tr', m, n1, n, a, lda, work, u,
1575 $ ldu, work(n+1), lwork-n, ierr )
1578 temp1 = dsqrt(dble(m)) * epsln
1580 xsc = one / dnrm2( m, u(1,p), 1 )
1581 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1582 $
CALL dscal( m, xsc, u(1,p), 1 )
1589 $
CALL dlaswp( n1, u, ldu, 1, m-1, iwork(2*n+1), -1 )
1596 CALL dlacpy(
'Upper', n, n, a, lda, work(n+1), n )
1600 temp1 = xsc * work( n + (p-1)*n + p )
1601 DO 5971 q = 1, p - 1
1602 work(n+(q-1)*n+p)=-dsign(temp1,work(n+(p-1)*n+q))
1606 CALL dlaset(
'Lower',n-1,n-1,zero,zero,work(n+2),n )
1609 CALL dgesvj(
'Upper',
'U',
'N', n, n, work(n+1), n, sva,
1610 $ n, u, ldu, work(n+n*n+1), lwork-n-n*n, info )
1612 scalem = work(n+n*n+1)
1613 numrank = idnint(work(n+n*n+2))
1615 CALL dcopy( n, work(n+(p-1)*n+1), 1, u(1,p), 1 )
1616 CALL dscal( n, sva(p), work(n+(p-1)*n+1), 1 )
1619 CALL dtrsm(
'Left',
'Upper',
'NoTrans',
'No UD', n, n,
1620 $ one, a, lda, work(n+1), n )
1622 CALL dcopy( n, work(n+p), n, v(iwork(p),1), ldv )
1624 temp1 = dsqrt(dble(n))*epsln
1626 xsc = one / dnrm2( n, v(1,p), 1 )
1627 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1628 $
CALL dscal( n, xsc, v(1,p), 1 )
1633 IF ( n .LT. m )
THEN
1634 CALL dlaset(
'A', m-n, n, zero, zero, u(n+1,1), ldu )
1635 IF ( n .LT. n1 )
THEN
1636 CALL dlaset(
'A',n, n1-n, zero, zero, u(1,n+1),
1638 CALL dlaset(
'A',m-n,n1-n, zero, one,u(n+1,n+1),
1642 CALL dormqr(
'Left',
'No Tr', m, n1, n, a, lda, work, u,
1643 $ ldu, work(n+1), lwork-n, ierr )
1644 temp1 = dsqrt(dble(m))*epsln
1646 xsc = one / dnrm2( m, u(1,p), 1 )
1647 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1648 $
CALL dscal( m, xsc, u(1,p), 1 )
1652 $
CALL dlaswp( n1, u, ldu, 1, m-1, iwork(2*n+1), -1 )
1671 CALL dcopy( n-p+1, a(p,p), lda, v(p,p), 1 )
1675 xsc = dsqrt(small/epsln)
1677 temp1 = xsc*dabs( v(q,q) )
1679 IF ( ( p .GT. q ) .AND. ( dabs(v(p,q)) .LE. temp1 )
1680 $ .OR. ( p .LT. q ) )
1681 $ v(p,q) = dsign( temp1, v(p,q) )
1682 IF ( p .LT. q ) v(p,q) = - v(p,q)
1686 CALL dlaset(
'U', nr-1, nr-1, zero, zero, v(1,2), ldv )
1689 CALL dgeqrf( n, nr, v, ldv, work(n+1), work(2*n+1),
1691 CALL dlacpy(
'L', n, nr, v, ldv, work(2*n+1), n )
1694 CALL dcopy( nr-p+1, v(p,p), ldv, u(p,p), 1 )
1698 xsc = dsqrt(small/epsln)
1700 DO 9971 p = 1, q - 1
1701 temp1 = xsc * min(dabs(u(p,p)),dabs(u(q,q)))
1702 u(p,q) = - dsign( temp1, u(q,p) )
1706 CALL dlaset(
'U', nr-1, nr-1, zero, zero, u(1,2), ldu )
1709 CALL dgesvj(
'G',
'U',
'V', nr, nr, u, ldu, sva,
1710 $ n, v, ldv, work(2*n+n*nr+1), lwork-2*n-n*nr, info )
1711 scalem = work(2*n+n*nr+1)
1712 numrank = idnint(work(2*n+n*nr+2))
1714 IF ( nr .LT. n )
THEN
1715 CALL dlaset(
'A',n-nr,nr,zero,zero,v(nr+1,1),ldv )
1716 CALL dlaset(
'A',nr,n-nr,zero,zero,v(1,nr+1),ldv )
1717 CALL dlaset(
'A',n-nr,n-nr,zero,one,v(nr+1,nr+1),ldv )
1720 CALL dormqr(
'L',
'N',n,n,nr,work(2*n+1),n,work(n+1),
1721 $ v,ldv,work(2*n+n*nr+nr+1),lwork-2*n-n*nr-nr,ierr )
1727 temp1 = dsqrt(dble(n)) * epsln
1730 work(2*n+n*nr+nr+iwork(p)) = v(p,q)
1733 v(p,q) = work(2*n+n*nr+nr+p)
1735 xsc = one / dnrm2( n, v(1,q), 1 )
1736 IF ( (xsc .LT. (one-temp1)) .OR. (xsc .GT. (one+temp1)) )
1737 $
CALL dscal( n, xsc, v(1,q), 1 )
1743 IF ( nr .LT. m )
THEN
1744 CALL dlaset(
'A', m-nr, nr, zero, zero, u(nr+1,1), ldu )
1745 IF ( nr .LT. n1 )
THEN
1746 CALL dlaset(
'A',nr, n1-nr, zero, zero, u(1,nr+1),
1748 CALL dlaset(
'A',m-nr,n1-nr, zero, one,u(nr+1,nr+1),
1753 CALL dormqr(
'Left',
'No Tr', m, n1, n, a, lda, work, u,
1754 $ ldu, work(n+1), lwork-n, ierr )
1757 $
CALL dlaswp( n1, u, ldu, 1, m-1, iwork(2*n+1), -1 )
1764 CALL dswap( n, u(1,p), 1, v(1,p), 1 )
1773 IF ( uscal2 .LE. (big/sva(1))*uscal1 )
THEN
1774 CALL dlascl(
'G', 0, 0, uscal1, uscal2, nr, 1, sva, n,
1780 IF ( nr .LT. n )
THEN
1786 work(1) = uscal2 * scalem
1788 IF ( errest ) work(3) = sconda
1789 IF ( lsvec .AND. rsvec )
THEN