234
  235
  236
  237
  238
  239
  240      DOUBLE PRECISION   EPS, SFMIN, TOL
  241      INTEGER            INFO, LDA, LDV, LWORK, M, MV, N, N1, NSWEEP
  242      CHARACTER*1        JOBV
  243
  244
  245      DOUBLE PRECISION   A( LDA, * ), D( N ), SVA( N ), V( LDV, * ),
  246     $                   WORK( LWORK )
  247
  248
  249
  250
  251
  252      DOUBLE PRECISION   ZERO, HALF, ONE
  253      parameter( zero = 0.0d0, half = 0.5d0, one = 1.0d0 )
  254
  255
  256      DOUBLE PRECISION   AAPP, AAPP0, AAPQ, AAQQ, APOAQ, AQOAP, BIG,
  257     $                   BIGTHETA, CS, LARGE, MXAAPQ, MXSINJ, ROOTBIG,
  258     $                   ROOTEPS, ROOTSFMIN, ROOTTOL, SMALL, SN, T,
  259     $                   TEMP1, THETA, THSIGN
  260      INTEGER            BLSKIP, EMPTSW, i, ibr, igl, IERR, IJBLSK,
  261     $                   ISWROT, jbc, jgl, KBL, MVL, NOTROT, nblc, nblr,
  262     $                   p, PSKIPPED, q, ROWSKIP, SWBAND
  263      LOGICAL            APPLV, ROTOK, RSVEC
  264
  265
  266      DOUBLE PRECISION   FASTR( 5 )
  267
  268
  269      INTRINSIC          dabs, max, dble, min, dsign, dsqrt
  270
  271
  272      DOUBLE PRECISION   DDOT, DNRM2
  273      INTEGER            IDAMAX
  274      LOGICAL            LSAME
  276
  277
  281
  282
  283
  284
  285
  286      applv = 
lsame( jobv, 
'A' )
 
  287      rsvec = 
lsame( jobv, 
'V' )
 
  288      IF( .NOT.( rsvec .OR. applv .OR. 
lsame( jobv, 
'N' ) ) ) 
THEN 
  289         info = -1
  290      ELSE IF( m.LT.0 ) THEN
  291         info = -2
  292      ELSE IF( ( n.LT.0 ) .OR. ( n.GT.m ) ) THEN
  293         info = -3
  294      ELSE IF( n1.LT.0 ) THEN
  295         info = -4
  296      ELSE IF( lda.LT.m ) THEN
  297         info = -6
  298      ELSE IF( ( rsvec.OR.applv ) .AND. ( mv.LT.0 ) ) THEN
  299         info = -9
  300      ELSE IF( ( rsvec.AND.( ldv.LT.n ) ).OR.
  301     $         ( applv.AND.( ldv.LT.mv ) )  ) THEN
  302         info = -11
  303      ELSE IF( tol.LE.eps ) THEN
  304         info = -14
  305      ELSE IF( nsweep.LT.0 ) THEN
  306         info = -15
  307      ELSE IF( lwork.LT.m ) THEN
  308         info = -17
  309      ELSE
  310         info = 0
  311      END IF
  312
  313
  314      IF( info.NE.0 ) THEN
  315         CALL xerbla( 
'DGSVJ1', -info )
 
  316         RETURN
  317      END IF
  318
  319      IF( rsvec ) THEN
  320         mvl = n
  321      ELSE IF( applv ) THEN
  322         mvl = mv
  323      END IF
  324      rsvec = rsvec .OR. applv
  325 
  326      rooteps = dsqrt( eps )
  327      rootsfmin = dsqrt( sfmin )
  328      small = sfmin / eps
  329      big = one / sfmin
  330      rootbig = one / rootsfmin
  331      large = big / dsqrt( dble( m*n ) )
  332      bigtheta = one / rooteps
  333      roottol = dsqrt( tol )
  334
  335
  336
  337
  338
  339      emptsw = n1*( n-n1 )
  340      notrot = 0
  341      fastr( 1 ) = zero
  342
  343
  344
  345      kbl = min( 8, n )
  346      nblr = n1 / kbl
  347      IF( ( nblr*kbl ).NE.n1 )nblr = nblr + 1
  348 
  349
  350 
  351      nblc = ( n-n1 ) / kbl
  352      IF( ( nblc*kbl ).NE.( n-n1 ) )nblc = nblc + 1
  353      blskip = ( kbl**2 ) + 1
  354
  355 
  356      rowskip = min( 5, kbl )
  357
  358      swband = 0
  359
  360
  361
  362
  363
  364
  365
  366
  367
  368
  369
  370
  371
  372      DO 1993 i = 1, nsweep
  373
  374
  375         mxaapq = zero
  376         mxsinj = zero
  377         iswrot = 0
  378
  379         notrot = 0
  380         pskipped = 0
  381
  382         DO 2000 ibr = 1, nblr
  383 
  384            igl = ( ibr-1 )*kbl + 1
  385
  386
  387
  388
  389 
  390            igl = ( ibr-1 )*kbl + 1
  391 
  392            DO 2010 jbc = 1, nblc
  393 
  394               jgl = n1 + ( jbc-1 )*kbl + 1
  395 
  396
  397 
  398               ijblsk = 0
  399               DO 2100 p = igl, min( igl+kbl-1, n1 )
  400 
  401                  aapp = sva( p )
  402 
  403                  IF( aapp.GT.zero ) THEN
  404 
  405                     pskipped = 0
  406 
  407                     DO 2200 q = jgl, min( jgl+kbl-1, n )
  408
  409                        aaqq = sva( q )
  410 
  411                        IF( aaqq.GT.zero ) THEN
  412                           aapp0 = aapp
  413
  414
  415
  416
  417
  418                           IF( aaqq.GE.one ) THEN
  419                              IF( aapp.GE.aaqq ) THEN
  420                                 rotok = ( small*aapp ).LE.aaqq
  421                              ELSE
  422                                 rotok = ( small*aaqq ).LE.aapp
  423                              END IF
  424                              IF( aapp.LT.( big / aaqq ) ) THEN
  425                                 aapq = ( 
ddot( m, a( 1, p ), 1,
 
  426     $                                    a( 1,
  427     $                                  q ), 1 )*d( p )*d( q ) / aaqq )
  428     $                                  / aapp
  429                              ELSE
  430                                 CALL dcopy( m, a( 1, p ), 1, work,
 
  431     $                                       1 )
  432                                 CALL dlascl( 
'G', 0, 0, aapp,
 
  433     $                                        d( p ),
  434     $                                        m, 1, work, lda, ierr )
  435                                 aapq = 
ddot( m, work, 1, a( 1, q ),
 
  436     $                                  1 )*d( q ) / aaqq
  437                              END IF
  438                           ELSE
  439                              IF( aapp.GE.aaqq ) THEN
  440                                 rotok = aapp.LE.( aaqq / small )
  441                              ELSE
  442                                 rotok = aaqq.LE.( aapp / small )
  443                              END IF
  444                              IF( aapp.GT.( small / aaqq ) ) THEN
  445                                 aapq = ( 
ddot( m, a( 1, p ), 1,
 
  446     $                                    a( 1,
  447     $                                  q ), 1 )*d( p )*d( q ) / aaqq )
  448     $                                  / aapp
  449                              ELSE
  450                                 CALL dcopy( m, a( 1, q ), 1, work,
 
  451     $                                       1 )
  452                                 CALL dlascl( 
'G', 0, 0, aaqq,
 
  453     $                                        d( q ),
  454     $                                        m, 1, work, lda, ierr )
  455                                 aapq = 
ddot( m, work, 1, a( 1, p ),
 
  456     $                                  1 )*d( p ) / aapp
  457                              END IF
  458                           END IF
  459 
  460                           mxaapq = max( mxaapq, dabs( aapq ) )
  461 
  462
  463
  464                           IF( dabs( aapq ).GT.tol ) THEN
  465                              notrot = 0
  466
  467                              pskipped = 0
  468                              iswrot = iswrot + 1
  469
  470                              IF( rotok ) THEN
  471
  472                                 aqoap = aaqq / aapp
  473                                 apoaq = aapp / aaqq
  474                                 theta = -half*dabs(aqoap-apoaq) / aapq
  475                                 IF( aaqq.GT.aapp0 )theta = -theta
  476 
  477                                 IF( dabs( theta ).GT.bigtheta ) THEN
  478                                    t = half / theta
  479                                    fastr( 3 ) = t*d( p ) / d( q )
  480                                    fastr( 4 ) = -t*d( q ) / d( p )
  481                                    CALL drotm( m, a( 1, p ), 1,
 
  482     $                                          a( 1, q ), 1, fastr )
  483                                    IF( rsvec )
CALL drotm( mvl,
 
  484     $                                              v( 1, p ), 1,
  485     $                                              v( 1, q ), 1,
  486     $                                              fastr )
  487                                    sva( q ) = aaqq*dsqrt( max( zero,
  488     $                                         one+t*apoaq*aapq ) )
  489                                    aapp = aapp*dsqrt( max( zero,
  490     $                                     one-t*aqoap*aapq ) )
  491                                    mxsinj = max( mxsinj, dabs( t ) )
  492                                 ELSE
  493
  494
  495
  496                                    thsign = -dsign( one, aapq )
  497                                    IF( aaqq.GT.aapp0 )thsign = -thsign
  498                                    t = one / ( theta+thsign*
  499     $                                  dsqrt( one+theta*theta ) )
  500                                    cs = dsqrt( one / ( one+t*t ) )
  501                                    sn = t*cs
  502                                    mxsinj = max( mxsinj, dabs( sn ) )
  503                                    sva( q ) = aaqq*dsqrt( max( zero,
  504     $                                         one+t*apoaq*aapq ) )
  505                                    aapp = aapp*dsqrt( max( zero,
  506     $                                    one-t*aqoap*aapq ) )
  507 
  508                                    apoaq = d( p ) / d( q )
  509                                    aqoap = d( q ) / d( p )
  510                                    IF( d( p ).GE.one ) THEN
  511
  512                                       IF( d( q ).GE.one ) THEN
  513                                          fastr( 3 ) = t*apoaq
  514                                          fastr( 4 ) = -t*aqoap
  515                                          d( p ) = d( p )*cs
  516                                          d( q ) = d( q )*cs
  517                                          CALL drotm( m, a( 1, p ),
 
  518     $                                                1,
  519     $                                                a( 1, q ), 1,
  520     $                                                fastr )
  521                                          IF( rsvec )
CALL drotm( mvl,
 
  522     $                                        v( 1, p ), 1, v( 1, q ),
  523     $                                        1, fastr )
  524                                       ELSE
  525                                          CALL daxpy( m, -t*aqoap,
 
  526     $                                                a( 1, q ), 1,
  527     $                                                a( 1, p ), 1 )
  528                                          CALL daxpy( m, cs*sn*apoaq,
 
  529     $                                                a( 1, p ), 1,
  530     $                                                a( 1, q ), 1 )
  531                                          IF( rsvec ) THEN
  533     $                                                   -t*aqoap,
  534     $                                                   v( 1, q ), 1,
  535     $                                                   v( 1, p ), 1 )
  537     $                                                   cs*sn*apoaq,
  538     $                                                   v( 1, p ), 1,
  539     $                                                   v( 1, q ), 1 )
  540                                          END IF
  541                                          d( p ) = d( p )*cs
  542                                          d( q ) = d( q ) / cs
  543                                       END IF
  544                                    ELSE
  545                                       IF( d( q ).GE.one ) THEN
  546                                          CALL daxpy( m, t*apoaq,
 
  547     $                                                a( 1, p ), 1,
  548     $                                                a( 1, q ), 1 )
  550     $                                                -cs*sn*aqoap,
  551     $                                                a( 1, q ), 1,
  552     $                                                a( 1, p ), 1 )
  553                                          IF( rsvec ) THEN
  555     $                                                   t*apoaq,
  556     $                                                   v( 1, p ), 1,
  557     $                                                   v( 1, q ), 1 )
  559     $                                                   -cs*sn*aqoap,
  560     $                                                   v( 1, q ), 1,
  561     $                                                   v( 1, p ), 1 )
  562                                          END IF
  563                                          d( p ) = d( p ) / cs
  564                                          d( q ) = d( q )*cs
  565                                       ELSE
  566                                          IF( d( p ).GE.d( q ) ) THEN
  567                                             CALL daxpy( m, -t*aqoap,
 
  568     $                                                   a( 1, q ), 1,
  569     $                                                   a( 1, p ), 1 )
  571     $                                                   cs*sn*apoaq,
  572     $                                                   a( 1, p ), 1,
  573     $                                                   a( 1, q ), 1 )
  574                                             d( p ) = d( p )*cs
  575                                             d( q ) = d( q ) / cs
  576                                             IF( rsvec ) THEN
  578     $                                               -t*aqoap,
  579     $                                               v( 1, q ), 1,
  580     $                                               v( 1, p ), 1 )
  582     $                                               cs*sn*apoaq,
  583     $                                               v( 1, p ), 1,
  584     $                                               v( 1, q ), 1 )
  585                                             END IF
  586                                          ELSE
  587                                             CALL daxpy( m, t*apoaq,
 
  588     $                                                   a( 1, p ), 1,
  589     $                                                   a( 1, q ), 1 )
  591     $                                                   -cs*sn*aqoap,
  592     $                                                   a( 1, q ), 1,
  593     $                                                   a( 1, p ), 1 )
  594                                             d( p ) = d( p ) / cs
  595                                             d( q ) = d( q )*cs
  596                                             IF( rsvec ) THEN
  598     $                                               t*apoaq, v( 1, p ),
  599     $                                               1, v( 1, q ), 1 )
  601     $                                               -cs*sn*aqoap,
  602     $                                               v( 1, q ), 1,
  603     $                                               v( 1, p ), 1 )
  604                                             END IF
  605                                          END IF
  606                                       END IF
  607                                    END IF
  608                                 END IF
  609 
  610                              ELSE
  611                                 IF( aapp.GT.aaqq ) THEN
  612                                    CALL dcopy( m, a( 1, p ), 1,
 
  613     $                                          work,
  614     $                                          1 )
  615                                    CALL dlascl( 
'G', 0, 0, aapp,
 
  616     $                                           one,
  617     $                                           m, 1, work, lda, ierr )
  618                                    CALL dlascl( 
'G', 0, 0, aaqq,
 
  619     $                                           one,
  620     $                                           m, 1, a( 1, q ), lda,
  621     $                                           ierr )
  622                                    temp1 = -aapq*d( p ) / d( q )
  623                                    CALL daxpy( m, temp1, work, 1,
 
  624     $                                          a( 1, q ), 1 )
  625                                    CALL dlascl( 
'G', 0, 0, one,
 
  626     $                                           aaqq,
  627     $                                           m, 1, a( 1, q ), lda,
  628     $                                           ierr )
  629                                    sva( q ) = aaqq*dsqrt( max( zero,
  630     $                                         one-aapq*aapq ) )
  631                                    mxsinj = max( mxsinj, sfmin )
  632                                 ELSE
  633                                    CALL dcopy( m, a( 1, q ), 1,
 
  634     $                                          work,
  635     $                                          1 )
  636                                    CALL dlascl( 
'G', 0, 0, aaqq,
 
  637     $                                           one,
  638     $                                           m, 1, work, lda, ierr )
  639                                    CALL dlascl( 
'G', 0, 0, aapp,
 
  640     $                                           one,
  641     $                                           m, 1, a( 1, p ), lda,
  642     $                                           ierr )
  643                                    temp1 = -aapq*d( q ) / d( p )
  644                                    CALL daxpy( m, temp1, work, 1,
 
  645     $                                          a( 1, p ), 1 )
  646                                    CALL dlascl( 
'G', 0, 0, one,
 
  647     $                                           aapp,
  648     $                                           m, 1, a( 1, p ), lda,
  649     $                                           ierr )
  650                                    sva( p ) = aapp*dsqrt( max( zero,
  651     $                                         one-aapq*aapq ) )
  652                                    mxsinj = max( mxsinj, sfmin )
  653                                 END IF
  654                              END IF
  655
  656
  657
  658
  659                              IF( ( sva( q ) / aaqq )**2.LE.rooteps )
  660     $                            THEN
  661                                 IF( ( aaqq.LT.rootbig ) .AND.
  662     $                               ( aaqq.GT.rootsfmin ) ) THEN
  663                                    sva( q ) = 
dnrm2( m, a( 1, q ),
 
  664     $                                   1 )*
  665     $                                         d( q )
  666                                 ELSE
  667                                    t = zero
  668                                    aaqq = one
  669                                    CALL dlassq( m, a( 1, q ), 1, t,
 
  670     $                                           aaqq )
  671                                    sva( q ) = t*dsqrt( aaqq )*d( q )
  672                                 END IF
  673                              END IF
  674                              IF( ( aapp / aapp0 )**2.LE.rooteps ) THEN
  675                                 IF( ( aapp.LT.rootbig ) .AND.
  676     $                               ( aapp.GT.rootsfmin ) ) THEN
  677                                    aapp = 
dnrm2( m, a( 1, p ), 1 )*
 
  678     $                                     d( p )
  679                                 ELSE
  680                                    t = zero
  681                                    aapp = one
  682                                    CALL dlassq( m, a( 1, p ), 1, t,
 
  683     $                                           aapp )
  684                                    aapp = t*dsqrt( aapp )*d( p )
  685                                 END IF
  686                                 sva( p ) = aapp
  687                              END IF
  688
  689                           ELSE
  690                              notrot = notrot + 1
  691
  692                              pskipped = pskipped + 1
  693                              ijblsk = ijblsk + 1
  694                           END IF
  695                        ELSE
  696                           notrot = notrot + 1
  697                           pskipped = pskipped + 1
  698                           ijblsk = ijblsk + 1
  699                        END IF
  700 
  701
  702                        IF( ( i.LE.swband ) .AND. ( ijblsk.GE.blskip ) )
  703     $                      THEN
  704                           sva( p ) = aapp
  705                           notrot = 0
  706                           GO TO 2011
  707                        END IF
  708                        IF( ( i.LE.swband ) .AND.
  709     $                      ( pskipped.GT.rowskip ) ) THEN
  710                           aapp = -aapp
  711                           notrot = 0
  712                           GO TO 2203
  713                        END IF
  714 
  715
  716 2200                CONTINUE
  717
  718 2203                CONTINUE
  719 
  720                     sva( p ) = aapp
  721
  722                  ELSE
  723                     IF( aapp.EQ.zero )notrot = notrot +
  724     $                   min( jgl+kbl-1, n ) - jgl + 1
  725                     IF( aapp.LT.zero )notrot = 0
  726
  727                  END IF
  728 
  729 2100          CONTINUE
  730
  731 2010       CONTINUE
  732
  733 2011       CONTINUE
  734
  735            DO 2012 p = igl, min( igl+kbl-1, n )
  736               sva( p ) = dabs( sva( p ) )
  737 2012       CONTINUE
  738
  739 2000    CONTINUE
  740
  741
  742
  743         IF( ( sva( n ).LT.rootbig ) .AND. ( sva( n ).GT.rootsfmin ) )
  744     $       THEN
  745            sva( n ) = 
dnrm2( m, a( 1, n ), 1 )*d( n )
 
  746         ELSE
  747            t = zero
  748            aapp = one
  749            CALL dlassq( m, a( 1, n ), 1, t, aapp )
 
  750            sva( n ) = t*dsqrt( aapp )*d( n )
  751         END IF
  752
  753
  754
  755         IF( ( i.LT.swband ) .AND. ( ( mxaapq.LE.roottol ) .OR.
  756     $       ( iswrot.LE.n ) ) )swband = i
  757 
  758         IF( ( i.GT.swband+1 ) .AND. ( mxaapq.LT.dble( n )*tol ) .AND.
  759     $       ( dble( n )*mxaapq*mxsinj.LT.tol ) ) THEN
  760            GO TO 1994
  761         END IF
  762 
  763
  764         IF( notrot.GE.emptsw )GO TO 1994
  765 
  766 1993 CONTINUE
  767
  768
  769
  770      info = nsweep - 1
  771      GO TO 1995
  772 1994 CONTINUE
  773
  774
  775 
  776      info = 0
  777
  778 1995 CONTINUE
  779
  780
  781
  782      DO 5991 p = 1, n - 1
  783         q = 
idamax( n-p+1, sva( p ), 1 ) + p - 1
 
  784         IF( p.NE.q ) THEN
  785            temp1 = sva( p )
  786            sva( p ) = sva( q )
  787            sva( q ) = temp1
  788            temp1 = d( p )
  789            d( p ) = d( q )
  790            d( q ) = temp1
  791            CALL dswap( m, a( 1, p ), 1, a( 1, q ), 1 )
 
  792            IF( rsvec )
CALL dswap( mvl, v( 1, p ), 1, v( 1, q ), 1 )
 
  793         END IF
  794 5991 CONTINUE
  795
  796      RETURN
  797
  798
  799
subroutine xerbla(srname, info)
subroutine daxpy(n, da, dx, incx, dy, incy)
DAXPY
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
double precision function ddot(n, dx, incx, dy, incy)
DDOT
integer function idamax(n, dx, incx)
IDAMAX
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 dlassq(n, x, incx, scale, sumsq)
DLASSQ updates a sum of squares represented in scaled form.
logical function lsame(ca, cb)
LSAME
real(wp) function dnrm2(n, x, incx)
DNRM2
subroutine drotm(n, dx, incx, dy, incy, dparam)
DROTM
subroutine dswap(n, dx, incx, dy, incy)
DSWAP