Annotation of rpl/lapack/lapack/dlaln2.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE DLALN2( LTRANS, NA, NW, SMIN, CA, A, LDA, D1, D2, B,
! 2: $ LDB, WR, WI, X, LDX, SCALE, XNORM, INFO )
! 3: *
! 4: * -- LAPACK auxiliary routine (version 3.2) --
! 5: * -- LAPACK is a software package provided by Univ. of Tennessee, --
! 6: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! 7: * November 2006
! 8: *
! 9: * .. Scalar Arguments ..
! 10: LOGICAL LTRANS
! 11: INTEGER INFO, LDA, LDB, LDX, NA, NW
! 12: DOUBLE PRECISION CA, D1, D2, SCALE, SMIN, WI, WR, XNORM
! 13: * ..
! 14: * .. Array Arguments ..
! 15: DOUBLE PRECISION A( LDA, * ), B( LDB, * ), X( LDX, * )
! 16: * ..
! 17: *
! 18: * Purpose
! 19: * =======
! 20: *
! 21: * DLALN2 solves a system of the form (ca A - w D ) X = s B
! 22: * or (ca A' - w D) X = s B with possible scaling ("s") and
! 23: * perturbation of A. (A' means A-transpose.)
! 24: *
! 25: * A is an NA x NA real matrix, ca is a real scalar, D is an NA x NA
! 26: * real diagonal matrix, w is a real or complex value, and X and B are
! 27: * NA x 1 matrices -- real if w is real, complex if w is complex. NA
! 28: * may be 1 or 2.
! 29: *
! 30: * If w is complex, X and B are represented as NA x 2 matrices,
! 31: * the first column of each being the real part and the second
! 32: * being the imaginary part.
! 33: *
! 34: * "s" is a scaling factor (.LE. 1), computed by DLALN2, which is
! 35: * so chosen that X can be computed without overflow. X is further
! 36: * scaled if necessary to assure that norm(ca A - w D)*norm(X) is less
! 37: * than overflow.
! 38: *
! 39: * If both singular values of (ca A - w D) are less than SMIN,
! 40: * SMIN*identity will be used instead of (ca A - w D). If only one
! 41: * singular value is less than SMIN, one element of (ca A - w D) will be
! 42: * perturbed enough to make the smallest singular value roughly SMIN.
! 43: * If both singular values are at least SMIN, (ca A - w D) will not be
! 44: * perturbed. In any case, the perturbation will be at most some small
! 45: * multiple of max( SMIN, ulp*norm(ca A - w D) ). The singular values
! 46: * are computed by infinity-norm approximations, and thus will only be
! 47: * correct to a factor of 2 or so.
! 48: *
! 49: * Note: all input quantities are assumed to be smaller than overflow
! 50: * by a reasonable factor. (See BIGNUM.)
! 51: *
! 52: * Arguments
! 53: * ==========
! 54: *
! 55: * LTRANS (input) LOGICAL
! 56: * =.TRUE.: A-transpose will be used.
! 57: * =.FALSE.: A will be used (not transposed.)
! 58: *
! 59: * NA (input) INTEGER
! 60: * The size of the matrix A. It may (only) be 1 or 2.
! 61: *
! 62: * NW (input) INTEGER
! 63: * 1 if "w" is real, 2 if "w" is complex. It may only be 1
! 64: * or 2.
! 65: *
! 66: * SMIN (input) DOUBLE PRECISION
! 67: * The desired lower bound on the singular values of A. This
! 68: * should be a safe distance away from underflow or overflow,
! 69: * say, between (underflow/machine precision) and (machine
! 70: * precision * overflow ). (See BIGNUM and ULP.)
! 71: *
! 72: * CA (input) DOUBLE PRECISION
! 73: * The coefficient c, which A is multiplied by.
! 74: *
! 75: * A (input) DOUBLE PRECISION array, dimension (LDA,NA)
! 76: * The NA x NA matrix A.
! 77: *
! 78: * LDA (input) INTEGER
! 79: * The leading dimension of A. It must be at least NA.
! 80: *
! 81: * D1 (input) DOUBLE PRECISION
! 82: * The 1,1 element in the diagonal matrix D.
! 83: *
! 84: * D2 (input) DOUBLE PRECISION
! 85: * The 2,2 element in the diagonal matrix D. Not used if NW=1.
! 86: *
! 87: * B (input) DOUBLE PRECISION array, dimension (LDB,NW)
! 88: * The NA x NW matrix B (right-hand side). If NW=2 ("w" is
! 89: * complex), column 1 contains the real part of B and column 2
! 90: * contains the imaginary part.
! 91: *
! 92: * LDB (input) INTEGER
! 93: * The leading dimension of B. It must be at least NA.
! 94: *
! 95: * WR (input) DOUBLE PRECISION
! 96: * The real part of the scalar "w".
! 97: *
! 98: * WI (input) DOUBLE PRECISION
! 99: * The imaginary part of the scalar "w". Not used if NW=1.
! 100: *
! 101: * X (output) DOUBLE PRECISION array, dimension (LDX,NW)
! 102: * The NA x NW matrix X (unknowns), as computed by DLALN2.
! 103: * If NW=2 ("w" is complex), on exit, column 1 will contain
! 104: * the real part of X and column 2 will contain the imaginary
! 105: * part.
! 106: *
! 107: * LDX (input) INTEGER
! 108: * The leading dimension of X. It must be at least NA.
! 109: *
! 110: * SCALE (output) DOUBLE PRECISION
! 111: * The scale factor that B must be multiplied by to insure
! 112: * that overflow does not occur when computing X. Thus,
! 113: * (ca A - w D) X will be SCALE*B, not B (ignoring
! 114: * perturbations of A.) It will be at most 1.
! 115: *
! 116: * XNORM (output) DOUBLE PRECISION
! 117: * The infinity-norm of X, when X is regarded as an NA x NW
! 118: * real matrix.
! 119: *
! 120: * INFO (output) INTEGER
! 121: * An error flag. It will be set to zero if no error occurs,
! 122: * a negative number if an argument is in error, or a positive
! 123: * number if ca A - w D had to be perturbed.
! 124: * The possible values are:
! 125: * = 0: No error occurred, and (ca A - w D) did not have to be
! 126: * perturbed.
! 127: * = 1: (ca A - w D) had to be perturbed to make its smallest
! 128: * (or only) singular value greater than SMIN.
! 129: * NOTE: In the interests of speed, this routine does not
! 130: * check the inputs for errors.
! 131: *
! 132: * =====================================================================
! 133: *
! 134: * .. Parameters ..
! 135: DOUBLE PRECISION ZERO, ONE
! 136: PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
! 137: DOUBLE PRECISION TWO
! 138: PARAMETER ( TWO = 2.0D0 )
! 139: * ..
! 140: * .. Local Scalars ..
! 141: INTEGER ICMAX, J
! 142: DOUBLE PRECISION BBND, BI1, BI2, BIGNUM, BNORM, BR1, BR2, CI21,
! 143: $ CI22, CMAX, CNORM, CR21, CR22, CSI, CSR, LI21,
! 144: $ LR21, SMINI, SMLNUM, TEMP, U22ABS, UI11, UI11R,
! 145: $ UI12, UI12S, UI22, UR11, UR11R, UR12, UR12S,
! 146: $ UR22, XI1, XI2, XR1, XR2
! 147: * ..
! 148: * .. Local Arrays ..
! 149: LOGICAL RSWAP( 4 ), ZSWAP( 4 )
! 150: INTEGER IPIVOT( 4, 4 )
! 151: DOUBLE PRECISION CI( 2, 2 ), CIV( 4 ), CR( 2, 2 ), CRV( 4 )
! 152: * ..
! 153: * .. External Functions ..
! 154: DOUBLE PRECISION DLAMCH
! 155: EXTERNAL DLAMCH
! 156: * ..
! 157: * .. External Subroutines ..
! 158: EXTERNAL DLADIV
! 159: * ..
! 160: * .. Intrinsic Functions ..
! 161: INTRINSIC ABS, MAX
! 162: * ..
! 163: * .. Equivalences ..
! 164: EQUIVALENCE ( CI( 1, 1 ), CIV( 1 ) ),
! 165: $ ( CR( 1, 1 ), CRV( 1 ) )
! 166: * ..
! 167: * .. Data statements ..
! 168: DATA ZSWAP / .FALSE., .FALSE., .TRUE., .TRUE. /
! 169: DATA RSWAP / .FALSE., .TRUE., .FALSE., .TRUE. /
! 170: DATA IPIVOT / 1, 2, 3, 4, 2, 1, 4, 3, 3, 4, 1, 2, 4,
! 171: $ 3, 2, 1 /
! 172: * ..
! 173: * .. Executable Statements ..
! 174: *
! 175: * Compute BIGNUM
! 176: *
! 177: SMLNUM = TWO*DLAMCH( 'Safe minimum' )
! 178: BIGNUM = ONE / SMLNUM
! 179: SMINI = MAX( SMIN, SMLNUM )
! 180: *
! 181: * Don't check for input errors
! 182: *
! 183: INFO = 0
! 184: *
! 185: * Standard Initializations
! 186: *
! 187: SCALE = ONE
! 188: *
! 189: IF( NA.EQ.1 ) THEN
! 190: *
! 191: * 1 x 1 (i.e., scalar) system C X = B
! 192: *
! 193: IF( NW.EQ.1 ) THEN
! 194: *
! 195: * Real 1x1 system.
! 196: *
! 197: * C = ca A - w D
! 198: *
! 199: CSR = CA*A( 1, 1 ) - WR*D1
! 200: CNORM = ABS( CSR )
! 201: *
! 202: * If | C | < SMINI, use C = SMINI
! 203: *
! 204: IF( CNORM.LT.SMINI ) THEN
! 205: CSR = SMINI
! 206: CNORM = SMINI
! 207: INFO = 1
! 208: END IF
! 209: *
! 210: * Check scaling for X = B / C
! 211: *
! 212: BNORM = ABS( B( 1, 1 ) )
! 213: IF( CNORM.LT.ONE .AND. BNORM.GT.ONE ) THEN
! 214: IF( BNORM.GT.BIGNUM*CNORM )
! 215: $ SCALE = ONE / BNORM
! 216: END IF
! 217: *
! 218: * Compute X
! 219: *
! 220: X( 1, 1 ) = ( B( 1, 1 )*SCALE ) / CSR
! 221: XNORM = ABS( X( 1, 1 ) )
! 222: ELSE
! 223: *
! 224: * Complex 1x1 system (w is complex)
! 225: *
! 226: * C = ca A - w D
! 227: *
! 228: CSR = CA*A( 1, 1 ) - WR*D1
! 229: CSI = -WI*D1
! 230: CNORM = ABS( CSR ) + ABS( CSI )
! 231: *
! 232: * If | C | < SMINI, use C = SMINI
! 233: *
! 234: IF( CNORM.LT.SMINI ) THEN
! 235: CSR = SMINI
! 236: CSI = ZERO
! 237: CNORM = SMINI
! 238: INFO = 1
! 239: END IF
! 240: *
! 241: * Check scaling for X = B / C
! 242: *
! 243: BNORM = ABS( B( 1, 1 ) ) + ABS( B( 1, 2 ) )
! 244: IF( CNORM.LT.ONE .AND. BNORM.GT.ONE ) THEN
! 245: IF( BNORM.GT.BIGNUM*CNORM )
! 246: $ SCALE = ONE / BNORM
! 247: END IF
! 248: *
! 249: * Compute X
! 250: *
! 251: CALL DLADIV( SCALE*B( 1, 1 ), SCALE*B( 1, 2 ), CSR, CSI,
! 252: $ X( 1, 1 ), X( 1, 2 ) )
! 253: XNORM = ABS( X( 1, 1 ) ) + ABS( X( 1, 2 ) )
! 254: END IF
! 255: *
! 256: ELSE
! 257: *
! 258: * 2x2 System
! 259: *
! 260: * Compute the real part of C = ca A - w D (or ca A' - w D )
! 261: *
! 262: CR( 1, 1 ) = CA*A( 1, 1 ) - WR*D1
! 263: CR( 2, 2 ) = CA*A( 2, 2 ) - WR*D2
! 264: IF( LTRANS ) THEN
! 265: CR( 1, 2 ) = CA*A( 2, 1 )
! 266: CR( 2, 1 ) = CA*A( 1, 2 )
! 267: ELSE
! 268: CR( 2, 1 ) = CA*A( 2, 1 )
! 269: CR( 1, 2 ) = CA*A( 1, 2 )
! 270: END IF
! 271: *
! 272: IF( NW.EQ.1 ) THEN
! 273: *
! 274: * Real 2x2 system (w is real)
! 275: *
! 276: * Find the largest element in C
! 277: *
! 278: CMAX = ZERO
! 279: ICMAX = 0
! 280: *
! 281: DO 10 J = 1, 4
! 282: IF( ABS( CRV( J ) ).GT.CMAX ) THEN
! 283: CMAX = ABS( CRV( J ) )
! 284: ICMAX = J
! 285: END IF
! 286: 10 CONTINUE
! 287: *
! 288: * If norm(C) < SMINI, use SMINI*identity.
! 289: *
! 290: IF( CMAX.LT.SMINI ) THEN
! 291: BNORM = MAX( ABS( B( 1, 1 ) ), ABS( B( 2, 1 ) ) )
! 292: IF( SMINI.LT.ONE .AND. BNORM.GT.ONE ) THEN
! 293: IF( BNORM.GT.BIGNUM*SMINI )
! 294: $ SCALE = ONE / BNORM
! 295: END IF
! 296: TEMP = SCALE / SMINI
! 297: X( 1, 1 ) = TEMP*B( 1, 1 )
! 298: X( 2, 1 ) = TEMP*B( 2, 1 )
! 299: XNORM = TEMP*BNORM
! 300: INFO = 1
! 301: RETURN
! 302: END IF
! 303: *
! 304: * Gaussian elimination with complete pivoting.
! 305: *
! 306: UR11 = CRV( ICMAX )
! 307: CR21 = CRV( IPIVOT( 2, ICMAX ) )
! 308: UR12 = CRV( IPIVOT( 3, ICMAX ) )
! 309: CR22 = CRV( IPIVOT( 4, ICMAX ) )
! 310: UR11R = ONE / UR11
! 311: LR21 = UR11R*CR21
! 312: UR22 = CR22 - UR12*LR21
! 313: *
! 314: * If smaller pivot < SMINI, use SMINI
! 315: *
! 316: IF( ABS( UR22 ).LT.SMINI ) THEN
! 317: UR22 = SMINI
! 318: INFO = 1
! 319: END IF
! 320: IF( RSWAP( ICMAX ) ) THEN
! 321: BR1 = B( 2, 1 )
! 322: BR2 = B( 1, 1 )
! 323: ELSE
! 324: BR1 = B( 1, 1 )
! 325: BR2 = B( 2, 1 )
! 326: END IF
! 327: BR2 = BR2 - LR21*BR1
! 328: BBND = MAX( ABS( BR1*( UR22*UR11R ) ), ABS( BR2 ) )
! 329: IF( BBND.GT.ONE .AND. ABS( UR22 ).LT.ONE ) THEN
! 330: IF( BBND.GE.BIGNUM*ABS( UR22 ) )
! 331: $ SCALE = ONE / BBND
! 332: END IF
! 333: *
! 334: XR2 = ( BR2*SCALE ) / UR22
! 335: XR1 = ( SCALE*BR1 )*UR11R - XR2*( UR11R*UR12 )
! 336: IF( ZSWAP( ICMAX ) ) THEN
! 337: X( 1, 1 ) = XR2
! 338: X( 2, 1 ) = XR1
! 339: ELSE
! 340: X( 1, 1 ) = XR1
! 341: X( 2, 1 ) = XR2
! 342: END IF
! 343: XNORM = MAX( ABS( XR1 ), ABS( XR2 ) )
! 344: *
! 345: * Further scaling if norm(A) norm(X) > overflow
! 346: *
! 347: IF( XNORM.GT.ONE .AND. CMAX.GT.ONE ) THEN
! 348: IF( XNORM.GT.BIGNUM / CMAX ) THEN
! 349: TEMP = CMAX / BIGNUM
! 350: X( 1, 1 ) = TEMP*X( 1, 1 )
! 351: X( 2, 1 ) = TEMP*X( 2, 1 )
! 352: XNORM = TEMP*XNORM
! 353: SCALE = TEMP*SCALE
! 354: END IF
! 355: END IF
! 356: ELSE
! 357: *
! 358: * Complex 2x2 system (w is complex)
! 359: *
! 360: * Find the largest element in C
! 361: *
! 362: CI( 1, 1 ) = -WI*D1
! 363: CI( 2, 1 ) = ZERO
! 364: CI( 1, 2 ) = ZERO
! 365: CI( 2, 2 ) = -WI*D2
! 366: CMAX = ZERO
! 367: ICMAX = 0
! 368: *
! 369: DO 20 J = 1, 4
! 370: IF( ABS( CRV( J ) )+ABS( CIV( J ) ).GT.CMAX ) THEN
! 371: CMAX = ABS( CRV( J ) ) + ABS( CIV( J ) )
! 372: ICMAX = J
! 373: END IF
! 374: 20 CONTINUE
! 375: *
! 376: * If norm(C) < SMINI, use SMINI*identity.
! 377: *
! 378: IF( CMAX.LT.SMINI ) THEN
! 379: BNORM = MAX( ABS( B( 1, 1 ) )+ABS( B( 1, 2 ) ),
! 380: $ ABS( B( 2, 1 ) )+ABS( B( 2, 2 ) ) )
! 381: IF( SMINI.LT.ONE .AND. BNORM.GT.ONE ) THEN
! 382: IF( BNORM.GT.BIGNUM*SMINI )
! 383: $ SCALE = ONE / BNORM
! 384: END IF
! 385: TEMP = SCALE / SMINI
! 386: X( 1, 1 ) = TEMP*B( 1, 1 )
! 387: X( 2, 1 ) = TEMP*B( 2, 1 )
! 388: X( 1, 2 ) = TEMP*B( 1, 2 )
! 389: X( 2, 2 ) = TEMP*B( 2, 2 )
! 390: XNORM = TEMP*BNORM
! 391: INFO = 1
! 392: RETURN
! 393: END IF
! 394: *
! 395: * Gaussian elimination with complete pivoting.
! 396: *
! 397: UR11 = CRV( ICMAX )
! 398: UI11 = CIV( ICMAX )
! 399: CR21 = CRV( IPIVOT( 2, ICMAX ) )
! 400: CI21 = CIV( IPIVOT( 2, ICMAX ) )
! 401: UR12 = CRV( IPIVOT( 3, ICMAX ) )
! 402: UI12 = CIV( IPIVOT( 3, ICMAX ) )
! 403: CR22 = CRV( IPIVOT( 4, ICMAX ) )
! 404: CI22 = CIV( IPIVOT( 4, ICMAX ) )
! 405: IF( ICMAX.EQ.1 .OR. ICMAX.EQ.4 ) THEN
! 406: *
! 407: * Code when off-diagonals of pivoted C are real
! 408: *
! 409: IF( ABS( UR11 ).GT.ABS( UI11 ) ) THEN
! 410: TEMP = UI11 / UR11
! 411: UR11R = ONE / ( UR11*( ONE+TEMP**2 ) )
! 412: UI11R = -TEMP*UR11R
! 413: ELSE
! 414: TEMP = UR11 / UI11
! 415: UI11R = -ONE / ( UI11*( ONE+TEMP**2 ) )
! 416: UR11R = -TEMP*UI11R
! 417: END IF
! 418: LR21 = CR21*UR11R
! 419: LI21 = CR21*UI11R
! 420: UR12S = UR12*UR11R
! 421: UI12S = UR12*UI11R
! 422: UR22 = CR22 - UR12*LR21
! 423: UI22 = CI22 - UR12*LI21
! 424: ELSE
! 425: *
! 426: * Code when diagonals of pivoted C are real
! 427: *
! 428: UR11R = ONE / UR11
! 429: UI11R = ZERO
! 430: LR21 = CR21*UR11R
! 431: LI21 = CI21*UR11R
! 432: UR12S = UR12*UR11R
! 433: UI12S = UI12*UR11R
! 434: UR22 = CR22 - UR12*LR21 + UI12*LI21
! 435: UI22 = -UR12*LI21 - UI12*LR21
! 436: END IF
! 437: U22ABS = ABS( UR22 ) + ABS( UI22 )
! 438: *
! 439: * If smaller pivot < SMINI, use SMINI
! 440: *
! 441: IF( U22ABS.LT.SMINI ) THEN
! 442: UR22 = SMINI
! 443: UI22 = ZERO
! 444: INFO = 1
! 445: END IF
! 446: IF( RSWAP( ICMAX ) ) THEN
! 447: BR2 = B( 1, 1 )
! 448: BR1 = B( 2, 1 )
! 449: BI2 = B( 1, 2 )
! 450: BI1 = B( 2, 2 )
! 451: ELSE
! 452: BR1 = B( 1, 1 )
! 453: BR2 = B( 2, 1 )
! 454: BI1 = B( 1, 2 )
! 455: BI2 = B( 2, 2 )
! 456: END IF
! 457: BR2 = BR2 - LR21*BR1 + LI21*BI1
! 458: BI2 = BI2 - LI21*BR1 - LR21*BI1
! 459: BBND = MAX( ( ABS( BR1 )+ABS( BI1 ) )*
! 460: $ ( U22ABS*( ABS( UR11R )+ABS( UI11R ) ) ),
! 461: $ ABS( BR2 )+ABS( BI2 ) )
! 462: IF( BBND.GT.ONE .AND. U22ABS.LT.ONE ) THEN
! 463: IF( BBND.GE.BIGNUM*U22ABS ) THEN
! 464: SCALE = ONE / BBND
! 465: BR1 = SCALE*BR1
! 466: BI1 = SCALE*BI1
! 467: BR2 = SCALE*BR2
! 468: BI2 = SCALE*BI2
! 469: END IF
! 470: END IF
! 471: *
! 472: CALL DLADIV( BR2, BI2, UR22, UI22, XR2, XI2 )
! 473: XR1 = UR11R*BR1 - UI11R*BI1 - UR12S*XR2 + UI12S*XI2
! 474: XI1 = UI11R*BR1 + UR11R*BI1 - UI12S*XR2 - UR12S*XI2
! 475: IF( ZSWAP( ICMAX ) ) THEN
! 476: X( 1, 1 ) = XR2
! 477: X( 2, 1 ) = XR1
! 478: X( 1, 2 ) = XI2
! 479: X( 2, 2 ) = XI1
! 480: ELSE
! 481: X( 1, 1 ) = XR1
! 482: X( 2, 1 ) = XR2
! 483: X( 1, 2 ) = XI1
! 484: X( 2, 2 ) = XI2
! 485: END IF
! 486: XNORM = MAX( ABS( XR1 )+ABS( XI1 ), ABS( XR2 )+ABS( XI2 ) )
! 487: *
! 488: * Further scaling if norm(A) norm(X) > overflow
! 489: *
! 490: IF( XNORM.GT.ONE .AND. CMAX.GT.ONE ) THEN
! 491: IF( XNORM.GT.BIGNUM / CMAX ) THEN
! 492: TEMP = CMAX / BIGNUM
! 493: X( 1, 1 ) = TEMP*X( 1, 1 )
! 494: X( 2, 1 ) = TEMP*X( 2, 1 )
! 495: X( 1, 2 ) = TEMP*X( 1, 2 )
! 496: X( 2, 2 ) = TEMP*X( 2, 2 )
! 497: XNORM = TEMP*XNORM
! 498: SCALE = TEMP*SCALE
! 499: END IF
! 500: END IF
! 501: END IF
! 502: END IF
! 503: *
! 504: RETURN
! 505: *
! 506: * End of DLALN2
! 507: *
! 508: END
CVSweb interface <joel.bertrand@systella.fr>