LAPACK 3.3.0

sggbal.f

Go to the documentation of this file.
00001       SUBROUTINE SGGBAL( JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE,
00002      $                   RSCALE, WORK, INFO )
00003 *
00004 *  -- LAPACK routine (version 3.2) --
00005 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00006 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00007 *     November 2006
00008 *
00009 *     .. Scalar Arguments ..
00010       CHARACTER          JOB
00011       INTEGER            IHI, ILO, INFO, LDA, LDB, N
00012 *     ..
00013 *     .. Array Arguments ..
00014       REAL               A( LDA, * ), B( LDB, * ), LSCALE( * ),
00015      $                   RSCALE( * ), WORK( * )
00016 *     ..
00017 *
00018 *  Purpose
00019 *  =======
00020 *
00021 *  SGGBAL balances a pair of general real matrices (A,B).  This
00022 *  involves, first, permuting A and B by similarity transformations to
00023 *  isolate eigenvalues in the first 1 to ILO$-$1 and last IHI+1 to N
00024 *  elements on the diagonal; and second, applying a diagonal similarity
00025 *  transformation to rows and columns ILO to IHI to make the rows
00026 *  and columns as close in norm as possible. Both steps are optional.
00027 *
00028 *  Balancing may reduce the 1-norm of the matrices, and improve the
00029 *  accuracy of the computed eigenvalues and/or eigenvectors in the
00030 *  generalized eigenvalue problem A*x = lambda*B*x.
00031 *
00032 *  Arguments
00033 *  =========
00034 *
00035 *  JOB     (input) CHARACTER*1
00036 *          Specifies the operations to be performed on A and B:
00037 *          = 'N':  none:  simply set ILO = 1, IHI = N, LSCALE(I) = 1.0
00038 *                  and RSCALE(I) = 1.0 for i = 1,...,N.
00039 *          = 'P':  permute only;
00040 *          = 'S':  scale only;
00041 *          = 'B':  both permute and scale.
00042 *
00043 *  N       (input) INTEGER
00044 *          The order of the matrices A and B.  N >= 0.
00045 *
00046 *  A       (input/output) REAL array, dimension (LDA,N)
00047 *          On entry, the input matrix A.
00048 *          On exit,  A is overwritten by the balanced matrix.
00049 *          If JOB = 'N', A is not referenced.
00050 *
00051 *  LDA     (input) INTEGER
00052 *          The leading dimension of the array A. LDA >= max(1,N).
00053 *
00054 *  B       (input/output) REAL array, dimension (LDB,N)
00055 *          On entry, the input matrix B.
00056 *          On exit,  B is overwritten by the balanced matrix.
00057 *          If JOB = 'N', B is not referenced.
00058 *
00059 *  LDB     (input) INTEGER
00060 *          The leading dimension of the array B. LDB >= max(1,N).
00061 *
00062 *  ILO     (output) INTEGER
00063 *  IHI     (output) INTEGER
00064 *          ILO and IHI are set to integers such that on exit
00065 *          A(i,j) = 0 and B(i,j) = 0 if i > j and
00066 *          j = 1,...,ILO-1 or i = IHI+1,...,N.
00067 *          If JOB = 'N' or 'S', ILO = 1 and IHI = N.
00068 *
00069 *  LSCALE  (output) REAL array, dimension (N)
00070 *          Details of the permutations and scaling factors applied
00071 *          to the left side of A and B.  If P(j) is the index of the
00072 *          row interchanged with row j, and D(j)
00073 *          is the scaling factor applied to row j, then
00074 *            LSCALE(j) = P(j)    for J = 1,...,ILO-1
00075 *                      = D(j)    for J = ILO,...,IHI
00076 *                      = P(j)    for J = IHI+1,...,N.
00077 *          The order in which the interchanges are made is N to IHI+1,
00078 *          then 1 to ILO-1.
00079 *
00080 *  RSCALE  (output) REAL array, dimension (N)
00081 *          Details of the permutations and scaling factors applied
00082 *          to the right side of A and B.  If P(j) is the index of the
00083 *          column interchanged with column j, and D(j)
00084 *          is the scaling factor applied to column j, then
00085 *            LSCALE(j) = P(j)    for J = 1,...,ILO-1
00086 *                      = D(j)    for J = ILO,...,IHI
00087 *                      = P(j)    for J = IHI+1,...,N.
00088 *          The order in which the interchanges are made is N to IHI+1,
00089 *          then 1 to ILO-1.
00090 *
00091 *  WORK    (workspace) REAL array, dimension (lwork)
00092 *          lwork must be at least max(1,6*N) when JOB = 'S' or 'B', and
00093 *          at least 1 when JOB = 'N' or 'P'.
00094 *
00095 *  INFO    (output) INTEGER
00096 *          = 0:  successful exit
00097 *          < 0:  if INFO = -i, the i-th argument had an illegal value.
00098 *
00099 *  Further Details
00100 *  ===============
00101 *
00102 *  See R.C. WARD, Balancing the generalized eigenvalue problem,
00103 *                 SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.
00104 *
00105 *  =====================================================================
00106 *
00107 *     .. Parameters ..
00108       REAL               ZERO, HALF, ONE
00109       PARAMETER          ( ZERO = 0.0E+0, HALF = 0.5E+0, ONE = 1.0E+0 )
00110       REAL               THREE, SCLFAC
00111       PARAMETER          ( THREE = 3.0E+0, SCLFAC = 1.0E+1 )
00112 *     ..
00113 *     .. Local Scalars ..
00114       INTEGER            I, ICAB, IFLOW, IP1, IR, IRAB, IT, J, JC, JP1,
00115      $                   K, KOUNT, L, LCAB, LM1, LRAB, LSFMAX, LSFMIN,
00116      $                   M, NR, NRP2
00117       REAL               ALPHA, BASL, BETA, CAB, CMAX, COEF, COEF2,
00118      $                   COEF5, COR, EW, EWC, GAMMA, PGAMMA, RAB, SFMAX,
00119      $                   SFMIN, SUM, T, TA, TB, TC
00120 *     ..
00121 *     .. External Functions ..
00122       LOGICAL            LSAME
00123       INTEGER            ISAMAX
00124       REAL               SDOT, SLAMCH
00125       EXTERNAL           LSAME, ISAMAX, SDOT, SLAMCH
00126 *     ..
00127 *     .. External Subroutines ..
00128       EXTERNAL           SAXPY, SSCAL, SSWAP, XERBLA
00129 *     ..
00130 *     .. Intrinsic Functions ..
00131       INTRINSIC          ABS, INT, LOG10, MAX, MIN, REAL, SIGN
00132 *     ..
00133 *     .. Executable Statements ..
00134 *
00135 *     Test the input parameters
00136 *
00137       INFO = 0
00138       IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
00139      $    .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
00140          INFO = -1
00141       ELSE IF( N.LT.0 ) THEN
00142          INFO = -2
00143       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00144          INFO = -4
00145       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00146          INFO = -6
00147       END IF
00148       IF( INFO.NE.0 ) THEN
00149          CALL XERBLA( 'SGGBAL', -INFO )
00150          RETURN
00151       END IF
00152 *
00153 *     Quick return if possible
00154 *
00155       IF( N.EQ.0 ) THEN
00156          ILO = 1
00157          IHI = N
00158          RETURN
00159       END IF
00160 *
00161       IF( N.EQ.1 ) THEN
00162          ILO = 1
00163          IHI = N
00164          LSCALE( 1 ) = ONE
00165          RSCALE( 1 ) = ONE
00166          RETURN
00167       END IF
00168 *
00169       IF( LSAME( JOB, 'N' ) ) THEN
00170          ILO = 1
00171          IHI = N
00172          DO 10 I = 1, N
00173             LSCALE( I ) = ONE
00174             RSCALE( I ) = ONE
00175    10    CONTINUE
00176          RETURN
00177       END IF
00178 *
00179       K = 1
00180       L = N
00181       IF( LSAME( JOB, 'S' ) )
00182      $   GO TO 190
00183 *
00184       GO TO 30
00185 *
00186 *     Permute the matrices A and B to isolate the eigenvalues.
00187 *
00188 *     Find row with one nonzero in columns 1 through L
00189 *
00190    20 CONTINUE
00191       L = LM1
00192       IF( L.NE.1 )
00193      $   GO TO 30
00194 *
00195       RSCALE( 1 ) = ONE
00196       LSCALE( 1 ) = ONE
00197       GO TO 190
00198 *
00199    30 CONTINUE
00200       LM1 = L - 1
00201       DO 80 I = L, 1, -1
00202          DO 40 J = 1, LM1
00203             JP1 = J + 1
00204             IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
00205      $         GO TO 50
00206    40    CONTINUE
00207          J = L
00208          GO TO 70
00209 *
00210    50    CONTINUE
00211          DO 60 J = JP1, L
00212             IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
00213      $         GO TO 80
00214    60    CONTINUE
00215          J = JP1 - 1
00216 *
00217    70    CONTINUE
00218          M = L
00219          IFLOW = 1
00220          GO TO 160
00221    80 CONTINUE
00222       GO TO 100
00223 *
00224 *     Find column with one nonzero in rows K through N
00225 *
00226    90 CONTINUE
00227       K = K + 1
00228 *
00229   100 CONTINUE
00230       DO 150 J = K, L
00231          DO 110 I = K, LM1
00232             IP1 = I + 1
00233             IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
00234      $         GO TO 120
00235   110    CONTINUE
00236          I = L
00237          GO TO 140
00238   120    CONTINUE
00239          DO 130 I = IP1, L
00240             IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )
00241      $         GO TO 150
00242   130    CONTINUE
00243          I = IP1 - 1
00244   140    CONTINUE
00245          M = K
00246          IFLOW = 2
00247          GO TO 160
00248   150 CONTINUE
00249       GO TO 190
00250 *
00251 *     Permute rows M and I
00252 *
00253   160 CONTINUE
00254       LSCALE( M ) = I
00255       IF( I.EQ.M )
00256      $   GO TO 170
00257       CALL SSWAP( N-K+1, A( I, K ), LDA, A( M, K ), LDA )
00258       CALL SSWAP( N-K+1, B( I, K ), LDB, B( M, K ), LDB )
00259 *
00260 *     Permute columns M and J
00261 *
00262   170 CONTINUE
00263       RSCALE( M ) = J
00264       IF( J.EQ.M )
00265      $   GO TO 180
00266       CALL SSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )
00267       CALL SSWAP( L, B( 1, J ), 1, B( 1, M ), 1 )
00268 *
00269   180 CONTINUE
00270       GO TO ( 20, 90 )IFLOW
00271 *
00272   190 CONTINUE
00273       ILO = K
00274       IHI = L
00275 *
00276       IF( LSAME( JOB, 'P' ) ) THEN
00277          DO 195 I = ILO, IHI
00278             LSCALE( I ) = ONE
00279             RSCALE( I ) = ONE
00280   195    CONTINUE
00281          RETURN
00282       END IF
00283 *
00284       IF( ILO.EQ.IHI )
00285      $   RETURN
00286 *
00287 *     Balance the submatrix in rows ILO to IHI.
00288 *
00289       NR = IHI - ILO + 1
00290       DO 200 I = ILO, IHI
00291          RSCALE( I ) = ZERO
00292          LSCALE( I ) = ZERO
00293 *
00294          WORK( I ) = ZERO
00295          WORK( I+N ) = ZERO
00296          WORK( I+2*N ) = ZERO
00297          WORK( I+3*N ) = ZERO
00298          WORK( I+4*N ) = ZERO
00299          WORK( I+5*N ) = ZERO
00300   200 CONTINUE
00301 *
00302 *     Compute right side vector in resulting linear equations
00303 *
00304       BASL = LOG10( SCLFAC )
00305       DO 240 I = ILO, IHI
00306          DO 230 J = ILO, IHI
00307             TB = B( I, J )
00308             TA = A( I, J )
00309             IF( TA.EQ.ZERO )
00310      $         GO TO 210
00311             TA = LOG10( ABS( TA ) ) / BASL
00312   210       CONTINUE
00313             IF( TB.EQ.ZERO )
00314      $         GO TO 220
00315             TB = LOG10( ABS( TB ) ) / BASL
00316   220       CONTINUE
00317             WORK( I+4*N ) = WORK( I+4*N ) - TA - TB
00318             WORK( J+5*N ) = WORK( J+5*N ) - TA - TB
00319   230    CONTINUE
00320   240 CONTINUE
00321 *
00322       COEF = ONE / REAL( 2*NR )
00323       COEF2 = COEF*COEF
00324       COEF5 = HALF*COEF2
00325       NRP2 = NR + 2
00326       BETA = ZERO
00327       IT = 1
00328 *
00329 *     Start generalized conjugate gradient iteration
00330 *
00331   250 CONTINUE
00332 *
00333       GAMMA = SDOT( NR, WORK( ILO+4*N ), 1, WORK( ILO+4*N ), 1 ) +
00334      $        SDOT( NR, WORK( ILO+5*N ), 1, WORK( ILO+5*N ), 1 )
00335 *
00336       EW = ZERO
00337       EWC = ZERO
00338       DO 260 I = ILO, IHI
00339          EW = EW + WORK( I+4*N )
00340          EWC = EWC + WORK( I+5*N )
00341   260 CONTINUE
00342 *
00343       GAMMA = COEF*GAMMA - COEF2*( EW**2+EWC**2 ) - COEF5*( EW-EWC )**2
00344       IF( GAMMA.EQ.ZERO )
00345      $   GO TO 350
00346       IF( IT.NE.1 )
00347      $   BETA = GAMMA / PGAMMA
00348       T = COEF5*( EWC-THREE*EW )
00349       TC = COEF5*( EW-THREE*EWC )
00350 *
00351       CALL SSCAL( NR, BETA, WORK( ILO ), 1 )
00352       CALL SSCAL( NR, BETA, WORK( ILO+N ), 1 )
00353 *
00354       CALL SAXPY( NR, COEF, WORK( ILO+4*N ), 1, WORK( ILO+N ), 1 )
00355       CALL SAXPY( NR, COEF, WORK( ILO+5*N ), 1, WORK( ILO ), 1 )
00356 *
00357       DO 270 I = ILO, IHI
00358          WORK( I ) = WORK( I ) + TC
00359          WORK( I+N ) = WORK( I+N ) + T
00360   270 CONTINUE
00361 *
00362 *     Apply matrix to vector
00363 *
00364       DO 300 I = ILO, IHI
00365          KOUNT = 0
00366          SUM = ZERO
00367          DO 290 J = ILO, IHI
00368             IF( A( I, J ).EQ.ZERO )
00369      $         GO TO 280
00370             KOUNT = KOUNT + 1
00371             SUM = SUM + WORK( J )
00372   280       CONTINUE
00373             IF( B( I, J ).EQ.ZERO )
00374      $         GO TO 290
00375             KOUNT = KOUNT + 1
00376             SUM = SUM + WORK( J )
00377   290    CONTINUE
00378          WORK( I+2*N ) = REAL( KOUNT )*WORK( I+N ) + SUM
00379   300 CONTINUE
00380 *
00381       DO 330 J = ILO, IHI
00382          KOUNT = 0
00383          SUM = ZERO
00384          DO 320 I = ILO, IHI
00385             IF( A( I, J ).EQ.ZERO )
00386      $         GO TO 310
00387             KOUNT = KOUNT + 1
00388             SUM = SUM + WORK( I+N )
00389   310       CONTINUE
00390             IF( B( I, J ).EQ.ZERO )
00391      $         GO TO 320
00392             KOUNT = KOUNT + 1
00393             SUM = SUM + WORK( I+N )
00394   320    CONTINUE
00395          WORK( J+3*N ) = REAL( KOUNT )*WORK( J ) + SUM
00396   330 CONTINUE
00397 *
00398       SUM = SDOT( NR, WORK( ILO+N ), 1, WORK( ILO+2*N ), 1 ) +
00399      $      SDOT( NR, WORK( ILO ), 1, WORK( ILO+3*N ), 1 )
00400       ALPHA = GAMMA / SUM
00401 *
00402 *     Determine correction to current iteration
00403 *
00404       CMAX = ZERO
00405       DO 340 I = ILO, IHI
00406          COR = ALPHA*WORK( I+N )
00407          IF( ABS( COR ).GT.CMAX )
00408      $      CMAX = ABS( COR )
00409          LSCALE( I ) = LSCALE( I ) + COR
00410          COR = ALPHA*WORK( I )
00411          IF( ABS( COR ).GT.CMAX )
00412      $      CMAX = ABS( COR )
00413          RSCALE( I ) = RSCALE( I ) + COR
00414   340 CONTINUE
00415       IF( CMAX.LT.HALF )
00416      $   GO TO 350
00417 *
00418       CALL SAXPY( NR, -ALPHA, WORK( ILO+2*N ), 1, WORK( ILO+4*N ), 1 )
00419       CALL SAXPY( NR, -ALPHA, WORK( ILO+3*N ), 1, WORK( ILO+5*N ), 1 )
00420 *
00421       PGAMMA = GAMMA
00422       IT = IT + 1
00423       IF( IT.LE.NRP2 )
00424      $   GO TO 250
00425 *
00426 *     End generalized conjugate gradient iteration
00427 *
00428   350 CONTINUE
00429       SFMIN = SLAMCH( 'S' )
00430       SFMAX = ONE / SFMIN
00431       LSFMIN = INT( LOG10( SFMIN ) / BASL+ONE )
00432       LSFMAX = INT( LOG10( SFMAX ) / BASL )
00433       DO 360 I = ILO, IHI
00434          IRAB = ISAMAX( N-ILO+1, A( I, ILO ), LDA )
00435          RAB = ABS( A( I, IRAB+ILO-1 ) )
00436          IRAB = ISAMAX( N-ILO+1, B( I, ILO ), LDB )
00437          RAB = MAX( RAB, ABS( B( I, IRAB+ILO-1 ) ) )
00438          LRAB = INT( LOG10( RAB+SFMIN ) / BASL+ONE )
00439          IR = LSCALE( I ) + SIGN( HALF, LSCALE( I ) )
00440          IR = MIN( MAX( IR, LSFMIN ), LSFMAX, LSFMAX-LRAB )
00441          LSCALE( I ) = SCLFAC**IR
00442          ICAB = ISAMAX( IHI, A( 1, I ), 1 )
00443          CAB = ABS( A( ICAB, I ) )
00444          ICAB = ISAMAX( IHI, B( 1, I ), 1 )
00445          CAB = MAX( CAB, ABS( B( ICAB, I ) ) )
00446          LCAB = INT( LOG10( CAB+SFMIN ) / BASL+ONE )
00447          JC = RSCALE( I ) + SIGN( HALF, RSCALE( I ) )
00448          JC = MIN( MAX( JC, LSFMIN ), LSFMAX, LSFMAX-LCAB )
00449          RSCALE( I ) = SCLFAC**JC
00450   360 CONTINUE
00451 *
00452 *     Row scaling of matrices A and B
00453 *
00454       DO 370 I = ILO, IHI
00455          CALL SSCAL( N-ILO+1, LSCALE( I ), A( I, ILO ), LDA )
00456          CALL SSCAL( N-ILO+1, LSCALE( I ), B( I, ILO ), LDB )
00457   370 CONTINUE
00458 *
00459 *     Column scaling of matrices A and B
00460 *
00461       DO 380 J = ILO, IHI
00462          CALL SSCAL( IHI, RSCALE( J ), A( 1, J ), 1 )
00463          CALL SSCAL( IHI, RSCALE( J ), B( 1, J ), 1 )
00464   380 CONTINUE
00465 *
00466       RETURN
00467 *
00468 *     End of SGGBAL
00469 *
00470       END
 All Files Functions