File:  [local] / rpl / lapack / lapack / zlaic1.f
Revision 1.19: download - view: text, annotated - select for diffs - revision graph
Mon Aug 7 08:39:29 2023 UTC (9 months 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 ZLAIC1 applies one step of incremental condition estimation.
    2: *
    3: *  =========== DOCUMENTATION ===========
    4: *
    5: * Online html documentation available at
    6: *            http://www.netlib.org/lapack/explore-html/
    7: *
    8: *> \htmlonly
    9: *> Download ZLAIC1 + dependencies
   10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlaic1.f">
   11: *> [TGZ]</a>
   12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlaic1.f">
   13: *> [ZIP]</a>
   14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlaic1.f">
   15: *> [TXT]</a>
   16: *> \endhtmlonly
   17: *
   18: *  Definition:
   19: *  ===========
   20: *
   21: *       SUBROUTINE ZLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
   22: *
   23: *       .. Scalar Arguments ..
   24: *       INTEGER            J, JOB
   25: *       DOUBLE PRECISION   SEST, SESTPR
   26: *       COMPLEX*16         C, GAMMA, S
   27: *       ..
   28: *       .. Array Arguments ..
   29: *       COMPLEX*16         W( J ), X( J )
   30: *       ..
   31: *
   32: *
   33: *> \par Purpose:
   34: *  =============
   35: *>
   36: *> \verbatim
   37: *>
   38: *> ZLAIC1 applies one step of incremental condition estimation in
   39: *> its simplest version:
   40: *>
   41: *> Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j
   42: *> lower triangular matrix L, such that
   43: *>          twonorm(L*x) = sest
   44: *> Then ZLAIC1 computes sestpr, s, c such that
   45: *> the vector
   46: *>                 [ s*x ]
   47: *>          xhat = [  c  ]
   48: *> is an approximate singular vector of
   49: *>                 [ L       0  ]
   50: *>          Lhat = [ w**H gamma ]
   51: *> in the sense that
   52: *>          twonorm(Lhat*xhat) = sestpr.
   53: *>
   54: *> Depending on JOB, an estimate for the largest or smallest singular
   55: *> value is computed.
   56: *>
   57: *> Note that [s c]**H and sestpr**2 is an eigenpair of the system
   58: *>
   59: *>     diag(sest*sest, 0) + [alpha  gamma] * [ conjg(alpha) ]
   60: *>                                           [ conjg(gamma) ]
   61: *>
   62: *> where  alpha =  x**H * w.
   63: *> \endverbatim
   64: *
   65: *  Arguments:
   66: *  ==========
   67: *
   68: *> \param[in] JOB
   69: *> \verbatim
   70: *>          JOB is INTEGER
   71: *>          = 1: an estimate for the largest singular value is computed.
   72: *>          = 2: an estimate for the smallest singular value is computed.
   73: *> \endverbatim
   74: *>
   75: *> \param[in] J
   76: *> \verbatim
   77: *>          J is INTEGER
   78: *>          Length of X and W
   79: *> \endverbatim
   80: *>
   81: *> \param[in] X
   82: *> \verbatim
   83: *>          X is COMPLEX*16 array, dimension (J)
   84: *>          The j-vector x.
   85: *> \endverbatim
   86: *>
   87: *> \param[in] SEST
   88: *> \verbatim
   89: *>          SEST is DOUBLE PRECISION
   90: *>          Estimated singular value of j by j matrix L
   91: *> \endverbatim
   92: *>
   93: *> \param[in] W
   94: *> \verbatim
   95: *>          W is COMPLEX*16 array, dimension (J)
   96: *>          The j-vector w.
   97: *> \endverbatim
   98: *>
   99: *> \param[in] GAMMA
  100: *> \verbatim
  101: *>          GAMMA is COMPLEX*16
  102: *>          The diagonal element gamma.
  103: *> \endverbatim
  104: *>
  105: *> \param[out] SESTPR
  106: *> \verbatim
  107: *>          SESTPR is DOUBLE PRECISION
  108: *>          Estimated singular value of (j+1) by (j+1) matrix Lhat.
  109: *> \endverbatim
  110: *>
  111: *> \param[out] S
  112: *> \verbatim
  113: *>          S is COMPLEX*16
  114: *>          Sine needed in forming xhat.
  115: *> \endverbatim
  116: *>
  117: *> \param[out] C
  118: *> \verbatim
  119: *>          C is COMPLEX*16
  120: *>          Cosine needed in forming xhat.
  121: *> \endverbatim
  122: *
  123: *  Authors:
  124: *  ========
  125: *
  126: *> \author Univ. of Tennessee
  127: *> \author Univ. of California Berkeley
  128: *> \author Univ. of Colorado Denver
  129: *> \author NAG Ltd.
  130: *
  131: *> \ingroup complex16OTHERauxiliary
  132: *
  133: *  =====================================================================
  134:       SUBROUTINE ZLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
  135: *
  136: *  -- LAPACK auxiliary routine --
  137: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
  138: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  139: *
  140: *     .. Scalar Arguments ..
  141:       INTEGER            J, JOB
  142:       DOUBLE PRECISION   SEST, SESTPR
  143:       COMPLEX*16         C, GAMMA, S
  144: *     ..
  145: *     .. Array Arguments ..
  146:       COMPLEX*16         W( J ), X( J )
  147: *     ..
  148: *
  149: *  =====================================================================
  150: *
  151: *     .. Parameters ..
  152:       DOUBLE PRECISION   ZERO, ONE, TWO
  153:       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
  154:       DOUBLE PRECISION   HALF, FOUR
  155:       PARAMETER          ( HALF = 0.5D0, FOUR = 4.0D0 )
  156: *     ..
  157: *     .. Local Scalars ..
  158:       DOUBLE PRECISION   ABSALP, ABSEST, ABSGAM, B, EPS, NORMA, S1, S2,
  159:      $                   SCL, T, TEST, TMP, ZETA1, ZETA2
  160:       COMPLEX*16         ALPHA, COSINE, SINE
  161: *     ..
  162: *     .. Intrinsic Functions ..
  163:       INTRINSIC          ABS, DCONJG, MAX, SQRT
  164: *     ..
  165: *     .. External Functions ..
  166:       DOUBLE PRECISION   DLAMCH
  167:       COMPLEX*16         ZDOTC
  168:       EXTERNAL           DLAMCH, ZDOTC
  169: *     ..
  170: *     .. Executable Statements ..
  171: *
  172:       EPS = DLAMCH( 'Epsilon' )
  173:       ALPHA = ZDOTC( J, X, 1, W, 1 )
  174: *
  175:       ABSALP = ABS( ALPHA )
  176:       ABSGAM = ABS( GAMMA )
  177:       ABSEST = ABS( SEST )
  178: *
  179:       IF( JOB.EQ.1 ) THEN
  180: *
  181: *        Estimating largest singular value
  182: *
  183: *        special cases
  184: *
  185:          IF( SEST.EQ.ZERO ) THEN
  186:             S1 = MAX( ABSGAM, ABSALP )
  187:             IF( S1.EQ.ZERO ) THEN
  188:                S = ZERO
  189:                C = ONE
  190:                SESTPR = ZERO
  191:             ELSE
  192:                S = ALPHA / S1
  193:                C = GAMMA / S1
  194:                TMP = DBLE( SQRT( S*DCONJG( S )+C*DCONJG( C ) ) )
  195:                S = S / TMP
  196:                C = C / TMP
  197:                SESTPR = S1*TMP
  198:             END IF
  199:             RETURN
  200:          ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
  201:             S = ONE
  202:             C = ZERO
  203:             TMP = MAX( ABSEST, ABSALP )
  204:             S1 = ABSEST / TMP
  205:             S2 = ABSALP / TMP
  206:             SESTPR = TMP*SQRT( S1*S1+S2*S2 )
  207:             RETURN
  208:          ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
  209:             S1 = ABSGAM
  210:             S2 = ABSEST
  211:             IF( S1.LE.S2 ) THEN
  212:                S = ONE
  213:                C = ZERO
  214:                SESTPR = S2
  215:             ELSE
  216:                S = ZERO
  217:                C = ONE
  218:                SESTPR = S1
  219:             END IF
  220:             RETURN
  221:          ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
  222:             S1 = ABSGAM
  223:             S2 = ABSALP
  224:             IF( S1.LE.S2 ) THEN
  225:                TMP = S1 / S2
  226:                SCL = SQRT( ONE+TMP*TMP )
  227:                SESTPR = S2*SCL
  228:                S = ( ALPHA / S2 ) / SCL
  229:                C = ( GAMMA / S2 ) / SCL
  230:             ELSE
  231:                TMP = S2 / S1
  232:                SCL = SQRT( ONE+TMP*TMP )
  233:                SESTPR = S1*SCL
  234:                S = ( ALPHA / S1 ) / SCL
  235:                C = ( GAMMA / S1 ) / SCL
  236:             END IF
  237:             RETURN
  238:          ELSE
  239: *
  240: *           normal case
  241: *
  242:             ZETA1 = ABSALP / ABSEST
  243:             ZETA2 = ABSGAM / ABSEST
  244: *
  245:             B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF
  246:             C = ZETA1*ZETA1
  247:             IF( B.GT.ZERO ) THEN
  248:                T = DBLE( C / ( B+SQRT( B*B+C ) ) )
  249:             ELSE
  250:                T = DBLE( SQRT( B*B+C ) - B )
  251:             END IF
  252: *
  253:             SINE = -( ALPHA / ABSEST ) / T
  254:             COSINE = -( GAMMA / ABSEST ) / ( ONE+T )
  255:             TMP = DBLE( SQRT( SINE * DCONJG( SINE )
  256:      $        + COSINE * DCONJG( COSINE ) ) )
  257: 
  258:             S = SINE / TMP
  259:             C = COSINE / TMP
  260:             SESTPR = SQRT( T+ONE )*ABSEST
  261:             RETURN
  262:          END IF
  263: *
  264:       ELSE IF( JOB.EQ.2 ) THEN
  265: *
  266: *        Estimating smallest singular value
  267: *
  268: *        special cases
  269: *
  270:          IF( SEST.EQ.ZERO ) THEN
  271:             SESTPR = ZERO
  272:             IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN
  273:                SINE = ONE
  274:                COSINE = ZERO
  275:             ELSE
  276:                SINE = -DCONJG( GAMMA )
  277:                COSINE = DCONJG( ALPHA )
  278:             END IF
  279:             S1 = MAX( ABS( SINE ), ABS( COSINE ) )
  280:             S = SINE / S1
  281:             C = COSINE / S1
  282:             TMP = DBLE( SQRT( S*DCONJG( S )+C*DCONJG( C ) ) )
  283:             S = S / TMP
  284:             C = C / TMP
  285:             RETURN
  286:          ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
  287:             S = ZERO
  288:             C = ONE
  289:             SESTPR = ABSGAM
  290:             RETURN
  291:          ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
  292:             S1 = ABSGAM
  293:             S2 = ABSEST
  294:             IF( S1.LE.S2 ) THEN
  295:                S = ZERO
  296:                C = ONE
  297:                SESTPR = S1
  298:             ELSE
  299:                S = ONE
  300:                C = ZERO
  301:                SESTPR = S2
  302:             END IF
  303:             RETURN
  304:          ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
  305:             S1 = ABSGAM
  306:             S2 = ABSALP
  307:             IF( S1.LE.S2 ) THEN
  308:                TMP = S1 / S2
  309:                SCL = SQRT( ONE+TMP*TMP )
  310:                SESTPR = ABSEST*( TMP / SCL )
  311:                S = -( DCONJG( GAMMA ) / S2 ) / SCL
  312:                C = ( DCONJG( ALPHA ) / S2 ) / SCL
  313:             ELSE
  314:                TMP = S2 / S1
  315:                SCL = SQRT( ONE+TMP*TMP )
  316:                SESTPR = ABSEST / SCL
  317:                S = -( DCONJG( GAMMA ) / S1 ) / SCL
  318:                C = ( DCONJG( ALPHA ) / S1 ) / SCL
  319:             END IF
  320:             RETURN
  321:          ELSE
  322: *
  323: *           normal case
  324: *
  325:             ZETA1 = ABSALP / ABSEST
  326:             ZETA2 = ABSGAM / ABSEST
  327: *
  328:             NORMA = MAX( ONE+ZETA1*ZETA1+ZETA1*ZETA2,
  329:      $              ZETA1*ZETA2+ZETA2*ZETA2 )
  330: *
  331: *           See if root is closer to zero or to ONE
  332: *
  333:             TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 )
  334:             IF( TEST.GE.ZERO ) THEN
  335: *
  336: *              root is close to zero, compute directly
  337: *
  338:                B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF
  339:                C = ZETA2*ZETA2
  340:                T = DBLE( C / ( B+SQRT( ABS( B*B-C ) ) ) )
  341:                SINE = ( ALPHA / ABSEST ) / ( ONE-T )
  342:                COSINE = -( GAMMA / ABSEST ) / T
  343:                SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST
  344:             ELSE
  345: *
  346: *              root is closer to ONE, shift by that amount
  347: *
  348:                B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF
  349:                C = ZETA1*ZETA1
  350:                IF( B.GE.ZERO ) THEN
  351:                   T = DBLE( -C / ( B+SQRT( B*B+C ) ) )
  352:                ELSE
  353:                   T = DBLE( B - SQRT( B*B+C ) )
  354:                END IF
  355:                SINE = -( ALPHA / ABSEST ) / T
  356:                COSINE = -( GAMMA / ABSEST ) / ( ONE+T )
  357:                SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST
  358:             END IF
  359:             TMP = DBLE( SQRT( SINE * DCONJG( SINE )
  360:      $        + COSINE * DCONJG( COSINE ) ) )
  361:             S = SINE / TMP
  362:             C = COSINE / TMP
  363:             RETURN
  364: *
  365:          END IF
  366:       END IF
  367:       RETURN
  368: *
  369: *     End of ZLAIC1
  370: *
  371:       END

CVSweb interface <joel.bertrand@systella.fr>