File:  [local] / rpl / lapack / lapack / dlasq3.f
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Jan 26 15:22:46 2010 UTC (14 years, 3 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Initial revision

    1:       SUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
    2:      $                   ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
    3:      $                   DN2, G, TAU )
    4: *
    5: *  -- LAPACK routine (version 3.2)                                    --
    6: *
    7: *  -- Contributed by Osni Marques of the Lawrence Berkeley National   --
    8: *  -- Laboratory and Beresford Parlett of the Univ. of California at  --
    9: *  -- Berkeley                                                        --
   10: *  -- November 2008                                                   --
   11: *
   12: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
   13: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
   14: *
   15: *     .. Scalar Arguments ..
   16:       LOGICAL            IEEE
   17:       INTEGER            I0, ITER, N0, NDIV, NFAIL, PP
   18:       DOUBLE PRECISION   DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, G,
   19:      $                   QMAX, SIGMA, TAU
   20: *     ..
   21: *     .. Array Arguments ..
   22:       DOUBLE PRECISION   Z( * )
   23: *     ..
   24: *
   25: *  Purpose
   26: *  =======
   27: *
   28: *  DLASQ3 checks for deflation, computes a shift (TAU) and calls dqds.
   29: *  In case of failure it changes shifts, and tries again until output
   30: *  is positive.
   31: *
   32: *  Arguments
   33: *  =========
   34: *
   35: *  I0     (input) INTEGER
   36: *         First index.
   37: *
   38: *  N0     (input) INTEGER
   39: *         Last index.
   40: *
   41: *  Z      (input) DOUBLE PRECISION array, dimension ( 4*N )
   42: *         Z holds the qd array.
   43: *
   44: *  PP     (input/output) INTEGER
   45: *         PP=0 for ping, PP=1 for pong.
   46: *         PP=2 indicates that flipping was applied to the Z array   
   47: *         and that the initial tests for deflation should not be 
   48: *         performed.
   49: *
   50: *  DMIN   (output) DOUBLE PRECISION
   51: *         Minimum value of d.
   52: *
   53: *  SIGMA  (output) DOUBLE PRECISION
   54: *         Sum of shifts used in current segment.
   55: *
   56: *  DESIG  (input/output) DOUBLE PRECISION
   57: *         Lower order part of SIGMA
   58: *
   59: *  QMAX   (input) DOUBLE PRECISION
   60: *         Maximum value of q.
   61: *
   62: *  NFAIL  (output) INTEGER
   63: *         Number of times shift was too big.
   64: *
   65: *  ITER   (output) INTEGER
   66: *         Number of iterations.
   67: *
   68: *  NDIV   (output) INTEGER
   69: *         Number of divisions.
   70: *
   71: *  IEEE   (input) LOGICAL
   72: *         Flag for IEEE or non IEEE arithmetic (passed to DLASQ5).
   73: *
   74: *  TTYPE  (input/output) INTEGER
   75: *         Shift type.
   76: *
   77: *  DMIN1, DMIN2, DN, DN1, DN2, G, TAU (input/output) DOUBLE PRECISION
   78: *         These are passed as arguments in order to save their values
   79: *         between calls to DLASQ3.
   80: *
   81: *  =====================================================================
   82: *
   83: *     .. Parameters ..
   84:       DOUBLE PRECISION   CBIAS
   85:       PARAMETER          ( CBIAS = 1.50D0 )
   86:       DOUBLE PRECISION   ZERO, QURTR, HALF, ONE, TWO, HUNDRD
   87:       PARAMETER          ( ZERO = 0.0D0, QURTR = 0.250D0, HALF = 0.5D0,
   88:      $                     ONE = 1.0D0, TWO = 2.0D0, HUNDRD = 100.0D0 )
   89: *     ..
   90: *     .. Local Scalars ..
   91:       INTEGER            IPN4, J4, N0IN, NN, TTYPE
   92:       DOUBLE PRECISION   EPS, S, T, TEMP, TOL, TOL2
   93: *     ..
   94: *     .. External Subroutines ..
   95:       EXTERNAL           DLASQ4, DLASQ5, DLASQ6
   96: *     ..
   97: *     .. External Function ..
   98:       DOUBLE PRECISION   DLAMCH
   99:       LOGICAL            DISNAN
  100:       EXTERNAL           DISNAN, DLAMCH
  101: *     ..
  102: *     .. Intrinsic Functions ..
  103:       INTRINSIC          ABS, MAX, MIN, SQRT
  104: *     ..
  105: *     .. Executable Statements ..
  106: *
  107:       N0IN = N0
  108:       EPS = DLAMCH( 'Precision' )
  109:       TOL = EPS*HUNDRD
  110:       TOL2 = TOL**2
  111: *
  112: *     Check for deflation.
  113: *
  114:    10 CONTINUE
  115: *
  116:       IF( N0.LT.I0 )
  117:      $   RETURN
  118:       IF( N0.EQ.I0 )
  119:      $   GO TO 20
  120:       NN = 4*N0 + PP
  121:       IF( N0.EQ.( I0+1 ) )
  122:      $   GO TO 40
  123: *
  124: *     Check whether E(N0-1) is negligible, 1 eigenvalue.
  125: *
  126:       IF( Z( NN-5 ).GT.TOL2*( SIGMA+Z( NN-3 ) ) .AND.
  127:      $    Z( NN-2*PP-4 ).GT.TOL2*Z( NN-7 ) )
  128:      $   GO TO 30
  129: *
  130:    20 CONTINUE
  131: *
  132:       Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMA
  133:       N0 = N0 - 1
  134:       GO TO 10
  135: *
  136: *     Check  whether E(N0-2) is negligible, 2 eigenvalues.
  137: *
  138:    30 CONTINUE
  139: *
  140:       IF( Z( NN-9 ).GT.TOL2*SIGMA .AND.
  141:      $    Z( NN-2*PP-8 ).GT.TOL2*Z( NN-11 ) )
  142:      $   GO TO 50
  143: *
  144:    40 CONTINUE
  145: *
  146:       IF( Z( NN-3 ).GT.Z( NN-7 ) ) THEN
  147:          S = Z( NN-3 )
  148:          Z( NN-3 ) = Z( NN-7 )
  149:          Z( NN-7 ) = S
  150:       END IF
  151:       IF( Z( NN-5 ).GT.Z( NN-3 )*TOL2 ) THEN
  152:          T = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) )
  153:          S = Z( NN-3 )*( Z( NN-5 ) / T )
  154:          IF( S.LE.T ) THEN
  155:             S = Z( NN-3 )*( Z( NN-5 ) /
  156:      $          ( T*( ONE+SQRT( ONE+S / T ) ) ) )
  157:          ELSE
  158:             S = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) )
  159:          END IF
  160:          T = Z( NN-7 ) + ( S+Z( NN-5 ) )
  161:          Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T )
  162:          Z( NN-7 ) = T
  163:       END IF
  164:       Z( 4*N0-7 ) = Z( NN-7 ) + SIGMA
  165:       Z( 4*N0-3 ) = Z( NN-3 ) + SIGMA
  166:       N0 = N0 - 2
  167:       GO TO 10
  168: *
  169:    50 CONTINUE
  170:       IF( PP.EQ.2  171:      $   PP = 0
  172: *
  173: *     Reverse the qd-array, if warranted.
  174: *
  175:       IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THEN
  176:          IF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THEN
  177:             IPN4 = 4*( I0+N0 )
  178:             DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4
  179:                TEMP = Z( J4-3 )
  180:                Z( J4-3 ) = Z( IPN4-J4-3 )
  181:                Z( IPN4-J4-3 ) = TEMP
  182:                TEMP = Z( J4-2 )
  183:                Z( J4-2 ) = Z( IPN4-J4-2 )
  184:                Z( IPN4-J4-2 ) = TEMP
  185:                TEMP = Z( J4-1 )
  186:                Z( J4-1 ) = Z( IPN4-J4-5 )
  187:                Z( IPN4-J4-5 ) = TEMP
  188:                TEMP = Z( J4 )
  189:                Z( J4 ) = Z( IPN4-J4-4 )
  190:                Z( IPN4-J4-4 ) = TEMP
  191:    60       CONTINUE
  192:             IF( N0-I0.LE.4 ) THEN
  193:                Z( 4*N0+PP-1 ) = Z( 4*I0+PP-1 )
  194:                Z( 4*N0-PP ) = Z( 4*I0-PP )
  195:             END IF
  196:             DMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) )
  197:             Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ),
  198:      $                            Z( 4*I0+PP+3 ) )
  199:             Z( 4*N0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ),
  200:      $                          Z( 4*I0-PP+4 ) )
  201:             QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) )
  202:             DMIN = -ZERO
  203:          END IF
  204:       END IF
  205: *
  206: *     Choose a shift.
  207: *
  208:       CALL DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1,
  209:      $             DN2, TAU, TTYPE, G )
  210: *
  211: *     Call dqds until DMIN > 0.
  212: *
  213:    70 CONTINUE
  214: *
  215:       CALL DLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN,
  216:      $             DN1, DN2, IEEE )
  217: *
  218:       NDIV = NDIV + ( N0-I0+2 )
  219:       ITER = ITER + 1
  220: *
  221: *     Check status.
  222: *
  223:       IF( DMIN.GE.ZERO .AND. DMIN1.GT.ZERO ) THEN
  224: *
  225: *        Success.
  226: *
  227:          GO TO 90
  228: *
  229:       ELSE IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND. 
  230:      $         Z( 4*( N0-1 )-PP ).LT.TOL*( SIGMA+DN1 ) .AND.
  231:      $         ABS( DN ).LT.TOL*SIGMA ) THEN
  232: *
  233: *        Convergence hidden by negative DN.
  234: *
  235:          Z( 4*( N0-1 )-PP+2 ) = ZERO
  236:          DMIN = ZERO
  237:          GO TO 90
  238:       ELSE IF( DMIN.LT.ZERO ) THEN
  239: *
  240: *        TAU too big. Select new TAU and try again.
  241: *
  242:          NFAIL = NFAIL + 1
  243:          IF( TTYPE.LT.-22 ) THEN
  244: *
  245: *           Failed twice. Play it safe.
  246: *
  247:             TAU = ZERO
  248:          ELSE IF( DMIN1.GT.ZERO ) THEN
  249: *
  250: *           Late failure. Gives excellent shift.
  251: *
  252:             TAU = ( TAU+DMIN )*( ONE-TWO*EPS )
  253:             TTYPE = TTYPE - 11
  254:          ELSE
  255: *
  256: *           Early failure. Divide by 4.
  257: *
  258:             TAU = QURTR*TAU
  259:             TTYPE = TTYPE - 12
  260:          END IF
  261:          GO TO 70
  262:       ELSE IF( DISNAN( DMIN ) ) THEN
  263: *
  264: *        NaN.
  265: *
  266:          IF( TAU.EQ.ZERO ) THEN
  267:             GO TO 80
  268:          ELSE
  269:             TAU = ZERO
  270:             GO TO 70
  271:          END IF
  272:       ELSE
  273: *            
  274: *        Possible underflow. Play it safe.
  275: *
  276:          GO TO 80
  277:       END IF
  278: *
  279: *     Risk of underflow.
  280: *
  281:    80 CONTINUE
  282:       CALL DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 )
  283:       NDIV = NDIV + ( N0-I0+2 )
  284:       ITER = ITER + 1
  285:       TAU = ZERO
  286: *
  287:    90 CONTINUE
  288:       IF( TAU.LT.SIGMA ) THEN
  289:          DESIG = DESIG + TAU
  290:          T = SIGMA + DESIG
  291:          DESIG = DESIG - ( T-SIGMA )
  292:       ELSE
  293:          T = SIGMA + TAU
  294:          DESIG = SIGMA - ( T-TAU ) + DESIG
  295:       END IF
  296:       SIGMA = T
  297: *
  298:       RETURN
  299: *
  300: *     End of DLASQ3
  301: *
  302:       END

CVSweb interface <joel.bertrand@systella.fr>