216 SUBROUTINE dgsvj0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS,
217 $ SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )
224 INTEGER INFO, LDA, LDV, LWORK, M, MV, N, NSWEEP
225 DOUBLE PRECISION EPS, SFMIN, TOL
229 DOUBLE PRECISION A( LDA, * ), SVA( N ), D( N ), V( LDV, * ),
236 DOUBLE PRECISION ZERO, HALF, ONE
237 parameter( zero = 0.0d0, half = 0.5d0, one = 1.0d0)
240 DOUBLE PRECISION AAPP, AAPP0, AAPQ, AAQQ, APOAQ, AQOAP, BIG,
241 $ bigtheta, cs, mxaapq, mxsinj, rootbig, rooteps,
242 $ rootsfmin, roottol, small, sn, t, temp1, theta,
244 INTEGER BLSKIP, EMPTSW, , ibr, IERR, igl, IJBLSK, ir1,
245 $ iswrot, jbc, jgl, kbl, lkahead, mvl, nbl,
246 $ notrot, p, pskipped, q, rowskip, swband
247 LOGICAL APPLV, ROTOK, RSVEC
250 DOUBLE PRECISION FASTR( 5 )
253 INTRINSIC dabs,
max, dble,
min, dsign, dsqrt
256 DOUBLE PRECISION DDOT, DNRM2
259 EXTERNAL idamax, lsame, ddot, dnrm2
269 applv = lsame( jobv,
'A' )
270 rsvec = lsame( jobv,
'V' )
271 IF( .NOT.( rsvec .OR. applv .OR. lsame( jobv,
'N'THEN
273 ELSE IF( m.LT.0 )
THEN
275 ELSE IF( ( n.LT.0 ) .OR. ( n.GT.m ) )
THEN
277 ELSE IF( lda.LT.m )
THEN
279 ELSE IF( ( rsvec.OR.applv ) .AND. ( mv.LT.0 ) )
THEN
281 ELSE IF( ( rsvec.AND.( ldv.LT.n ) ).OR.
282 $ ( applv.AND.( ldv.LT.mv ) ) )
THEN
284 ELSE IF( tol.LE.eps )
THEN
286 ELSE IF( nsweep.LT.0 )
THEN
288 ELSE IF( lwork.LT.m )
THEN
296 CALL xerbla(
'DGSVJ0', -info )
302 ELSE IF( applv )
THEN
305 rsvec = rsvec .OR. applv
307 rooteps = dsqrt( eps )
311 rootbig = one / rootsfmin
312 bigtheta = one / rooteps
313 roottol = dsqrt( tol )
317 emptsw = ( n*( n-1 ) ) / 2
337 IF( ( nbl*kbl ).NE.n )nbl = nbl + 1
339 blskip = ( kbl**2 ) + 1
342 rowskip =
min( 5, kbl )
350 DO 1993 i = 1, nsweep
362 igl = ( ibr-1 )*kbl + 1
364 DO 1002 ir1 = 0,
min( lkahead, nbl-ibr )
368 DO 2001 p = igl,
min( igl+kbl-1, n-1 )
371 q = idamax( n-p+1, sva( p ), 1 ) + p - 1
373 CALL dswap( m, a( 1, p ), 1, a( 1, q ), 1 )
374 IF( rsvec )
CALL dswap( mvl, v( 1, p ), 1,
398 IF( ( sva( p ).LT.rootbig ) .AND.
399 $ ( sva( p ).GT.rootsfmin ) )
THEN
400 sva( p ) = dnrm2( m, a( 1, p ), 1 )*d( p )
404 CALL dlassq( m, a( 1, p ), 1, temp1, aapp )
405 sva( p ) = temp1*dsqrt( aapp )*d( p )
421 IF( aaqq.GT.zero )
THEN
424 IF( aaqq.GE.one )
THEN
425 rotok = ( small*aapp ).LE.aaqq
426 IF( aapp.LT.( big / aaqq ) )
THEN
427 aapq = ( ddot( m, a( 1, p ), 1, a( 1,
428 $ q ), 1 )*d( p )*d( q ) / aaqq )
431 CALL dcopy( m, a( 1, p ), 1, work, 1 )
432 CALL dlascl(
'G', 0, 0, aapp, d( p ),
433 $ m, 1, work, lda, ierr )
434 aapq = ddot( m, work, 1, a( 1, q ),
438 rotok = aapp.LE.( aaqq / small )
439 IF( aapp.GT.( small / aaqq ) )
THEN
440 aapq = ( ddot( m, a( 1, p ), 1, a( 1,
441 $ q ), 1 )*d( p )*d( q ) / aaqq )
444 CALL dcopy( m, a( 1, q ), 1, work, 1 )
445 CALL dlascl(
'G', 0, 0, aaqq, d( q ),
446 $ m, 1, work, lda, ierr )
447 aapq = ddot( m, work, 1, a( 1, p ),
452 mxaapq =
max( mxaapq, dabs( aapq ) )
456 IF( dabs( aapq ).GT.tol )
THEN
471 theta = -half*dabs( aqoap-apoaq )/aapq
473 IF( dabs( theta ).GT.bigtheta )
THEN
476 fastr( 3 ) = t*d( p ) / d( q )
477 fastr( 4 ) = -t*d( q ) / d( p )
478 CALL drotm( m, a( 1, p ), 1,
479 $ a( 1, q ), 1, fastr )
480 IF( rsvec )
CALL drotm( mvl,
484 sva( q ) = aaqq*dsqrt(
max( zero,
485 $ one+t*apoaq*aapq ) )
486 aapp = aapp*dsqrt(
max( zero,
487 $ one-t*aqoap*aapq ) )
488 mxsinj =
max( mxsinj, dabs( t ) )
494 thsign = -dsign( one, aapq )
495 t = one / ( theta+thsign*
496 $ dsqrt( one+theta*theta ) )
497 cs = dsqrt( one / ( one+t*t ) )
500 mxsinj =
max( mxsinj, dabs( sn ) )
501 sva( q ) = aaqq*dsqrt(
max( zero,
502 $ one+t*apoaq*aapq ) )
503 aapp = aapp*dsqrt(
max( zero,
504 $ one-t*aqoap*aapq ) )
506 apoaq = d( p ) / d( q )
507 aqoap = d( q ) / d( p )
508 IF( d( p ).GE.one )
THEN
509 IF( d( q ).GE.one )
THEN
511 fastr( 4 ) = -t*aqoap
517 IF( rsvec )
CALL drotm( mvl,
521 CALL daxpy( m, -t*aqoap,
524 CALL daxpy( m, cs*sn*apoaq,
530 CALL daxpy( mvl, -t*aqoap,
540 IF( d( q ).GE.one )
THEN
541 CALL daxpy( m, t*apoaq,
544 CALL daxpy( m, -cs*sn*aqoap,
550 CALL daxpy( mvl, t*apoaq,
559 IF( d( p ).GE.d( q ) )
THEN
560 CALL daxpy( m, -t*aqoap,
563 CALL daxpy( m, cs*sn*apoaq,
579 CALL daxpy( m, t*apoaq,
590 $ t*apoaq, v( 1, p ),
604 CALL dcopy( m, a( 1, p ), 1, work, 1 )
605 CALL dlascl(
'G', 0, 0, aapp, one, m,
606 $ 1, work, lda, ierr )
607 CALL dlascl(
'G', 0, 0, aaqq, one, m,
608 $ 1, a( 1, q ), lda, ierr )
609 temp1 = -aapq*d( p ) / d( q )
610 CALL daxpy( m, temp1, work, 1,
612 CALL dlascl(
'G', 0, 0, one, aaqq, m,
613 $ 1, a( 1, q ), lda, ierr )
614 sva( q ) = aaqq*dsqrt(
max( zero,
616 mxsinj =
max( mxsinj, sfmin )
622 IF( ( sva( q ) / aaqq )**2.LE.rooteps )
624 IF( ( aaqq.LT.rootbig ) .AND.
625 $ ( aaqq.GT.rootsfmin ) )
THEN
626 sva( q ) = dnrm2( m, a( 1, q ), 1 )*
631 CALL dlassq( m, a( 1, q ), 1, t,
633 sva( q ) = t*dsqrt( aaqq )*d( q )
636 IF( ( aapp / aapp0 ).LE.rooteps )
THEN
637 IF( ( aapp.LT.rootbig ) .AND.
638 $ ( aapp.GT.rootsfmin ) )
THEN
639 aapp = dnrm2( m, a( 1, p ), 1 )*
644 CALL dlassq( m, a( 1, p ), 1, t,
646 aapp = t*dsqrt( aapp )*d( p )
653 IF( ir1.EQ.0 )notrot = notrot + 1
654 pskipped = pskipped + 1
658 IF( ir1.EQ.0 )notrot = notrot + 1
659 pskipped = pskipped + 1
662 IF( ( i.LE.swband ) .AND.
663 $ ( pskipped.GT.rowskip ) )
THEN
664 IF( ir1.EQ.0 )aapp = -aapp
679 IF( ( ir1.EQ.0 ) .AND. ( aapp.EQ.zero ) )
680 $ notrot = notrot +
min( igl+kbl-1, n ) - p
692 igl = ( ibr-1 )*kbl + 1
694 DO 2010 jbc = ibr + 1, nbl
696 jgl = ( jbc-1 )*kbl + 1
701 DO 2100 p = igl,
min( igl+kbl-1, n )
705 IF( aapp.GT.zero )
THEN
709 DO 2200 q = jgl,
min( jgl+kbl-1, n )
713 IF( aaqq.GT.zero )
THEN
720 IF( aaqq.GE.one )
THEN
721 IF( aapp.GE.aaqq )
THEN
722 rotok = ( small*aapp ).LE.aaqq
724 rotok = ( small*aaqq ).LE.aapp
726 IF( aapp.LT.( big / aaqq ) )
THEN
727 aapq = ( ddot( m, a( 1, p ), 1, a( 1,
728 $ q ), 1 )*d( p )*d( q ) / aaqq )
731 CALL dcopy( m, a( 1, p ), 1, work, 1 )
732 CALL dlascl(
'G', 0, 0, aapp, d( p ),
733 $ m, 1, work, lda, ierr )
738 IF( aapp.GE.aaqq )
THEN
739 rotok = aapp.LE.( aaqq / small )
741 rotok = aaqq.LE.( aapp / small )
743 IF( aapp.GT.( small / aaqq ) )
THEN
745 $ q ), 1 )*d( p )*d( q
748 CALL dcopy( m, a( 1, q ), 1, work, 1 )
750 $ m, 1, work, lda, ierr )
751 aapq = ddot( m, work, 1, a( 1, p ),
756 mxaapq =
max( mxaapq, dabs( aapq ) )
770 theta = -half*dabs( aqoap-apoaq )/aapq
771 IF( aaqq.GT.aapp0 )theta = -theta
773 IF( dabs( theta ).GT.bigtheta )
THEN
775 fastr( 3 ) = t*d( p ) / d( q )
776 fastr( 4 ) = -t*d( q ) / d( p )
777 CALL drotm( m, a( 1, p ), 1,
778 $ a( 1, q ), 1, fastr )
779 IF( rsvec )
CALL drotm( mvl,
783 sva( q ) = aaqq*dsqrt(
max( zero,
784 $ one+t*apoaq*aapq ) )
785 aapp = aapp*dsqrt(
max( zero,
786 $ one-t*aqoap*aapq ) )
787 mxsinj =
max( mxsinj, dabs( t ) )
792 thsign = -dsign( one, aapq )
793 IF( aaqq.GT.aapp0 )thsign = -thsign
794 t = one / ( theta+thsign*
795 $ dsqrt( one+theta*theta ) )
796 cs = dsqrt( one / ( one+t*t ) )
798 mxsinj =
max( mxsinj, dabs( sn ) )
799 sva( q ) = aaqq*dsqrt(
max( zero,
800 $ one+t*apoaq*aapq ) )
801 aapp = aapp*dsqrt(
max( zero,
802 $ one-t*aqoap*aapq ) )
804 apoaq = d( p ) / d( q )
805 aqoap = d( q ) / d( p )
806 IF( d( p ).GE.one )
THEN
808 IF( d( q ).GE.one )
THEN
810 fastr( 4 ) = -t*aqoap
813 CALL drotm( m, a( 1, p ), 1,
816 IF( rsvec )
CALL drotm( mvl,
817 $ v( 1, p ), 1, v( 1, q ),
820 CALL daxpy( m, -t*aqoap,
823 CALL daxpy( m, cs*sn*apoaq,
827 CALL daxpy( mvl, -t*aqoap,
839 IF( d( q ).GE.one )
THEN
840 CALL daxpy( m, t*apoaq,
843 CALL daxpy( m, -cs*sn*aqoap,
847 CALL daxpy( mvl, t*apoaq,
858 IF( d( p ).GE.d( q ) )
THEN
859 CALL daxpy( m, -t*aqoap,
862 CALL daxpy( m, cs*sn*apoaq,
878 CALL daxpy( m, t*apoaq,
889 $ t*apoaq, v( 1, p ),
902 IF( aapp.GT.aaqq )
THEN
903 CALL dcopy( m, a( 1, p ), 1, work,
905 CALL dlascl(
'G', 0, 0, aapp, one,
906 $ m, 1, work, lda, ierr )
907 CALL dlascl(
'G', 0, 0, aaqq, one,
908 $ m, 1, a( 1, q ), lda,
910 temp1 = -aapq*d( p ) / d( q )
911 CALL daxpy( m, temp1, work, 1,
913 CALL dlascl(
'G', 0, 0, one, aaqq,
914 $ m, 1, a( 1, q ), lda,
916 sva( q ) = aaqq*dsqrt(
max( zero,
918 mxsinj =
max( mxsinj, sfmin )
920 CALL dcopy( m, a( 1, q ), 1, work,
922 CALL dlascl(
'G', 0, 0, aaqq, one,
923 $ m, 1, work, lda, ierr )
924 CALL dlascl(
'G', 0, 0, aapp, one,
925 $ m, 1, a( 1, p ), lda,
927 temp1 = -aapq*d( q ) / d( p )
928 CALL daxpy( m, temp1, work, 1,
930 CALL dlascl(
'G', 0, 0, one, aapp,
931 $ m, 1, a( 1, p ), lda,
933 sva( p ) = aapp*dsqrt(
max( zero,
935 mxsinj =
max( mxsinj, sfmin )
942 IF( ( sva( q ) / aaqq )**2.LE.rooteps )
944 IF( ( aaqq.LT.rootbig ) .AND.
945 $ ( aaqq.GT.rootsfmin ) )
THEN
946 sva( q ) = dnrm2( m, a( 1, q ), 1 )*
951 CALL dlassq( m, a( 1, q ), 1, t,
953 sva( q ) = t*dsqrt( aaqq )*d( q )
956 IF( ( aapp / aapp0 )**2.LE.rooteps )
THEN
957 IF( ( aapp.LT.rootbig ) .AND.
958 $ ( aapp.GT.rootsfmin ) )
THEN
959 aapp = dnrm2( m, a( 1, p ), 1 )*
964 CALL dlassq( m, a( 1, p ), 1, t,
966 aapp = t*dsqrt( aapp )*d( p )
973 pskipped = pskipped + 1
978 pskipped = pskipped + 1
982 IF( ( i.LE.swband ) .AND. ( ijblsk.GE.blskip ) )
988 IF( ( i.LE.swband ) .AND.
989 $ ( pskipped.GT.rowskip ) )
THEN
1002 IF( aapp.EQ.zero )notrot = notrot +
1003 $
min( jgl+kbl-1, n ) - jgl + 1
1004 IF( aapp.LT.zero )notrot = 0
1013 DO 2012 p = igl,
min( igl+kbl-1, n )
1014 sva( p ) = dabs( sva( p ) )
1021 IF( ( sva( n ).LT.rootbig ) .AND. ( sva( n ).GT.rootsfmin ) )
1023 sva( n ) = dnrm2( m, a( 1, n ), 1 )*d( n )
1027 CALL dlassq( m, a( 1, n ), 1, t, aapp )
1028 sva( n ) = t*dsqrt( aapp )*d( n )
1033 IF( ( i.LT.swband ) .AND. ( ( mxaapq.LE.roottol ) .OR.
1034 $ ( iswrot.LE.n ) ) )swband = i
1036 IF( ( i.GT.swband+1 ) .AND. ( mxaapq.LT.dble( n )*tol ) .AND.
1037 $ ( dble( n )*mxaapq*mxsinj.LT.tol ) )
THEN
1041 IF( notrot.GE.emptsw )
GO TO 1994
1058 DO 5991 p = 1, n - 1
1059 q = idamax( n-p+1, sva( p ), 1 ) + p - 1
1067 CALL dswap( m, a( 1, p ), 1, a( 1, q ), 1 )
1068 IF( rsvec )
CALL dswap( mvl, v( 1, p ), 1, v( 1, q ), 1 )