File:  [local] / rpl / lapack / lapack / dlasq3.f
Revision 1.8: download - view: text, annotated - select for diffs - revision graph
Tue Dec 21 13:53:33 2010 UTC (13 years, 4 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_3, rpl-4_1_2, rpl-4_1_1, rpl-4_1_0, rpl-4_0_24, rpl-4_0_22, rpl-4_0_21, rpl-4_0_20, rpl-4_0, HEAD
Mise à jour de lapack vers la version 3.3.0.

    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.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: *  -- June 2010                                                       --
   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/output) 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  (input/output) DOUBLE PRECISION
   78: *
   79: *  DMIN2  (input/output) DOUBLE PRECISION
   80: *
   81: *  DN     (input/output) DOUBLE PRECISION
   82: *
   83: *  DN1    (input/output) DOUBLE PRECISION
   84: *
   85: *  DN2    (input/output) DOUBLE PRECISION
   86: *
   87: *  G      (input/output) DOUBLE PRECISION
   88: *
   89: *  TAU    (input/output) DOUBLE PRECISION
   90: *
   91: *         These are passed as arguments in order to save their values
   92: *         between calls to DLASQ3.
   93: *
   94: *  =====================================================================
   95: *
   96: *     .. Parameters ..
   97:       DOUBLE PRECISION   CBIAS
   98:       PARAMETER          ( CBIAS = 1.50D0 )
   99:       DOUBLE PRECISION   ZERO, QURTR, HALF, ONE, TWO, HUNDRD
  100:       PARAMETER          ( ZERO = 0.0D0, QURTR = 0.250D0, HALF = 0.5D0,
  101:      $                     ONE = 1.0D0, TWO = 2.0D0, HUNDRD = 100.0D0 )
  102: *     ..
  103: *     .. Local Scalars ..
  104:       INTEGER            IPN4, J4, N0IN, NN, TTYPE
  105:       DOUBLE PRECISION   EPS, S, T, TEMP, TOL, TOL2
  106: *     ..
  107: *     .. External Subroutines ..
  108:       EXTERNAL           DLASQ4, DLASQ5, DLASQ6
  109: *     ..
  110: *     .. External Function ..
  111:       DOUBLE PRECISION   DLAMCH
  112:       LOGICAL            DISNAN
  113:       EXTERNAL           DISNAN, DLAMCH
  114: *     ..
  115: *     .. Intrinsic Functions ..
  116:       INTRINSIC          ABS, MAX, MIN, SQRT
  117: *     ..
  118: *     .. Executable Statements ..
  119: *
  120:       N0IN = N0
  121:       EPS = DLAMCH( 'Precision' )
  122:       TOL = EPS*HUNDRD
  123:       TOL2 = TOL**2
  124: *
  125: *     Check for deflation.
  126: *
  127:    10 CONTINUE
  128: *
  129:       IF( N0.LT.I0 )
  130:      $   RETURN
  131:       IF( N0.EQ.I0 )
  132:      $   GO TO 20
  133:       NN = 4*N0 + PP
  134:       IF( N0.EQ.( I0+1 ) )
  135:      $   GO TO 40
  136: *
  137: *     Check whether E(N0-1) is negligible, 1 eigenvalue.
  138: *
  139:       IF( Z( NN-5 ).GT.TOL2*( SIGMA+Z( NN-3 ) ) .AND.
  140:      $    Z( NN-2*PP-4 ).GT.TOL2*Z( NN-7 ) )
  141:      $   GO TO 30
  142: *
  143:    20 CONTINUE
  144: *
  145:       Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMA
  146:       N0 = N0 - 1
  147:       GO TO 10
  148: *
  149: *     Check  whether E(N0-2) is negligible, 2 eigenvalues.
  150: *
  151:    30 CONTINUE
  152: *
  153:       IF( Z( NN-9 ).GT.TOL2*SIGMA .AND.
  154:      $    Z( NN-2*PP-8 ).GT.TOL2*Z( NN-11 ) )
  155:      $   GO TO 50
  156: *
  157:    40 CONTINUE
  158: *
  159:       IF( Z( NN-3 ).GT.Z( NN-7 ) ) THEN
  160:          S = Z( NN-3 )
  161:          Z( NN-3 ) = Z( NN-7 )
  162:          Z( NN-7 ) = S
  163:       END IF
  164:       IF( Z( NN-5 ).GT.Z( NN-3 )*TOL2 ) THEN
  165:          T = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) )
  166:          S = Z( NN-3 )*( Z( NN-5 ) / T )
  167:          IF( S.LE.T ) THEN
  168:             S = Z( NN-3 )*( Z( NN-5 ) /
  169:      $          ( T*( ONE+SQRT( ONE+S / T ) ) ) )
  170:          ELSE
  171:             S = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) )
  172:          END IF
  173:          T = Z( NN-7 ) + ( S+Z( NN-5 ) )
  174:          Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T )
  175:          Z( NN-7 ) = T
  176:       END IF
  177:       Z( 4*N0-7 ) = Z( NN-7 ) + SIGMA
  178:       Z( 4*N0-3 ) = Z( NN-3 ) + SIGMA
  179:       N0 = N0 - 2
  180:       GO TO 10
  181: *
  182:    50 CONTINUE
  183:       IF( PP.EQ.2  184:      $   PP = 0
  185: *
  186: *     Reverse the qd-array, if warranted.
  187: *
  188:       IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THEN
  189:          IF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THEN
  190:             IPN4 = 4*( I0+N0 )
  191:             DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4
  192:                TEMP = Z( J4-3 )
  193:                Z( J4-3 ) = Z( IPN4-J4-3 )
  194:                Z( IPN4-J4-3 ) = TEMP
  195:                TEMP = Z( J4-2 )
  196:                Z( J4-2 ) = Z( IPN4-J4-2 )
  197:                Z( IPN4-J4-2 ) = TEMP
  198:                TEMP = Z( J4-1 )
  199:                Z( J4-1 ) = Z( IPN4-J4-5 )
  200:                Z( IPN4-J4-5 ) = TEMP
  201:                TEMP = Z( J4 )
  202:                Z( J4 ) = Z( IPN4-J4-4 )
  203:                Z( IPN4-J4-4 ) = TEMP
  204:    60       CONTINUE
  205:             IF( N0-I0.LE.4 ) THEN
  206:                Z( 4*N0+PP-1 ) = Z( 4*I0+PP-1 )
  207:                Z( 4*N0-PP ) = Z( 4*I0-PP )
  208:             END IF
  209:             DMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) )
  210:             Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ),
  211:      $                            Z( 4*I0+PP+3 ) )
  212:             Z( 4*N0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ),
  213:      $                          Z( 4*I0-PP+4 ) )
  214:             QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) )
  215:             DMIN = -ZERO
  216:          END IF
  217:       END IF
  218: *
  219: *     Choose a shift.
  220: *
  221:       CALL DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1,
  222:      $             DN2, TAU, TTYPE, G )
  223: *
  224: *     Call dqds until DMIN > 0.
  225: *
  226:    70 CONTINUE
  227: *
  228:       CALL DLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN,
  229:      $             DN1, DN2, IEEE )
  230: *
  231:       NDIV = NDIV + ( N0-I0+2 )
  232:       ITER = ITER + 1
  233: *
  234: *     Check status.
  235: *
  236:       IF( DMIN.GE.ZERO .AND. DMIN1.GT.ZERO ) THEN
  237: *
  238: *        Success.
  239: *
  240:          GO TO 90
  241: *
  242:       ELSE IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND. 
  243:      $         Z( 4*( N0-1 )-PP ).LT.TOL*( SIGMA+DN1 ) .AND.
  244:      $         ABS( DN ).LT.TOL*SIGMA ) THEN
  245: *
  246: *        Convergence hidden by negative DN.
  247: *
  248:          Z( 4*( N0-1 )-PP+2 ) = ZERO
  249:          DMIN = ZERO
  250:          GO TO 90
  251:       ELSE IF( DMIN.LT.ZERO ) THEN
  252: *
  253: *        TAU too big. Select new TAU and try again.
  254: *
  255:          NFAIL = NFAIL + 1
  256:          IF( TTYPE.LT.-22 ) THEN
  257: *
  258: *           Failed twice. Play it safe.
  259: *
  260:             TAU = ZERO
  261:          ELSE IF( DMIN1.GT.ZERO ) THEN
  262: *
  263: *           Late failure. Gives excellent shift.
  264: *
  265:             TAU = ( TAU+DMIN )*( ONE-TWO*EPS )
  266:             TTYPE = TTYPE - 11
  267:          ELSE
  268: *
  269: *           Early failure. Divide by 4.
  270: *
  271:             TAU = QURTR*TAU
  272:             TTYPE = TTYPE - 12
  273:          END IF
  274:          GO TO 70
  275:       ELSE IF( DISNAN( DMIN ) ) THEN
  276: *
  277: *        NaN.
  278: *
  279:          IF( TAU.EQ.ZERO ) THEN
  280:             GO TO 80
  281:          ELSE
  282:             TAU = ZERO
  283:             GO TO 70
  284:          END IF
  285:       ELSE
  286: *            
  287: *        Possible underflow. Play it safe.
  288: *
  289:          GO TO 80
  290:       END IF
  291: *
  292: *     Risk of underflow.
  293: *
  294:    80 CONTINUE
  295:       CALL DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 )
  296:       NDIV = NDIV + ( N0-I0+2 )
  297:       ITER = ITER + 1
  298:       TAU = ZERO
  299: *
  300:    90 CONTINUE
  301:       IF( TAU.LT.SIGMA ) THEN
  302:          DESIG = DESIG + TAU
  303:          T = SIGMA + DESIG
  304:          DESIG = DESIG - ( T-SIGMA )
  305:       ELSE
  306:          T = SIGMA + TAU
  307:          DESIG = SIGMA - ( T-TAU ) + DESIG
  308:       END IF
  309:       SIGMA = T
  310: *
  311:       RETURN
  312: *
  313: *     End of DLASQ3
  314: *
  315:       END

CVSweb interface <joel.bertrand@systella.fr>