File:  [local] / rpl / lapack / lapack / dlaqtr.f
Revision 1.19: download - view: text, annotated - select for diffs - revision graph
Mon Aug 7 08:38:56 2023 UTC (8 months, 3 weeks ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_35, rpl-4_1_34, HEAD
Première mise à jour de lapack et blas.

    1: *> \brief \b DLAQTR solves a real quasi-triangular system of equations, or a complex quasi-triangular system of special form, in real arithmetic.
    2: *
    3: *  =========== DOCUMENTATION ===========
    4: *
    5: * Online html documentation available at
    6: *            http://www.netlib.org/lapack/explore-html/
    7: *
    8: *> \htmlonly
    9: *> Download DLAQTR + dependencies
   10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqtr.f">
   11: *> [TGZ]</a>
   12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqtr.f">
   13: *> [ZIP]</a>
   14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqtr.f">
   15: *> [TXT]</a>
   16: *> \endhtmlonly
   17: *
   18: *  Definition:
   19: *  ===========
   20: *
   21: *       SUBROUTINE DLAQTR( LTRAN, LREAL, N, T, LDT, B, W, SCALE, X, WORK,
   22: *                          INFO )
   23: *
   24: *       .. Scalar Arguments ..
   25: *       LOGICAL            LREAL, LTRAN
   26: *       INTEGER            INFO, LDT, N
   27: *       DOUBLE PRECISION   SCALE, W
   28: *       ..
   29: *       .. Array Arguments ..
   30: *       DOUBLE PRECISION   B( * ), T( LDT, * ), WORK( * ), X( * )
   31: *       ..
   32: *
   33: *
   34: *> \par Purpose:
   35: *  =============
   36: *>
   37: *> \verbatim
   38: *>
   39: *> DLAQTR solves the real quasi-triangular system
   40: *>
   41: *>              op(T)*p = scale*c,               if LREAL = .TRUE.
   42: *>
   43: *> or the complex quasi-triangular systems
   44: *>
   45: *>            op(T + iB)*(p+iq) = scale*(c+id),  if LREAL = .FALSE.
   46: *>
   47: *> in real arithmetic, where T is upper quasi-triangular.
   48: *> If LREAL = .FALSE., then the first diagonal block of T must be
   49: *> 1 by 1, B is the specially structured matrix
   50: *>
   51: *>                B = [ b(1) b(2) ... b(n) ]
   52: *>                    [       w            ]
   53: *>                    [           w        ]
   54: *>                    [              .     ]
   55: *>                    [                 w  ]
   56: *>
   57: *> op(A) = A or A**T, A**T denotes the transpose of
   58: *> matrix A.
   59: *>
   60: *> On input, X = [ c ].  On output, X = [ p ].
   61: *>               [ d ]                  [ q ]
   62: *>
   63: *> This subroutine is designed for the condition number estimation
   64: *> in routine DTRSNA.
   65: *> \endverbatim
   66: *
   67: *  Arguments:
   68: *  ==========
   69: *
   70: *> \param[in] LTRAN
   71: *> \verbatim
   72: *>          LTRAN is LOGICAL
   73: *>          On entry, LTRAN specifies the option of conjugate transpose:
   74: *>             = .FALSE.,    op(T+i*B) = T+i*B,
   75: *>             = .TRUE.,     op(T+i*B) = (T+i*B)**T.
   76: *> \endverbatim
   77: *>
   78: *> \param[in] LREAL
   79: *> \verbatim
   80: *>          LREAL is LOGICAL
   81: *>          On entry, LREAL specifies the input matrix structure:
   82: *>             = .FALSE.,    the input is complex
   83: *>             = .TRUE.,     the input is real
   84: *> \endverbatim
   85: *>
   86: *> \param[in] N
   87: *> \verbatim
   88: *>          N is INTEGER
   89: *>          On entry, N specifies the order of T+i*B. N >= 0.
   90: *> \endverbatim
   91: *>
   92: *> \param[in] T
   93: *> \verbatim
   94: *>          T is DOUBLE PRECISION array, dimension (LDT,N)
   95: *>          On entry, T contains a matrix in Schur canonical form.
   96: *>          If LREAL = .FALSE., then the first diagonal block of T mu
   97: *>          be 1 by 1.
   98: *> \endverbatim
   99: *>
  100: *> \param[in] LDT
  101: *> \verbatim
  102: *>          LDT is INTEGER
  103: *>          The leading dimension of the matrix T. LDT >= max(1,N).
  104: *> \endverbatim
  105: *>
  106: *> \param[in] B
  107: *> \verbatim
  108: *>          B is DOUBLE PRECISION array, dimension (N)
  109: *>          On entry, B contains the elements to form the matrix
  110: *>          B as described above.
  111: *>          If LREAL = .TRUE., B is not referenced.
  112: *> \endverbatim
  113: *>
  114: *> \param[in] W
  115: *> \verbatim
  116: *>          W is DOUBLE PRECISION
  117: *>          On entry, W is the diagonal element of the matrix B.
  118: *>          If LREAL = .TRUE., W is not referenced.
  119: *> \endverbatim
  120: *>
  121: *> \param[out] SCALE
  122: *> \verbatim
  123: *>          SCALE is DOUBLE PRECISION
  124: *>          On exit, SCALE is the scale factor.
  125: *> \endverbatim
  126: *>
  127: *> \param[in,out] X
  128: *> \verbatim
  129: *>          X is DOUBLE PRECISION array, dimension (2*N)
  130: *>          On entry, X contains the right hand side of the system.
  131: *>          On exit, X is overwritten by the solution.
  132: *> \endverbatim
  133: *>
  134: *> \param[out] WORK
  135: *> \verbatim
  136: *>          WORK is DOUBLE PRECISION array, dimension (N)
  137: *> \endverbatim
  138: *>
  139: *> \param[out] INFO
  140: *> \verbatim
  141: *>          INFO is INTEGER
  142: *>          On exit, INFO is set to
  143: *>             0: successful exit.
  144: *>               1: the some diagonal 1 by 1 block has been perturbed by
  145: *>                  a small number SMIN to keep nonsingularity.
  146: *>               2: the some diagonal 2 by 2 block has been perturbed by
  147: *>                  a small number in DLALN2 to keep nonsingularity.
  148: *>          NOTE: In the interests of speed, this routine does not
  149: *>                check the inputs for errors.
  150: *> \endverbatim
  151: *
  152: *  Authors:
  153: *  ========
  154: *
  155: *> \author Univ. of Tennessee
  156: *> \author Univ. of California Berkeley
  157: *> \author Univ. of Colorado Denver
  158: *> \author NAG Ltd.
  159: *
  160: *> \ingroup doubleOTHERauxiliary
  161: *
  162: *  =====================================================================
  163:       SUBROUTINE DLAQTR( LTRAN, LREAL, N, T, LDT, B, W, SCALE, X, WORK,
  164:      $                   INFO )
  165: *
  166: *  -- LAPACK auxiliary routine --
  167: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
  168: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  169: *
  170: *     .. Scalar Arguments ..
  171:       LOGICAL            LREAL, LTRAN
  172:       INTEGER            INFO, LDT, N
  173:       DOUBLE PRECISION   SCALE, W
  174: *     ..
  175: *     .. Array Arguments ..
  176:       DOUBLE PRECISION   B( * ), T( LDT, * ), WORK( * ), X( * )
  177: *     ..
  178: *
  179: * =====================================================================
  180: *
  181: *     .. Parameters ..
  182:       DOUBLE PRECISION   ZERO, ONE
  183:       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  184: *     ..
  185: *     .. Local Scalars ..
  186:       LOGICAL            NOTRAN
  187:       INTEGER            I, IERR, J, J1, J2, JNEXT, K, N1, N2
  188:       DOUBLE PRECISION   BIGNUM, EPS, REC, SCALOC, SI, SMIN, SMINW,
  189:      $                   SMLNUM, SR, TJJ, TMP, XJ, XMAX, XNORM, Z
  190: *     ..
  191: *     .. Local Arrays ..
  192:       DOUBLE PRECISION   D( 2, 2 ), V( 2, 2 )
  193: *     ..
  194: *     .. External Functions ..
  195:       INTEGER            IDAMAX
  196:       DOUBLE PRECISION   DASUM, DDOT, DLAMCH, DLANGE
  197:       EXTERNAL           IDAMAX, DASUM, DDOT, DLAMCH, DLANGE
  198: *     ..
  199: *     .. External Subroutines ..
  200:       EXTERNAL           DAXPY, DLADIV, DLALN2, DSCAL
  201: *     ..
  202: *     .. Intrinsic Functions ..
  203:       INTRINSIC          ABS, MAX
  204: *     ..
  205: *     .. Executable Statements ..
  206: *
  207: *     Do not test the input parameters for errors
  208: *
  209:       NOTRAN = .NOT.LTRAN
  210:       INFO = 0
  211: *
  212: *     Quick return if possible
  213: *
  214:       IF( N.EQ.0 )
  215:      $   RETURN
  216: *
  217: *     Set constants to control overflow
  218: *
  219:       EPS = DLAMCH( 'P' )
  220:       SMLNUM = DLAMCH( 'S' ) / EPS
  221:       BIGNUM = ONE / SMLNUM
  222: *
  223:       XNORM = DLANGE( 'M', N, N, T, LDT, D )
  224:       IF( .NOT.LREAL )
  225:      $   XNORM = MAX( XNORM, ABS( W ), DLANGE( 'M', N, 1, B, N, D ) )
  226:       SMIN = MAX( SMLNUM, EPS*XNORM )
  227: *
  228: *     Compute 1-norm of each column of strictly upper triangular
  229: *     part of T to control overflow in triangular solver.
  230: *
  231:       WORK( 1 ) = ZERO
  232:       DO 10 J = 2, N
  233:          WORK( J ) = DASUM( J-1, T( 1, J ), 1 )
  234:    10 CONTINUE
  235: *
  236:       IF( .NOT.LREAL ) THEN
  237:          DO 20 I = 2, N
  238:             WORK( I ) = WORK( I ) + ABS( B( I ) )
  239:    20    CONTINUE
  240:       END IF
  241: *
  242:       N2 = 2*N
  243:       N1 = N
  244:       IF( .NOT.LREAL )
  245:      $   N1 = N2
  246:       K = IDAMAX( N1, X, 1 )
  247:       XMAX = ABS( X( K ) )
  248:       SCALE = ONE
  249: *
  250:       IF( XMAX.GT.BIGNUM ) THEN
  251:          SCALE = BIGNUM / XMAX
  252:          CALL DSCAL( N1, SCALE, X, 1 )
  253:          XMAX = BIGNUM
  254:       END IF
  255: *
  256:       IF( LREAL ) THEN
  257: *
  258:          IF( NOTRAN ) THEN
  259: *
  260: *           Solve T*p = scale*c
  261: *
  262:             JNEXT = N
  263:             DO 30 J = N, 1, -1
  264:                IF( J.GT.JNEXT )
  265:      $            GO TO 30
  266:                J1 = J
  267:                J2 = J
  268:                JNEXT = J - 1
  269:                IF( J.GT.1 ) THEN
  270:                   IF( T( J, J-1 ).NE.ZERO ) THEN
  271:                      J1 = J - 1
  272:                      JNEXT = J - 2
  273:                   END IF
  274:                END IF
  275: *
  276:                IF( J1.EQ.J2 ) THEN
  277: *
  278: *                 Meet 1 by 1 diagonal block
  279: *
  280: *                 Scale to avoid overflow when computing
  281: *                     x(j) = b(j)/T(j,j)
  282: *
  283:                   XJ = ABS( X( J1 ) )
  284:                   TJJ = ABS( T( J1, J1 ) )
  285:                   TMP = T( J1, J1 )
  286:                   IF( TJJ.LT.SMIN ) THEN
  287:                      TMP = SMIN
  288:                      TJJ = SMIN
  289:                      INFO = 1
  290:                   END IF
  291: *
  292:                   IF( XJ.EQ.ZERO )
  293:      $               GO TO 30
  294: *
  295:                   IF( TJJ.LT.ONE ) THEN
  296:                      IF( XJ.GT.BIGNUM*TJJ ) THEN
  297:                         REC = ONE / XJ
  298:                         CALL DSCAL( N, REC, X, 1 )
  299:                         SCALE = SCALE*REC
  300:                         XMAX = XMAX*REC
  301:                      END IF
  302:                   END IF
  303:                   X( J1 ) = X( J1 ) / TMP
  304:                   XJ = ABS( X( J1 ) )
  305: *
  306: *                 Scale x if necessary to avoid overflow when adding a
  307: *                 multiple of column j1 of T.
  308: *
  309:                   IF( XJ.GT.ONE ) THEN
  310:                      REC = ONE / XJ
  311:                      IF( WORK( J1 ).GT.( BIGNUM-XMAX )*REC ) THEN
  312:                         CALL DSCAL( N, REC, X, 1 )
  313:                         SCALE = SCALE*REC
  314:                      END IF
  315:                   END IF
  316:                   IF( J1.GT.1 ) THEN
  317:                      CALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )
  318:                      K = IDAMAX( J1-1, X, 1 )
  319:                      XMAX = ABS( X( K ) )
  320:                   END IF
  321: *
  322:                ELSE
  323: *
  324: *                 Meet 2 by 2 diagonal block
  325: *
  326: *                 Call 2 by 2 linear system solve, to take
  327: *                 care of possible overflow by scaling factor.
  328: *
  329:                   D( 1, 1 ) = X( J1 )
  330:                   D( 2, 1 ) = X( J2 )
  331:                   CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, T( J1, J1 ),
  332:      $                         LDT, ONE, ONE, D, 2, ZERO, ZERO, V, 2,
  333:      $                         SCALOC, XNORM, IERR )
  334:                   IF( IERR.NE.0 )
  335:      $               INFO = 2
  336: *
  337:                   IF( SCALOC.NE.ONE ) THEN
  338:                      CALL DSCAL( N, SCALOC, X, 1 )
  339:                      SCALE = SCALE*SCALOC
  340:                   END IF
  341:                   X( J1 ) = V( 1, 1 )
  342:                   X( J2 ) = V( 2, 1 )
  343: *
  344: *                 Scale V(1,1) (= X(J1)) and/or V(2,1) (=X(J2))
  345: *                 to avoid overflow in updating right-hand side.
  346: *
  347:                   XJ = MAX( ABS( V( 1, 1 ) ), ABS( V( 2, 1 ) ) )
  348:                   IF( XJ.GT.ONE ) THEN
  349:                      REC = ONE / XJ
  350:                      IF( MAX( WORK( J1 ), WORK( J2 ) ).GT.
  351:      $                   ( BIGNUM-XMAX )*REC ) THEN
  352:                         CALL DSCAL( N, REC, X, 1 )
  353:                         SCALE = SCALE*REC
  354:                      END IF
  355:                   END IF
  356: *
  357: *                 Update right-hand side
  358: *
  359:                   IF( J1.GT.1 ) THEN
  360:                      CALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )
  361:                      CALL DAXPY( J1-1, -X( J2 ), T( 1, J2 ), 1, X, 1 )
  362:                      K = IDAMAX( J1-1, X, 1 )
  363:                      XMAX = ABS( X( K ) )
  364:                   END IF
  365: *
  366:                END IF
  367: *
  368:    30       CONTINUE
  369: *
  370:          ELSE
  371: *
  372: *           Solve T**T*p = scale*c
  373: *
  374:             JNEXT = 1
  375:             DO 40 J = 1, N
  376:                IF( J.LT.JNEXT )
  377:      $            GO TO 40
  378:                J1 = J
  379:                J2 = J
  380:                JNEXT = J + 1
  381:                IF( J.LT.N ) THEN
  382:                   IF( T( J+1, J ).NE.ZERO ) THEN
  383:                      J2 = J + 1
  384:                      JNEXT = J + 2
  385:                   END IF
  386:                END IF
  387: *
  388:                IF( J1.EQ.J2 ) THEN
  389: *
  390: *                 1 by 1 diagonal block
  391: *
  392: *                 Scale if necessary to avoid overflow in forming the
  393: *                 right-hand side element by inner product.
  394: *
  395:                   XJ = ABS( X( J1 ) )
  396:                   IF( XMAX.GT.ONE ) THEN
  397:                      REC = ONE / XMAX
  398:                      IF( WORK( J1 ).GT.( BIGNUM-XJ )*REC ) THEN
  399:                         CALL DSCAL( N, REC, X, 1 )
  400:                         SCALE = SCALE*REC
  401:                         XMAX = XMAX*REC
  402:                      END IF
  403:                   END IF
  404: *
  405:                   X( J1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X, 1 )
  406: *
  407:                   XJ = ABS( X( J1 ) )
  408:                   TJJ = ABS( T( J1, J1 ) )
  409:                   TMP = T( J1, J1 )
  410:                   IF( TJJ.LT.SMIN ) THEN
  411:                      TMP = SMIN
  412:                      TJJ = SMIN
  413:                      INFO = 1
  414:                   END IF
  415: *
  416:                   IF( TJJ.LT.ONE ) THEN
  417:                      IF( XJ.GT.BIGNUM*TJJ ) THEN
  418:                         REC = ONE / XJ
  419:                         CALL DSCAL( N, REC, X, 1 )
  420:                         SCALE = SCALE*REC
  421:                         XMAX = XMAX*REC
  422:                      END IF
  423:                   END IF
  424:                   X( J1 ) = X( J1 ) / TMP
  425:                   XMAX = MAX( XMAX, ABS( X( J1 ) ) )
  426: *
  427:                ELSE
  428: *
  429: *                 2 by 2 diagonal block
  430: *
  431: *                 Scale if necessary to avoid overflow in forming the
  432: *                 right-hand side elements by inner product.
  433: *
  434:                   XJ = MAX( ABS( X( J1 ) ), ABS( X( J2 ) ) )
  435:                   IF( XMAX.GT.ONE ) THEN
  436:                      REC = ONE / XMAX
  437:                      IF( MAX( WORK( J2 ), WORK( J1 ) ).GT.( BIGNUM-XJ )*
  438:      $                   REC ) THEN
  439:                         CALL DSCAL( N, REC, X, 1 )
  440:                         SCALE = SCALE*REC
  441:                         XMAX = XMAX*REC
  442:                      END IF
  443:                   END IF
  444: *
  445:                   D( 1, 1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X,
  446:      $                        1 )
  447:                   D( 2, 1 ) = X( J2 ) - DDOT( J1-1, T( 1, J2 ), 1, X,
  448:      $                        1 )
  449: *
  450:                   CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, T( J1, J1 ),
  451:      $                         LDT, ONE, ONE, D, 2, ZERO, ZERO, V, 2,
  452:      $                         SCALOC, XNORM, IERR )
  453:                   IF( IERR.NE.0 )
  454:      $               INFO = 2
  455: *
  456:                   IF( SCALOC.NE.ONE ) THEN
  457:                      CALL DSCAL( N, SCALOC, X, 1 )
  458:                      SCALE = SCALE*SCALOC
  459:                   END IF
  460:                   X( J1 ) = V( 1, 1 )
  461:                   X( J2 ) = V( 2, 1 )
  462:                   XMAX = MAX( ABS( X( J1 ) ), ABS( X( J2 ) ), XMAX )
  463: *
  464:                END IF
  465:    40       CONTINUE
  466:          END IF
  467: *
  468:       ELSE
  469: *
  470:          SMINW = MAX( EPS*ABS( W ), SMIN )
  471:          IF( NOTRAN ) THEN
  472: *
  473: *           Solve (T + iB)*(p+iq) = c+id
  474: *
  475:             JNEXT = N
  476:             DO 70 J = N, 1, -1
  477:                IF( J.GT.JNEXT )
  478:      $            GO TO 70
  479:                J1 = J
  480:                J2 = J
  481:                JNEXT = J - 1
  482:                IF( J.GT.1 ) THEN
  483:                   IF( T( J, J-1 ).NE.ZERO ) THEN
  484:                      J1 = J - 1
  485:                      JNEXT = J - 2
  486:                   END IF
  487:                END IF
  488: *
  489:                IF( J1.EQ.J2 ) THEN
  490: *
  491: *                 1 by 1 diagonal block
  492: *
  493: *                 Scale if necessary to avoid overflow in division
  494: *
  495:                   Z = W
  496:                   IF( J1.EQ.1 )
  497:      $               Z = B( 1 )
  498:                   XJ = ABS( X( J1 ) ) + ABS( X( N+J1 ) )
  499:                   TJJ = ABS( T( J1, J1 ) ) + ABS( Z )
  500:                   TMP = T( J1, J1 )
  501:                   IF( TJJ.LT.SMINW ) THEN
  502:                      TMP = SMINW
  503:                      TJJ = SMINW
  504:                      INFO = 1
  505:                   END IF
  506: *
  507:                   IF( XJ.EQ.ZERO )
  508:      $               GO TO 70
  509: *
  510:                   IF( TJJ.LT.ONE ) THEN
  511:                      IF( XJ.GT.BIGNUM*TJJ ) THEN
  512:                         REC = ONE / XJ
  513:                         CALL DSCAL( N2, REC, X, 1 )
  514:                         SCALE = SCALE*REC
  515:                         XMAX = XMAX*REC
  516:                      END IF
  517:                   END IF
  518:                   CALL DLADIV( X( J1 ), X( N+J1 ), TMP, Z, SR, SI )
  519:                   X( J1 ) = SR
  520:                   X( N+J1 ) = SI
  521:                   XJ = ABS( X( J1 ) ) + ABS( X( N+J1 ) )
  522: *
  523: *                 Scale x if necessary to avoid overflow when adding a
  524: *                 multiple of column j1 of T.
  525: *
  526:                   IF( XJ.GT.ONE ) THEN
  527:                      REC = ONE / XJ
  528:                      IF( WORK( J1 ).GT.( BIGNUM-XMAX )*REC ) THEN
  529:                         CALL DSCAL( N2, REC, X, 1 )
  530:                         SCALE = SCALE*REC
  531:                      END IF
  532:                   END IF
  533: *
  534:                   IF( J1.GT.1 ) THEN
  535:                      CALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )
  536:                      CALL DAXPY( J1-1, -X( N+J1 ), T( 1, J1 ), 1,
  537:      $                           X( N+1 ), 1 )
  538: *
  539:                      X( 1 ) = X( 1 ) + B( J1 )*X( N+J1 )
  540:                      X( N+1 ) = X( N+1 ) - B( J1 )*X( J1 )
  541: *
  542:                      XMAX = ZERO
  543:                      DO 50 K = 1, J1 - 1
  544:                         XMAX = MAX( XMAX, ABS( X( K ) )+
  545:      $                         ABS( X( K+N ) ) )
  546:    50                CONTINUE
  547:                   END IF
  548: *
  549:                ELSE
  550: *
  551: *                 Meet 2 by 2 diagonal block
  552: *
  553:                   D( 1, 1 ) = X( J1 )
  554:                   D( 2, 1 ) = X( J2 )
  555:                   D( 1, 2 ) = X( N+J1 )
  556:                   D( 2, 2 ) = X( N+J2 )
  557:                   CALL DLALN2( .FALSE., 2, 2, SMINW, ONE, T( J1, J1 ),
  558:      $                         LDT, ONE, ONE, D, 2, ZERO, -W, V, 2,
  559:      $                         SCALOC, XNORM, IERR )
  560:                   IF( IERR.NE.0 )
  561:      $               INFO = 2
  562: *
  563:                   IF( SCALOC.NE.ONE ) THEN
  564:                      CALL DSCAL( 2*N, SCALOC, X, 1 )
  565:                      SCALE = SCALOC*SCALE
  566:                   END IF
  567:                   X( J1 ) = V( 1, 1 )
  568:                   X( J2 ) = V( 2, 1 )
  569:                   X( N+J1 ) = V( 1, 2 )
  570:                   X( N+J2 ) = V( 2, 2 )
  571: *
  572: *                 Scale X(J1), .... to avoid overflow in
  573: *                 updating right hand side.
  574: *
  575:                   XJ = MAX( ABS( V( 1, 1 ) )+ABS( V( 1, 2 ) ),
  576:      $                 ABS( V( 2, 1 ) )+ABS( V( 2, 2 ) ) )
  577:                   IF( XJ.GT.ONE ) THEN
  578:                      REC = ONE / XJ
  579:                      IF( MAX( WORK( J1 ), WORK( J2 ) ).GT.
  580:      $                   ( BIGNUM-XMAX )*REC ) THEN
  581:                         CALL DSCAL( N2, REC, X, 1 )
  582:                         SCALE = SCALE*REC
  583:                      END IF
  584:                   END IF
  585: *
  586: *                 Update the right-hand side.
  587: *
  588:                   IF( J1.GT.1 ) THEN
  589:                      CALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )
  590:                      CALL DAXPY( J1-1, -X( J2 ), T( 1, J2 ), 1, X, 1 )
  591: *
  592:                      CALL DAXPY( J1-1, -X( N+J1 ), T( 1, J1 ), 1,
  593:      $                           X( N+1 ), 1 )
  594:                      CALL DAXPY( J1-1, -X( N+J2 ), T( 1, J2 ), 1,
  595:      $                           X( N+1 ), 1 )
  596: *
  597:                      X( 1 ) = X( 1 ) + B( J1 )*X( N+J1 ) +
  598:      $                        B( J2 )*X( N+J2 )
  599:                      X( N+1 ) = X( N+1 ) - B( J1 )*X( J1 ) -
  600:      $                          B( J2 )*X( J2 )
  601: *
  602:                      XMAX = ZERO
  603:                      DO 60 K = 1, J1 - 1
  604:                         XMAX = MAX( ABS( X( K ) )+ABS( X( K+N ) ),
  605:      $                         XMAX )
  606:    60                CONTINUE
  607:                   END IF
  608: *
  609:                END IF
  610:    70       CONTINUE
  611: *
  612:          ELSE
  613: *
  614: *           Solve (T + iB)**T*(p+iq) = c+id
  615: *
  616:             JNEXT = 1
  617:             DO 80 J = 1, N
  618:                IF( J.LT.JNEXT )
  619:      $            GO TO 80
  620:                J1 = J
  621:                J2 = J
  622:                JNEXT = J + 1
  623:                IF( J.LT.N ) THEN
  624:                   IF( T( J+1, J ).NE.ZERO ) THEN
  625:                      J2 = J + 1
  626:                      JNEXT = J + 2
  627:                   END IF
  628:                END IF
  629: *
  630:                IF( J1.EQ.J2 ) THEN
  631: *
  632: *                 1 by 1 diagonal block
  633: *
  634: *                 Scale if necessary to avoid overflow in forming the
  635: *                 right-hand side element by inner product.
  636: *
  637:                   XJ = ABS( X( J1 ) ) + ABS( X( J1+N ) )
  638:                   IF( XMAX.GT.ONE ) THEN
  639:                      REC = ONE / XMAX
  640:                      IF( WORK( J1 ).GT.( BIGNUM-XJ )*REC ) THEN
  641:                         CALL DSCAL( N2, REC, X, 1 )
  642:                         SCALE = SCALE*REC
  643:                         XMAX = XMAX*REC
  644:                      END IF
  645:                   END IF
  646: *
  647:                   X( J1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X, 1 )
  648:                   X( N+J1 ) = X( N+J1 ) - DDOT( J1-1, T( 1, J1 ), 1,
  649:      $                        X( N+1 ), 1 )
  650:                   IF( J1.GT.1 ) THEN
  651:                      X( J1 ) = X( J1 ) - B( J1 )*X( N+1 )
  652:                      X( N+J1 ) = X( N+J1 ) + B( J1 )*X( 1 )
  653:                   END IF
  654:                   XJ = ABS( X( J1 ) ) + ABS( X( J1+N ) )
  655: *
  656:                   Z = W
  657:                   IF( J1.EQ.1 )
  658:      $               Z = B( 1 )
  659: *
  660: *                 Scale if necessary to avoid overflow in
  661: *                 complex division
  662: *
  663:                   TJJ = ABS( T( J1, J1 ) ) + ABS( Z )
  664:                   TMP = T( J1, J1 )
  665:                   IF( TJJ.LT.SMINW ) THEN
  666:                      TMP = SMINW
  667:                      TJJ = SMINW
  668:                      INFO = 1
  669:                   END IF
  670: *
  671:                   IF( TJJ.LT.ONE ) THEN
  672:                      IF( XJ.GT.BIGNUM*TJJ ) THEN
  673:                         REC = ONE / XJ
  674:                         CALL DSCAL( N2, REC, X, 1 )
  675:                         SCALE = SCALE*REC
  676:                         XMAX = XMAX*REC
  677:                      END IF
  678:                   END IF
  679:                   CALL DLADIV( X( J1 ), X( N+J1 ), TMP, -Z, SR, SI )
  680:                   X( J1 ) = SR
  681:                   X( J1+N ) = SI
  682:                   XMAX = MAX( ABS( X( J1 ) )+ABS( X( J1+N ) ), XMAX )
  683: *
  684:                ELSE
  685: *
  686: *                 2 by 2 diagonal block
  687: *
  688: *                 Scale if necessary to avoid overflow in forming the
  689: *                 right-hand side element by inner product.
  690: *
  691:                   XJ = MAX( ABS( X( J1 ) )+ABS( X( N+J1 ) ),
  692:      $                 ABS( X( J2 ) )+ABS( X( N+J2 ) ) )
  693:                   IF( XMAX.GT.ONE ) THEN
  694:                      REC = ONE / XMAX
  695:                      IF( MAX( WORK( J1 ), WORK( J2 ) ).GT.
  696:      $                   ( BIGNUM-XJ ) / XMAX ) THEN
  697:                         CALL DSCAL( N2, REC, X, 1 )
  698:                         SCALE = SCALE*REC
  699:                         XMAX = XMAX*REC
  700:                      END IF
  701:                   END IF
  702: *
  703:                   D( 1, 1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X,
  704:      $                        1 )
  705:                   D( 2, 1 ) = X( J2 ) - DDOT( J1-1, T( 1, J2 ), 1, X,
  706:      $                        1 )
  707:                   D( 1, 2 ) = X( N+J1 ) - DDOT( J1-1, T( 1, J1 ), 1,
  708:      $                        X( N+1 ), 1 )
  709:                   D( 2, 2 ) = X( N+J2 ) - DDOT( J1-1, T( 1, J2 ), 1,
  710:      $                        X( N+1 ), 1 )
  711:                   D( 1, 1 ) = D( 1, 1 ) - B( J1 )*X( N+1 )
  712:                   D( 2, 1 ) = D( 2, 1 ) - B( J2 )*X( N+1 )
  713:                   D( 1, 2 ) = D( 1, 2 ) + B( J1 )*X( 1 )
  714:                   D( 2, 2 ) = D( 2, 2 ) + B( J2 )*X( 1 )
  715: *
  716:                   CALL DLALN2( .TRUE., 2, 2, SMINW, ONE, T( J1, J1 ),
  717:      $                         LDT, ONE, ONE, D, 2, ZERO, W, V, 2,
  718:      $                         SCALOC, XNORM, IERR )
  719:                   IF( IERR.NE.0 )
  720:      $               INFO = 2
  721: *
  722:                   IF( SCALOC.NE.ONE ) THEN
  723:                      CALL DSCAL( N2, SCALOC, X, 1 )
  724:                      SCALE = SCALOC*SCALE
  725:                   END IF
  726:                   X( J1 ) = V( 1, 1 )
  727:                   X( J2 ) = V( 2, 1 )
  728:                   X( N+J1 ) = V( 1, 2 )
  729:                   X( N+J2 ) = V( 2, 2 )
  730:                   XMAX = MAX( ABS( X( J1 ) )+ABS( X( N+J1 ) ),
  731:      $                   ABS( X( J2 ) )+ABS( X( N+J2 ) ), XMAX )
  732: *
  733:                END IF
  734: *
  735:    80       CONTINUE
  736: *
  737:          END IF
  738: *
  739:       END IF
  740: *
  741:       RETURN
  742: *
  743: *     End of DLAQTR
  744: *
  745:       END

CVSweb interface <joel.bertrand@systella.fr>