560 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Fortran
		
	
	
	
			
		
		
	
	
			560 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Fortran
		
	
	
	
*> \brief \b DGGBAL
 | 
						|
*
 | 
						|
*  =========== DOCUMENTATION ===========
 | 
						|
*
 | 
						|
* Online html documentation available at 
 | 
						|
*            http://www.netlib.org/lapack/explore-html/ 
 | 
						|
*
 | 
						|
*> \htmlonly
 | 
						|
*> Download DGGBAL + dependencies 
 | 
						|
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dggbal.f"> 
 | 
						|
*> [TGZ]</a> 
 | 
						|
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dggbal.f"> 
 | 
						|
*> [ZIP]</a> 
 | 
						|
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dggbal.f"> 
 | 
						|
*> [TXT]</a>
 | 
						|
*> \endhtmlonly 
 | 
						|
*
 | 
						|
*  Definition:
 | 
						|
*  ===========
 | 
						|
*
 | 
						|
*       SUBROUTINE DGGBAL( JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE,
 | 
						|
*                          RSCALE, WORK, INFO )
 | 
						|
* 
 | 
						|
*       .. Scalar Arguments ..
 | 
						|
*       CHARACTER          JOB
 | 
						|
*       INTEGER            IHI, ILO, INFO, LDA, LDB, N
 | 
						|
*       ..
 | 
						|
*       .. Array Arguments ..
 | 
						|
*       DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), LSCALE( * ),
 | 
						|
*      $                   RSCALE( * ), WORK( * )
 | 
						|
*       ..
 | 
						|
*  
 | 
						|
*
 | 
						|
*> \par Purpose:
 | 
						|
*  =============
 | 
						|
*>
 | 
						|
*> \verbatim
 | 
						|
*>
 | 
						|
*> DGGBAL balances a pair of general real matrices (A,B).  This
 | 
						|
*> involves, first, permuting A and B by similarity transformations to
 | 
						|
*> isolate eigenvalues in the first 1 to ILO$-$1 and last IHI+1 to N
 | 
						|
*> elements on the diagonal; and second, applying a diagonal similarity
 | 
						|
*> transformation to rows and columns ILO to IHI to make the rows
 | 
						|
*> and columns as close in norm as possible. Both steps are optional.
 | 
						|
*>
 | 
						|
*> Balancing may reduce the 1-norm of the matrices, and improve the
 | 
						|
*> accuracy of the computed eigenvalues and/or eigenvectors in the
 | 
						|
*> generalized eigenvalue problem A*x = lambda*B*x.
 | 
						|
*> \endverbatim
 | 
						|
*
 | 
						|
*  Arguments:
 | 
						|
*  ==========
 | 
						|
*
 | 
						|
*> \param[in] JOB
 | 
						|
*> \verbatim
 | 
						|
*>          JOB is CHARACTER*1
 | 
						|
*>          Specifies the operations to be performed on A and B:
 | 
						|
*>          = 'N':  none:  simply set ILO = 1, IHI = N, LSCALE(I) = 1.0
 | 
						|
*>                  and RSCALE(I) = 1.0 for i = 1,...,N.
 | 
						|
*>          = 'P':  permute only;
 | 
						|
*>          = 'S':  scale only;
 | 
						|
*>          = 'B':  both permute and scale.
 | 
						|
*> \endverbatim
 | 
						|
*>
 | 
						|
*> \param[in] N
 | 
						|
*> \verbatim
 | 
						|
*>          N is INTEGER
 | 
						|
*>          The order of the matrices A and B.  N >= 0.
 | 
						|
*> \endverbatim
 | 
						|
*>
 | 
						|
*> \param[in,out] A
 | 
						|
*> \verbatim
 | 
						|
*>          A is DOUBLE PRECISION array, dimension (LDA,N)
 | 
						|
*>          On entry, the input matrix A.
 | 
						|
*>          On exit,  A is overwritten by the balanced matrix.
 | 
						|
*>          If JOB = 'N', A is not referenced.
 | 
						|
*> \endverbatim
 | 
						|
*>
 | 
						|
*> \param[in] LDA
 | 
						|
*> \verbatim
 | 
						|
*>          LDA is INTEGER
 | 
						|
*>          The leading dimension of the array A. LDA >= max(1,N).
 | 
						|
*> \endverbatim
 | 
						|
*>
 | 
						|
*> \param[in,out] B
 | 
						|
*> \verbatim
 | 
						|
*>          B is DOUBLE PRECISION array, dimension (LDB,N)
 | 
						|
*>          On entry, the input matrix B.
 | 
						|
*>          On exit,  B is overwritten by the balanced matrix.
 | 
						|
*>          If JOB = 'N', B is not referenced.
 | 
						|
*> \endverbatim
 | 
						|
*>
 | 
						|
*> \param[in] LDB
 | 
						|
*> \verbatim
 | 
						|
*>          LDB is INTEGER
 | 
						|
*>          The leading dimension of the array B. LDB >= max(1,N).
 | 
						|
*> \endverbatim
 | 
						|
*>
 | 
						|
*> \param[out] ILO
 | 
						|
*> \verbatim
 | 
						|
*>          ILO is INTEGER
 | 
						|
*> \endverbatim
 | 
						|
*>
 | 
						|
*> \param[out] IHI
 | 
						|
*> \verbatim
 | 
						|
*>          IHI is INTEGER
 | 
						|
*>          ILO and IHI are set to integers such that on exit
 | 
						|
*>          A(i,j) = 0 and B(i,j) = 0 if i > j and
 | 
						|
*>          j = 1,...,ILO-1 or i = IHI+1,...,N.
 | 
						|
*>          If JOB = 'N' or 'S', ILO = 1 and IHI = N.
 | 
						|
*> \endverbatim
 | 
						|
*>
 | 
						|
*> \param[out] LSCALE
 | 
						|
*> \verbatim
 | 
						|
*>          LSCALE is DOUBLE PRECISION array, dimension (N)
 | 
						|
*>          Details of the permutations and scaling factors applied
 | 
						|
*>          to the left side of A and B.  If P(j) is the index of the
 | 
						|
*>          row interchanged with row j, and D(j)
 | 
						|
*>          is the scaling factor applied to row j, then
 | 
						|
*>            LSCALE(j) = P(j)    for J = 1,...,ILO-1
 | 
						|
*>                      = D(j)    for J = ILO,...,IHI
 | 
						|
*>                      = P(j)    for J = IHI+1,...,N.
 | 
						|
*>          The order in which the interchanges are made is N to IHI+1,
 | 
						|
*>          then 1 to ILO-1.
 | 
						|
*> \endverbatim
 | 
						|
*>
 | 
						|
*> \param[out] RSCALE
 | 
						|
*> \verbatim
 | 
						|
*>          RSCALE is DOUBLE PRECISION array, dimension (N)
 | 
						|
*>          Details of the permutations and scaling factors applied
 | 
						|
*>          to the right side of A and B.  If P(j) is the index of the
 | 
						|
*>          column interchanged with column j, and D(j)
 | 
						|
*>          is the scaling factor applied to column j, then
 | 
						|
*>            LSCALE(j) = P(j)    for J = 1,...,ILO-1
 | 
						|
*>                      = D(j)    for J = ILO,...,IHI
 | 
						|
*>                      = P(j)    for J = IHI+1,...,N.
 | 
						|
*>          The order in which the interchanges are made is N to IHI+1,
 | 
						|
*>          then 1 to ILO-1.
 | 
						|
*> \endverbatim
 | 
						|
*>
 | 
						|
*> \param[out] WORK
 | 
						|
*> \verbatim
 | 
						|
*>          WORK is DOUBLE PRECISION array, dimension (lwork)
 | 
						|
*>          lwork must be at least max(1,6*N) when JOB = 'S' or 'B', and
 | 
						|
*>          at least 1 when JOB = 'N' or 'P'.
 | 
						|
*> \endverbatim
 | 
						|
*>
 | 
						|
*> \param[out] INFO
 | 
						|
*> \verbatim
 | 
						|
*>          INFO is INTEGER
 | 
						|
*>          = 0:  successful exit
 | 
						|
*>          < 0:  if INFO = -i, the i-th argument had an illegal value.
 | 
						|
*> \endverbatim
 | 
						|
*
 | 
						|
*  Authors:
 | 
						|
*  ========
 | 
						|
*
 | 
						|
*> \author Univ. of Tennessee 
 | 
						|
*> \author Univ. of California Berkeley 
 | 
						|
*> \author Univ. of Colorado Denver 
 | 
						|
*> \author NAG Ltd. 
 | 
						|
*
 | 
						|
*> \date November 2011
 | 
						|
*
 | 
						|
*> \ingroup doubleGBcomputational
 | 
						|
*
 | 
						|
*> \par Further Details:
 | 
						|
*  =====================
 | 
						|
*>
 | 
						|
*> \verbatim
 | 
						|
*>
 | 
						|
*>  See R.C. WARD, Balancing the generalized eigenvalue problem,
 | 
						|
*>                 SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.
 | 
						|
*> \endverbatim
 | 
						|
*>
 | 
						|
*  =====================================================================
 | 
						|
      SUBROUTINE DGGBAL( JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE,
 | 
						|
     $                   RSCALE, WORK, INFO )
 | 
						|
*
 | 
						|
*  -- LAPACK computational routine (version 3.4.0) --
 | 
						|
*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 | 
						|
*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 | 
						|
*     November 2011
 | 
						|
*
 | 
						|
*     .. Scalar Arguments ..
 | 
						|
      CHARACTER          JOB
 | 
						|
      INTEGER            IHI, ILO, INFO, LDA, LDB, N
 | 
						|
*     ..
 | 
						|
*     .. Array Arguments ..
 | 
						|
      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), LSCALE( * ),
 | 
						|
     $                   RSCALE( * ), WORK( * )
 | 
						|
*     ..
 | 
						|
*
 | 
						|
*  =====================================================================
 | 
						|
*
 | 
						|
*     .. Parameters ..
 | 
						|
      DOUBLE PRECISION   ZERO, HALF, ONE
 | 
						|
      PARAMETER          ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )
 | 
						|
      DOUBLE PRECISION   THREE, SCLFAC
 | 
						|
      PARAMETER          ( THREE = 3.0D+0, SCLFAC = 1.0D+1 )
 | 
						|
*     ..
 | 
						|
*     .. Local Scalars ..
 | 
						|
      INTEGER            I, ICAB, IFLOW, IP1, IR, IRAB, IT, J, JC, JP1,
 | 
						|
     $                   K, KOUNT, L, LCAB, LM1, LRAB, LSFMAX, LSFMIN,
 | 
						|
     $                   M, NR, NRP2
 | 
						|
      DOUBLE PRECISION   ALPHA, BASL, BETA, CAB, CMAX, COEF, COEF2,
 | 
						|
     $                   COEF5, COR, EW, EWC, GAMMA, PGAMMA, RAB, SFMAX,
 | 
						|
     $                   SFMIN, SUM, T, TA, TB, TC
 | 
						|
*     ..
 | 
						|
*     .. External Functions ..
 | 
						|
      LOGICAL            LSAME
 | 
						|
      INTEGER            IDAMAX
 | 
						|
      DOUBLE PRECISION   DDOT, DLAMCH
 | 
						|
      EXTERNAL           LSAME, IDAMAX, DDOT, DLAMCH
 | 
						|
*     ..
 | 
						|
*     .. External Subroutines ..
 | 
						|
      EXTERNAL           DAXPY, DSCAL, DSWAP, XERBLA
 | 
						|
*     ..
 | 
						|
*     .. Intrinsic Functions ..
 | 
						|
      INTRINSIC          ABS, DBLE, INT, LOG10, MAX, MIN, SIGN
 | 
						|
*     ..
 | 
						|
*     .. Executable Statements ..
 | 
						|
*
 | 
						|
*     Test the input parameters
 | 
						|
*
 | 
						|
      INFO = 0
 | 
						|
      IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
 | 
						|
     $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
 | 
						|
         INFO = -1
 | 
						|
      ELSE IF( N.LT.0 ) THEN
 | 
						|
         INFO = -2
 | 
						|
      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
 | 
						|
         INFO = -4
 | 
						|
      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
 | 
						|
         INFO = -6
 | 
						|
      END IF
 | 
						|
      IF( INFO.NE.0 ) THEN
 | 
						|
         CALL XERBLA( 'DGGBAL', -INFO )
 | 
						|
         RETURN
 | 
						|
      END IF
 | 
						|
*
 | 
						|
*     Quick return if possible
 | 
						|
*
 | 
						|
      IF( N.EQ.0 ) THEN
 | 
						|
         ILO = 1
 | 
						|
         IHI = N
 | 
						|
         RETURN
 | 
						|
      END IF
 | 
						|
*
 | 
						|
      IF( N.EQ.1 ) THEN
 | 
						|
         ILO = 1
 | 
						|
         IHI = N
 | 
						|
         LSCALE( 1 ) = ONE
 | 
						|
         RSCALE( 1 ) = ONE
 | 
						|
         RETURN
 | 
						|
      END IF
 | 
						|
*
 | 
						|
      IF( LSAME( JOB, 'N' ) ) THEN
 | 
						|
         ILO = 1
 | 
						|
         IHI = N
 | 
						|
         DO 10 I = 1, N
 | 
						|
            LSCALE( I ) = ONE
 | 
						|
            RSCALE( I ) = ONE
 | 
						|
   10    CONTINUE
 | 
						|
         RETURN
 | 
						|
      END IF
 | 
						|
*
 | 
						|
      K = 1
 | 
						|
      L = N
 | 
						|
      IF( LSAME( JOB, 'S' ) )
 | 
						|
     $   GO TO 190
 | 
						|
*
 | 
						|
      GO TO 30
 | 
						|
*
 | 
						|
*     Permute the matrices A and B to isolate the eigenvalues.
 | 
						|
*
 | 
						|
*     Find row with one nonzero in columns 1 through L
 | 
						|
*
 | 
						|
   20 CONTINUE
 | 
						|
      L = LM1
 | 
						|
      IF( L.NE.1 )
 | 
						|
     $   GO TO 30
 | 
						|
*
 | 
						|
      RSCALE( 1 ) = ONE
 | 
						|
      LSCALE( 1 ) = ONE
 | 
						|
      GO TO 190
 | 
						|
*
 | 
						|
   30 CONTINUE
 | 
						|
      LM1 = L - 1
 | 
						|
      DO 80 I = L, 1, -1
 | 
						|
         DO 40 J = 1, LM1
 | 
						|
            JP1 = J + 1
 | 
						|
            IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
 | 
						|
     $         GO TO 50
 | 
						|
   40    CONTINUE
 | 
						|
         J = L
 | 
						|
         GO TO 70
 | 
						|
*
 | 
						|
   50    CONTINUE
 | 
						|
         DO 60 J = JP1, L
 | 
						|
            IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
 | 
						|
     $         GO TO 80
 | 
						|
   60    CONTINUE
 | 
						|
         J = JP1 - 1
 | 
						|
*
 | 
						|
   70    CONTINUE
 | 
						|
         M = L
 | 
						|
         IFLOW = 1
 | 
						|
         GO TO 160
 | 
						|
   80 CONTINUE
 | 
						|
      GO TO 100
 | 
						|
*
 | 
						|
*     Find column with one nonzero in rows K through N
 | 
						|
*
 | 
						|
   90 CONTINUE
 | 
						|
      K = K + 1
 | 
						|
*
 | 
						|
  100 CONTINUE
 | 
						|
      DO 150 J = K, L
 | 
						|
         DO 110 I = K, LM1
 | 
						|
            IP1 = I + 1
 | 
						|
            IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
 | 
						|
     $         GO TO 120
 | 
						|
  110    CONTINUE
 | 
						|
         I = L
 | 
						|
         GO TO 140
 | 
						|
  120    CONTINUE
 | 
						|
         DO 130 I = IP1, L
 | 
						|
            IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
 | 
						|
     $         GO TO 150
 | 
						|
  130    CONTINUE
 | 
						|
         I = IP1 - 1
 | 
						|
  140    CONTINUE
 | 
						|
         M = K
 | 
						|
         IFLOW = 2
 | 
						|
         GO TO 160
 | 
						|
  150 CONTINUE
 | 
						|
      GO TO 190
 | 
						|
*
 | 
						|
*     Permute rows M and I
 | 
						|
*
 | 
						|
  160 CONTINUE
 | 
						|
      LSCALE( M ) = I
 | 
						|
      IF( I.EQ.M )
 | 
						|
     $   GO TO 170
 | 
						|
      CALL DSWAP( N-K+1, A( I, K ), LDA, A( M, K ), LDA )
 | 
						|
      CALL DSWAP( N-K+1, B( I, K ), LDB, B( M, K ), LDB )
 | 
						|
*
 | 
						|
*     Permute columns M and J
 | 
						|
*
 | 
						|
  170 CONTINUE
 | 
						|
      RSCALE( M ) = J
 | 
						|
      IF( J.EQ.M )
 | 
						|
     $   GO TO 180
 | 
						|
      CALL DSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )
 | 
						|
      CALL DSWAP( L, B( 1, J ), 1, B( 1, M ), 1 )
 | 
						|
*
 | 
						|
  180 CONTINUE
 | 
						|
      GO TO ( 20, 90 )IFLOW
 | 
						|
*
 | 
						|
  190 CONTINUE
 | 
						|
      ILO = K
 | 
						|
      IHI = L
 | 
						|
*
 | 
						|
      IF( LSAME( JOB, 'P' ) ) THEN
 | 
						|
         DO 195 I = ILO, IHI
 | 
						|
            LSCALE( I ) = ONE
 | 
						|
            RSCALE( I ) = ONE
 | 
						|
  195    CONTINUE
 | 
						|
         RETURN
 | 
						|
      END IF
 | 
						|
*
 | 
						|
      IF( ILO.EQ.IHI )
 | 
						|
     $   RETURN
 | 
						|
*
 | 
						|
*     Balance the submatrix in rows ILO to IHI.
 | 
						|
*
 | 
						|
      NR = IHI - ILO + 1
 | 
						|
      DO 200 I = ILO, IHI
 | 
						|
         RSCALE( I ) = ZERO
 | 
						|
         LSCALE( I ) = ZERO
 | 
						|
*
 | 
						|
         WORK( I ) = ZERO
 | 
						|
         WORK( I+N ) = ZERO
 | 
						|
         WORK( I+2*N ) = ZERO
 | 
						|
         WORK( I+3*N ) = ZERO
 | 
						|
         WORK( I+4*N ) = ZERO
 | 
						|
         WORK( I+5*N ) = ZERO
 | 
						|
  200 CONTINUE
 | 
						|
*
 | 
						|
*     Compute right side vector in resulting linear equations
 | 
						|
*
 | 
						|
      BASL = LOG10( SCLFAC )
 | 
						|
      DO 240 I = ILO, IHI
 | 
						|
         DO 230 J = ILO, IHI
 | 
						|
            TB = B( I, J )
 | 
						|
            TA = A( I, J )
 | 
						|
            IF( TA.EQ.ZERO )
 | 
						|
     $         GO TO 210
 | 
						|
            TA = LOG10( ABS( TA ) ) / BASL
 | 
						|
  210       CONTINUE
 | 
						|
            IF( TB.EQ.ZERO )
 | 
						|
     $         GO TO 220
 | 
						|
            TB = LOG10( ABS( TB ) ) / BASL
 | 
						|
  220       CONTINUE
 | 
						|
            WORK( I+4*N ) = WORK( I+4*N ) - TA - TB
 | 
						|
            WORK( J+5*N ) = WORK( J+5*N ) - TA - TB
 | 
						|
  230    CONTINUE
 | 
						|
  240 CONTINUE
 | 
						|
*
 | 
						|
      COEF = ONE / DBLE( 2*NR )
 | 
						|
      COEF2 = COEF*COEF
 | 
						|
      COEF5 = HALF*COEF2
 | 
						|
      NRP2 = NR + 2
 | 
						|
      BETA = ZERO
 | 
						|
      IT = 1
 | 
						|
*
 | 
						|
*     Start generalized conjugate gradient iteration
 | 
						|
*
 | 
						|
  250 CONTINUE
 | 
						|
*
 | 
						|
      GAMMA = DDOT( NR, WORK( ILO+4*N ), 1, WORK( ILO+4*N ), 1 ) +
 | 
						|
     $        DDOT( NR, WORK( ILO+5*N ), 1, WORK( ILO+5*N ), 1 )
 | 
						|
*
 | 
						|
      EW = ZERO
 | 
						|
      EWC = ZERO
 | 
						|
      DO 260 I = ILO, IHI
 | 
						|
         EW = EW + WORK( I+4*N )
 | 
						|
         EWC = EWC + WORK( I+5*N )
 | 
						|
  260 CONTINUE
 | 
						|
*
 | 
						|
      GAMMA = COEF*GAMMA - COEF2*( EW**2+EWC**2 ) - COEF5*( EW-EWC )**2
 | 
						|
      IF( GAMMA.EQ.ZERO )
 | 
						|
     $   GO TO 350
 | 
						|
      IF( IT.NE.1 )
 | 
						|
     $   BETA = GAMMA / PGAMMA
 | 
						|
      T = COEF5*( EWC-THREE*EW )
 | 
						|
      TC = COEF5*( EW-THREE*EWC )
 | 
						|
*
 | 
						|
      CALL DSCAL( NR, BETA, WORK( ILO ), 1 )
 | 
						|
      CALL DSCAL( NR, BETA, WORK( ILO+N ), 1 )
 | 
						|
*
 | 
						|
      CALL DAXPY( NR, COEF, WORK( ILO+4*N ), 1, WORK( ILO+N ), 1 )
 | 
						|
      CALL DAXPY( NR, COEF, WORK( ILO+5*N ), 1, WORK( ILO ), 1 )
 | 
						|
*
 | 
						|
      DO 270 I = ILO, IHI
 | 
						|
         WORK( I ) = WORK( I ) + TC
 | 
						|
         WORK( I+N ) = WORK( I+N ) + T
 | 
						|
  270 CONTINUE
 | 
						|
*
 | 
						|
*     Apply matrix to vector
 | 
						|
*
 | 
						|
      DO 300 I = ILO, IHI
 | 
						|
         KOUNT = 0
 | 
						|
         SUM = ZERO
 | 
						|
         DO 290 J = ILO, IHI
 | 
						|
            IF( A( I, J ).EQ.ZERO )
 | 
						|
     $         GO TO 280
 | 
						|
            KOUNT = KOUNT + 1
 | 
						|
            SUM = SUM + WORK( J )
 | 
						|
  280       CONTINUE
 | 
						|
            IF( B( I, J ).EQ.ZERO )
 | 
						|
     $         GO TO 290
 | 
						|
            KOUNT = KOUNT + 1
 | 
						|
            SUM = SUM + WORK( J )
 | 
						|
  290    CONTINUE
 | 
						|
         WORK( I+2*N ) = DBLE( KOUNT )*WORK( I+N ) + SUM
 | 
						|
  300 CONTINUE
 | 
						|
*
 | 
						|
      DO 330 J = ILO, IHI
 | 
						|
         KOUNT = 0
 | 
						|
         SUM = ZERO
 | 
						|
         DO 320 I = ILO, IHI
 | 
						|
            IF( A( I, J ).EQ.ZERO )
 | 
						|
     $         GO TO 310
 | 
						|
            KOUNT = KOUNT + 1
 | 
						|
            SUM = SUM + WORK( I+N )
 | 
						|
  310       CONTINUE
 | 
						|
            IF( B( I, J ).EQ.ZERO )
 | 
						|
     $         GO TO 320
 | 
						|
            KOUNT = KOUNT + 1
 | 
						|
            SUM = SUM + WORK( I+N )
 | 
						|
  320    CONTINUE
 | 
						|
         WORK( J+3*N ) = DBLE( KOUNT )*WORK( J ) + SUM
 | 
						|
  330 CONTINUE
 | 
						|
*
 | 
						|
      SUM = DDOT( NR, WORK( ILO+N ), 1, WORK( ILO+2*N ), 1 ) +
 | 
						|
     $      DDOT( NR, WORK( ILO ), 1, WORK( ILO+3*N ), 1 )
 | 
						|
      ALPHA = GAMMA / SUM
 | 
						|
*
 | 
						|
*     Determine correction to current iteration
 | 
						|
*
 | 
						|
      CMAX = ZERO
 | 
						|
      DO 340 I = ILO, IHI
 | 
						|
         COR = ALPHA*WORK( I+N )
 | 
						|
         IF( ABS( COR ).GT.CMAX )
 | 
						|
     $      CMAX = ABS( COR )
 | 
						|
         LSCALE( I ) = LSCALE( I ) + COR
 | 
						|
         COR = ALPHA*WORK( I )
 | 
						|
         IF( ABS( COR ).GT.CMAX )
 | 
						|
     $      CMAX = ABS( COR )
 | 
						|
         RSCALE( I ) = RSCALE( I ) + COR
 | 
						|
  340 CONTINUE
 | 
						|
      IF( CMAX.LT.HALF )
 | 
						|
     $   GO TO 350
 | 
						|
*
 | 
						|
      CALL DAXPY( NR, -ALPHA, WORK( ILO+2*N ), 1, WORK( ILO+4*N ), 1 )
 | 
						|
      CALL DAXPY( NR, -ALPHA, WORK( ILO+3*N ), 1, WORK( ILO+5*N ), 1 )
 | 
						|
*
 | 
						|
      PGAMMA = GAMMA
 | 
						|
      IT = IT + 1
 | 
						|
      IF( IT.LE.NRP2 )
 | 
						|
     $   GO TO 250
 | 
						|
*
 | 
						|
*     End generalized conjugate gradient iteration
 | 
						|
*
 | 
						|
  350 CONTINUE
 | 
						|
      SFMIN = DLAMCH( 'S' )
 | 
						|
      SFMAX = ONE / SFMIN
 | 
						|
      LSFMIN = INT( LOG10( SFMIN ) / BASL+ONE )
 | 
						|
      LSFMAX = INT( LOG10( SFMAX ) / BASL )
 | 
						|
      DO 360 I = ILO, IHI
 | 
						|
         IRAB = IDAMAX( N-ILO+1, A( I, ILO ), LDA )
 | 
						|
         RAB = ABS( A( I, IRAB+ILO-1 ) )
 | 
						|
         IRAB = IDAMAX( N-ILO+1, B( I, ILO ), LDB )
 | 
						|
         RAB = MAX( RAB, ABS( B( I, IRAB+ILO-1 ) ) )
 | 
						|
         LRAB = INT( LOG10( RAB+SFMIN ) / BASL+ONE )
 | 
						|
         IR = LSCALE( I ) + SIGN( HALF, LSCALE( I ) )
 | 
						|
         IR = MIN( MAX( IR, LSFMIN ), LSFMAX, LSFMAX-LRAB )
 | 
						|
         LSCALE( I ) = SCLFAC**IR
 | 
						|
         ICAB = IDAMAX( IHI, A( 1, I ), 1 )
 | 
						|
         CAB = ABS( A( ICAB, I ) )
 | 
						|
         ICAB = IDAMAX( IHI, B( 1, I ), 1 )
 | 
						|
         CAB = MAX( CAB, ABS( B( ICAB, I ) ) )
 | 
						|
         LCAB = INT( LOG10( CAB+SFMIN ) / BASL+ONE )
 | 
						|
         JC = RSCALE( I ) + SIGN( HALF, RSCALE( I ) )
 | 
						|
         JC = MIN( MAX( JC, LSFMIN ), LSFMAX, LSFMAX-LCAB )
 | 
						|
         RSCALE( I ) = SCLFAC**JC
 | 
						|
  360 CONTINUE
 | 
						|
*
 | 
						|
*     Row scaling of matrices A and B
 | 
						|
*
 | 
						|
      DO 370 I = ILO, IHI
 | 
						|
         CALL DSCAL( N-ILO+1, LSCALE( I ), A( I, ILO ), LDA )
 | 
						|
         CALL DSCAL( N-ILO+1, LSCALE( I ), B( I, ILO ), LDB )
 | 
						|
  370 CONTINUE
 | 
						|
*
 | 
						|
*     Column scaling of matrices A and B
 | 
						|
*
 | 
						|
      DO 380 J = ILO, IHI
 | 
						|
         CALL DSCAL( IHI, RSCALE( J ), A( 1, J ), 1 )
 | 
						|
         CALL DSCAL( IHI, RSCALE( J ), B( 1, J ), 1 )
 | 
						|
  380 CONTINUE
 | 
						|
*
 | 
						|
      RETURN
 | 
						|
*
 | 
						|
*     End of DGGBAL
 | 
						|
*
 | 
						|
      END
 |