Contributors: Zlatko Drmac (Zagreb, Croatia) and Kresimir Veselic (Hagen, Germany)
Bugs, Examples and Comments: Please report all bugs and send interesting test examples and comments to drmac.nosp@m.@mat.nosp@m.h.hr. Thank you.
227 INTEGER info, lda, ldv, lwork, m, mv, n, nsweep
228 DOUBLE PRECISION eps, sfmin, tol
232 COMPLEX*16 a( lda, * ), d( n ), v( ldv, * ), work( lwork )
233 DOUBLE PRECISION sva( n )
239 DOUBLE PRECISION zero, half, one
240 parameter ( zero = 0.0d0, half = 0.5d0, one = 1.0d0)
241 COMPLEX*16 czero, cone
242 parameter( czero = (0.0d0, 0.0d0), cone = (1.0d0, 0.0d0) )
245 COMPLEX*16 aapq, ompq
246 DOUBLE PRECISION aapp, aapp0, aapq1, aaqq, apoaq, aqoap, big,
247 $ bigtheta, cs, mxaapq, mxsinj, rootbig, rooteps,
248 $ rootsfmin, roottol, small, sn, t, temp1, theta,
250 INTEGER blskip, emptsw, i, ibr, ierr, igl, ijblsk, ir1,
251 $ iswrot, jbc, jgl, kbl, lkahead, mvl, nbl,
252 $ notrot, p, pskipped, q, rowskip, swband
253 LOGICAL applv, rotok, rsvec
257 INTRINSIC abs, dmax1, dconjg, dble, min0, dsign, dsqrt
278 applv =
lsame( jobv,
'A' )
279 rsvec =
lsame( jobv,
'V' )
280 IF( .NOT.( rsvec .OR. applv .OR.
lsame( jobv,
'N' ) ) )
THEN
282 ELSE IF( m.LT.0 )
THEN
284 ELSE IF( ( n.LT.0 ) .OR. ( n.GT.m ) )
THEN
286 ELSE IF( lda.LT.m )
THEN
288 ELSE IF( ( rsvec.OR.applv ) .AND. ( mv.LT.0 ) )
THEN
290 ELSE IF( ( rsvec.AND.( ldv.LT.n ) ).OR.
291 $ ( applv.AND.( ldv.LT.mv ) ) )
THEN
293 ELSE IF( tol.LE.eps )
THEN
295 ELSE IF( nsweep.LT.0 )
THEN
297 ELSE IF( lwork.LT.m )
THEN
305 CALL xerbla(
'ZGSVJ0', -info )
311 ELSE IF( applv )
THEN
314 rsvec = rsvec .OR. applv
316 rooteps = dsqrt( eps )
317 rootsfmin = dsqrt( sfmin )
320 rootbig = one / rootsfmin
321 bigtheta = one / rooteps
322 roottol = dsqrt( tol )
326 emptsw = ( n*( n-1 ) ) / 2
347 IF( ( nbl*kbl ).NE.n )nbl = nbl + 1
352 rowskip = min0( 5, kbl )
366 DO 1993 i = 1, nsweep
384 igl = ( ibr-1 )*kbl + 1
386 DO 1002 ir1 = 0, min0( lkahead, nbl-ibr )
390 DO 2001 p = igl, min0( igl+kbl-1, n-1 )
394 q =
idamax( n-p+1, sva( p ), 1 ) + p - 1
396 CALL zswap( m, a( 1, p ), 1, a( 1, q ), 1 )
397 IF( rsvec )
CALL zswap( mvl, v( 1, p ), 1,
421 IF( ( sva( p ).LT.rootbig ) .AND.
422 $ ( sva( p ).GT.rootsfmin ) )
THEN
423 sva( p ) =
dznrm2( m, a( 1, p ), 1 )
427 CALL zlassq( m, a( 1, p ), 1, temp1, aapp )
428 sva( p ) = temp1*dsqrt( aapp )
435 IF( aapp.GT.zero )
THEN
439 DO 2002 q = p + 1, min0( igl+kbl-1, n )
443 IF( aaqq.GT.zero )
THEN
446 IF( aaqq.GE.one )
THEN
447 rotok = ( small*aapp ).LE.aaqq
448 IF( aapp.LT.( big / aaqq ) )
THEN
449 aapq = (
zdotc( m, a( 1, p ), 1,
450 $ a( 1, q ), 1 ) / aaqq ) / aapp
452 CALL zcopy( m, a( 1, p ), 1,
454 CALL zlascl(
'G', 0, 0, aapp, one,
455 $ m, 1, work, lda, ierr )
456 aapq =
zdotc( m, work, 1,
457 $ a( 1, q ), 1 ) / aaqq
460 rotok = aapp.LE.( aaqq / small )
461 IF( aapp.GT.( small / aaqq ) )
THEN
462 aapq = (
zdotc( m, a( 1, p ), 1,
463 $ a( 1, q ), 1 ) / aaqq ) / aapp
465 CALL zcopy( m, a( 1, q ), 1,
467 CALL zlascl(
'G', 0, 0, aaqq,
470 aapq =
zdotc( m, a( 1, p ), 1,
475 ompq = aapq / abs(aapq)
478 mxaapq = dmax1( mxaapq, -aapq1 )
482 IF( abs( aapq1 ).GT.tol )
THEN
497 theta = -half*abs( aqoap-apoaq )/aapq1
499 IF( abs( theta ).GT.bigtheta )
THEN
504 CALL zrot( m, a(1,p), 1, a(1,q), 1,
505 $ cs, dconjg(ompq)*t )
507 CALL zrot( mvl, v(1,p), 1,
508 $ v(1,q), 1, cs, dconjg(ompq)*t )
511 sva( q ) = aaqq*dsqrt( dmax1( zero,
512 $ one+t*apoaq*aapq1 ) )
513 aapp = aapp*dsqrt( dmax1( zero,
514 $ one-t*aqoap*aapq1 ) )
515 mxsinj = dmax1( mxsinj, abs( t ) )
521 thsign = -dsign( one, aapq1 )
522 t = one / ( theta+thsign*
523 $ dsqrt( one+theta*theta ) )
524 cs = dsqrt( one / ( one+t*t ) )
527 mxsinj = dmax1( mxsinj, abs( sn ) )
528 sva( q ) = aaqq*dsqrt( dmax1( zero,
529 $ one+t*apoaq*aapq1 ) )
530 aapp = aapp*dsqrt( dmax1( zero,
531 $ one-t*aqoap*aapq1 ) )
533 CALL zrot( m, a(1,p), 1, a(1,q), 1,
534 $ cs, dconjg(ompq)*sn )
536 CALL zrot( mvl, v(1,p), 1,
537 $ v(1,q), 1, cs, dconjg(ompq)*sn )
544 CALL zcopy( m, a( 1, p ), 1,
546 CALL zlascl(
'G', 0, 0, aapp, one, m,
549 CALL zlascl(
'G', 0, 0, aaqq, one, m,
550 $ 1, a( 1, q ), lda, ierr )
551 CALL zaxpy( m, -aapq, work, 1,
553 CALL zlascl(
'G', 0, 0, one, aaqq, m,
554 $ 1, a( 1, q ), lda, ierr )
555 sva( q ) = aaqq*dsqrt( dmax1( zero,
556 $ one-aapq1*aapq1 ) )
557 mxsinj = dmax1( mxsinj, sfmin )
564 IF( ( sva( q ) / aaqq )**2.LE.rooteps )
566 IF( ( aaqq.LT.rootbig ) .AND.
567 $ ( aaqq.GT.rootsfmin ) )
THEN
568 sva( q ) =
dznrm2( m, a( 1, q ), 1 )
572 CALL zlassq( m, a( 1, q ), 1, t,
574 sva( q ) = t*dsqrt( aaqq )
577 IF( ( aapp / aapp0 ).LE.rooteps )
THEN
578 IF( ( aapp.LT.rootbig ) .AND.
579 $ ( aapp.GT.rootsfmin ) )
THEN
580 aapp =
dznrm2( m, a( 1, p ), 1 )
584 CALL zlassq( m, a( 1, p ), 1, t,
586 aapp = t*dsqrt( aapp )
593 IF( ir1.EQ.0 )notrot = notrot + 1
595 pskipped = pskipped + 1
599 IF( ir1.EQ.0 )notrot = notrot + 1
600 pskipped = pskipped + 1
603 IF( ( i.LE.swband ) .AND.
604 $ ( pskipped.GT.rowskip ) )
THEN
605 IF( ir1.EQ.0 )aapp = -aapp
620 IF( ( ir1.EQ.0 ) .AND. ( aapp.EQ.zero ) )
621 $ notrot = notrot + min0( igl+kbl-1, n ) - p
632 igl = ( ibr-1 )*kbl + 1
634 DO 2010 jbc = ibr + 1, nbl
636 jgl = ( jbc-1 )*kbl + 1
641 DO 2100 p = igl, min0( igl+kbl-1, n )
644 IF( aapp.GT.zero )
THEN
648 DO 2200 q = jgl, min0( jgl+kbl-1, n )
651 IF( aaqq.GT.zero )
THEN
658 IF( aaqq.GE.one )
THEN
659 IF( aapp.GE.aaqq )
THEN
660 rotok = ( small*aapp ).LE.aaqq
662 rotok = ( small*aaqq ).LE.aapp
664 IF( aapp.LT.( big / aaqq ) )
THEN
665 aapq = (
zdotc( m, a( 1, p ), 1,
666 $ a( 1, q ), 1 ) / aaqq ) / aapp
668 CALL zcopy( m, a( 1, p ), 1,
670 CALL zlascl(
'G', 0, 0, aapp,
673 aapq =
zdotc( m, work, 1,
674 $ a( 1, q ), 1 ) / aaqq
677 IF( aapp.GE.aaqq )
THEN
678 rotok = aapp.LE.( aaqq / small )
680 rotok = aaqq.LE.( aapp / small )
682 IF( aapp.GT.( small / aaqq ) )
THEN
683 aapq = (
zdotc( m, a( 1, p ), 1,
684 $ a( 1, q ), 1 ) / aaqq ) / aapp
686 CALL zcopy( m, a( 1, q ), 1,
688 CALL zlascl(
'G', 0, 0, aaqq,
691 aapq =
zdotc( m, a( 1, p ), 1,
696 ompq = aapq / abs(aapq)
699 mxaapq = dmax1( mxaapq, -aapq1 )
703 IF( abs( aapq1 ).GT.tol )
THEN
713 theta = -half*abs( aqoap-apoaq )/ aapq1
714 IF( aaqq.GT.aapp0 )theta = -theta
716 IF( abs( theta ).GT.bigtheta )
THEN
719 CALL zrot( m, a(1,p), 1, a(1,q), 1,
720 $ cs, dconjg(ompq)*t )
722 CALL zrot( mvl, v(1,p), 1,
723 $ v(1,q), 1, cs, dconjg(ompq)*t )
725 sva( q ) = aaqq*dsqrt( dmax1( zero,
726 $ one+t*apoaq*aapq1 ) )
727 aapp = aapp*dsqrt( dmax1( zero,
728 $ one-t*aqoap*aapq1 ) )
729 mxsinj = dmax1( mxsinj, abs( t ) )
734 thsign = -dsign( one, aapq1 )
735 IF( aaqq.GT.aapp0 )thsign = -thsign
736 t = one / ( theta+thsign*
737 $ dsqrt( one+theta*theta ) )
738 cs = dsqrt( one / ( one+t*t ) )
740 mxsinj = dmax1( mxsinj, abs( sn ) )
741 sva( q ) = aaqq*dsqrt( dmax1( zero,
742 $ one+t*apoaq*aapq1 ) )
743 aapp = aapp*dsqrt( dmax1( zero,
744 $ one-t*aqoap*aapq1 ) )
746 CALL zrot( m, a(1,p), 1, a(1,q), 1,
747 $ cs, dconjg(ompq)*sn )
749 CALL zrot( mvl, v(1,p), 1,
750 $ v(1,q), 1, cs, dconjg(ompq)*sn )
757 IF( aapp.GT.aaqq )
THEN
758 CALL zcopy( m, a( 1, p ), 1,
760 CALL zlascl(
'G', 0, 0, aapp, one,
763 CALL zlascl(
'G', 0, 0, aaqq, one,
764 $ m, 1, a( 1, q ), lda,
766 CALL zaxpy( m, -aapq, work,
768 CALL zlascl(
'G', 0, 0, one, aaqq,
769 $ m, 1, a( 1, q ), lda,
771 sva( q ) = aaqq*dsqrt( dmax1( zero,
772 $ one-aapq1*aapq1 ) )
773 mxsinj = dmax1( mxsinj, sfmin )
775 CALL zcopy( m, a( 1, q ), 1,
777 CALL zlascl(
'G', 0, 0, aaqq, one,
780 CALL zlascl(
'G', 0, 0, aapp, one,
781 $ m, 1, a( 1, p ), lda,
783 CALL zaxpy( m, -dconjg(aapq),
784 $ work, 1, a( 1, p ), 1 )
785 CALL zlascl(
'G', 0, 0, one, aapp,
786 $ m, 1, a( 1, p ), lda,
788 sva( p ) = aapp*dsqrt( dmax1( zero,
789 $ one-aapq1*aapq1 ) )
790 mxsinj = dmax1( mxsinj, sfmin )
797 IF( ( sva( q ) / aaqq )**2.LE.rooteps )
799 IF( ( aaqq.LT.rootbig ) .AND.
800 $ ( aaqq.GT.rootsfmin ) )
THEN
801 sva( q ) =
dznrm2( m, a( 1, q ), 1)
805 CALL zlassq( m, a( 1, q ), 1, t,
807 sva( q ) = t*dsqrt( aaqq )
810 IF( ( aapp / aapp0 )**2.LE.rooteps )
THEN
811 IF( ( aapp.LT.rootbig ) .AND.
812 $ ( aapp.GT.rootsfmin ) )
THEN
813 aapp =
dznrm2( m, a( 1, p ), 1 )
817 CALL zlassq( m, a( 1, p ), 1, t,
819 aapp = t*dsqrt( aapp )
827 pskipped = pskipped + 1
832 pskipped = pskipped + 1
836 IF( ( i.LE.swband ) .AND. ( ijblsk.GE.blskip ) )
842 IF( ( i.LE.swband ) .AND.
843 $ ( pskipped.GT.rowskip ) )
THEN
857 IF( aapp.EQ.zero )notrot = notrot +
858 $ min0( jgl+kbl-1, n ) - jgl + 1
859 IF( aapp.LT.zero )notrot = 0
869 DO 2012 p = igl, min0( igl+kbl-1, n )
870 sva( p ) = abs( sva( p ) )
877 IF( ( sva( n ).LT.rootbig ) .AND. ( sva( n ).GT.rootsfmin ) )
879 sva( n ) =
dznrm2( m, a( 1, n ), 1 )
883 CALL zlassq( m, a( 1, n ), 1, t, aapp )
884 sva( n ) = t*dsqrt( aapp )
889 IF( ( i.LT.swband ) .AND. ( ( mxaapq.LE.roottol ) .OR.
890 $ ( iswrot.LE.n ) ) )swband = i
892 IF( ( i.GT.swband+1 ) .AND. ( mxaapq.LT.dsqrt( dble( n ) )*
893 $ tol ) .AND. ( dble( n )*mxaapq*mxsinj.LT.tol ) )
THEN
897 IF( notrot.GE.emptsw )
GO TO 1994
916 q =
idamax( n-p+1, sva( p ), 1 ) + p - 1
924 CALL zswap( m, a( 1, p ), 1, a( 1, q ), 1 )
925 IF( rsvec )
CALL zswap( mvl, v( 1, p ), 1, v( 1, q ), 1 )
integer function idamax(N, DX, INCX)
IDAMAX
subroutine zcopy(N, ZX, INCX, ZY, INCY)
ZCOPY
subroutine zswap(N, ZX, INCX, ZY, INCY)
ZSWAP
subroutine xerbla(SRNAME, INFO)
XERBLA
complex *16 function zdotc(N, ZX, INCX, ZY, INCY)
ZDOTC
subroutine zlassq(N, X, INCX, SCALE, SUMSQ)
ZLASSQ updates a sum of squares represented in scaled form.
double precision function dznrm2(N, X, INCX)
DZNRM2
subroutine zrot(N, CX, INCX, CY, INCY, C, S)
ZROT applies a plane rotation with real cosine and complex sine to a pair of complex vectors...
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.
logical function lsame(CA, CB)
LSAME
subroutine zaxpy(N, ZA, ZX, INCX, ZY, INCY)
ZAXPY