File:  [local] / rpl / lapack / lapack / zsyequb.f
Revision 1.4: download - view: text, annotated - select for diffs - revision graph
Tue Dec 21 13:53:55 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 ZSYEQUB( UPLO, N, A, LDA, S, SCOND, AMAX, WORK, INFO )
    2: *
    3: *     -- LAPACK routine (version 3.2.2)                                 --
    4: *     -- Contributed by James Demmel, Deaglan Halligan, Yozo Hida and --
    5: *     -- Jason Riedy of Univ. of California Berkeley.                 --
    6: *     -- June 2010                                                    --
    7: *
    8: *     -- LAPACK is a software package provided by Univ. of Tennessee, --
    9: *     -- Univ. of California Berkeley and NAG Ltd.                    --
   10: *
   11:       IMPLICIT NONE
   12: *     ..
   13: *     .. Scalar Arguments ..
   14:       INTEGER            INFO, LDA, N
   15:       DOUBLE PRECISION   AMAX, SCOND
   16:       CHARACTER          UPLO
   17: *     ..
   18: *     .. Array Arguments ..
   19:       COMPLEX*16         A( LDA, * ), WORK( * )
   20:       DOUBLE PRECISION   S( * )
   21: *     ..
   22: *
   23: *  Purpose
   24: *  =======
   25: *
   26: *  ZSYEQUB computes row and column scalings intended to equilibrate a
   27: *  symmetric matrix A and reduce its condition number
   28: *  (with respect to the two-norm).  S contains the scale factors,
   29: *  S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
   30: *  elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
   31: *  choice of S puts the condition number of B within a factor N of the
   32: *  smallest possible condition number over all possible diagonal
   33: *  scalings.
   34: *
   35: *  Arguments
   36: *  =========
   37: *
   38: *  UPLO    (input) CHARACTER*1
   39: *          Specifies whether the details of the factorization are stored
   40: *          as an upper or lower triangular matrix.
   41: *          = 'U':  Upper triangular, form is A = U*D*U**T;
   42: *          = 'L':  Lower triangular, form is A = L*D*L**T.
   43: *
   44: *  N       (input) INTEGER
   45: *          The order of the matrix A.  N >= 0.
   46: *
   47: *  A       (input) COMPLEX*16 array, dimension (LDA,N)
   48: *          The N-by-N symmetric matrix whose scaling
   49: *          factors are to be computed.  Only the diagonal elements of A
   50: *          are referenced.
   51: *
   52: *  LDA     (input) INTEGER
   53: *          The leading dimension of the array A.  LDA >= max(1,N).
   54: *
   55: *  S       (output) DOUBLE PRECISION array, dimension (N)
   56: *          If INFO = 0, S contains the scale factors for A.
   57: *
   58: *  SCOND   (output) DOUBLE PRECISION
   59: *          If INFO = 0, S contains the ratio of the smallest S(i) to
   60: *          the largest S(i).  If SCOND >= 0.1 and AMAX is neither too
   61: *          large nor too small, it is not worth scaling by S.
   62: *
   63: *  AMAX    (output) DOUBLE PRECISION
   64: *          Absolute value of largest matrix element.  If AMAX is very
   65: *          close to overflow or very close to underflow, the matrix
   66: *          should be scaled.
   67: *
   68: *  WORK    (workspace) COMPLEX*16 array, dimension (3*N)
   69: *
   70: *  INFO    (output) INTEGER
   71: *          = 0:  successful exit
   72: *          < 0:  if INFO = -i, the i-th argument had an illegal value
   73: *          > 0:  if INFO = i, the i-th diagonal element is nonpositive.
   74: *
   75: *  Further Details
   76: *  ======= =======
   77: *
   78: *  Reference: Livne, O.E. and Golub, G.H., "Scaling by Binormalization",
   79: *  Numerical Algorithms, vol. 35, no. 1, pp. 97-120, January 2004.
   80: *  DOI 10.1023/B:NUMA.0000016606.32820.69
   81: *  Tech report version: http://ruready.utah.edu/archive/papers/bin.pdf
   82: *
   83: *  =====================================================================
   84: *
   85: *     .. Parameters ..
   86:       DOUBLE PRECISION   ONE, ZERO
   87:       PARAMETER          ( ONE = 1.0D0, ZERO = 0.0D0 )
   88:       INTEGER            MAX_ITER
   89:       PARAMETER          ( MAX_ITER = 100 )
   90: *     ..
   91: *     .. Local Scalars ..
   92:       INTEGER            I, J, ITER
   93:       DOUBLE PRECISION   AVG, STD, TOL, C0, C1, C2, T, U, SI, D, BASE,
   94:      $                   SMIN, SMAX, SMLNUM, BIGNUM, SCALE, SUMSQ
   95:       LOGICAL            UP
   96:       COMPLEX*16         ZDUM
   97: *     ..
   98: *     .. External Functions ..
   99:       DOUBLE PRECISION   DLAMCH
  100:       LOGICAL            LSAME
  101:       EXTERNAL           DLAMCH, LSAME
  102: *     ..
  103: *     .. External Subroutines ..
  104:       EXTERNAL           ZLASSQ
  105: *     ..
  106: *     .. Intrinsic Functions ..
  107:       INTRINSIC          ABS, DBLE, DIMAG, INT, LOG, MAX, MIN, SQRT
  108: *     ..
  109: *     .. Statement Functions ..
  110:       DOUBLE PRECISION   CABS1
  111: *     ..
  112: *     Statement Function Definitions
  113:       CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
  114: *     ..
  115: *     .. Executable Statements ..
  116: *
  117: *     Test the input parameters.
  118: *
  119:       INFO = 0
  120:       IF ( .NOT. ( LSAME( UPLO, 'U' ) .OR. LSAME( UPLO, 'L' ) ) ) THEN
  121:         INFO = -1
  122:       ELSE IF ( N .LT. 0 ) THEN
  123:         INFO = -2
  124:       ELSE IF ( LDA .LT. MAX( 1, N ) ) THEN
  125:         INFO = -4
  126:       END IF
  127:       IF ( INFO .NE. 0 ) THEN
  128:         CALL XERBLA( 'ZSYEQUB', -INFO )
  129:         RETURN
  130:       END IF
  131: 
  132:       UP = LSAME( UPLO, 'U' )
  133:       AMAX = ZERO
  134: *
  135: *     Quick return if possible.
  136: *
  137:       IF ( N .EQ. 0 ) THEN
  138:         SCOND = ONE
  139:         RETURN
  140:       END IF
  141: 
  142:       DO I = 1, N
  143:         S( I ) = ZERO
  144:       END DO
  145: 
  146:       AMAX = ZERO
  147:       IF ( UP ) THEN
  148:          DO J = 1, N
  149:             DO I = 1, J-1
  150:                S( I ) = MAX( S( I ), CABS1( A( I, J ) ) )
  151:                S( J ) = MAX( S( J ), CABS1( A( I, J ) ) )
  152:                AMAX = MAX( AMAX, CABS1( A( I, J ) ) )
  153:             END DO
  154:             S( J ) = MAX( S( J ), CABS1( A( J, J) ) )
  155:             AMAX = MAX( AMAX, CABS1( A( J, J ) ) )
  156:          END DO
  157:       ELSE
  158:          DO J = 1, N
  159:             S( J ) = MAX( S( J ), CABS1( A( J, J ) ) )
  160:             AMAX = MAX( AMAX, CABS1( A( J, J ) ) )
  161:             DO I = J+1, N
  162:                S( I ) = MAX( S( I ), CABS1( A( I, J ) ) )
  163:                S( J ) = MAX( S( J ), CABS1 (A( I, J ) ) )
  164:                AMAX = MAX( AMAX, CABS1( A( I, J ) ) )
  165:             END DO
  166:          END DO
  167:       END IF
  168:       DO J = 1, N
  169:          S( J ) = 1.0D+0 / S( J )
  170:       END DO
  171: 
  172:       TOL = ONE / SQRT( 2.0D0 * N )
  173: 
  174:       DO ITER = 1, MAX_ITER
  175:          SCALE = 0.0D+0
  176:          SUMSQ = 0.0D+0
  177: *       beta = |A|s
  178:         DO I = 1, N
  179:            WORK( I ) = ZERO
  180:         END DO
  181:         IF ( UP ) THEN
  182:            DO J = 1, N
  183:               DO I = 1, J-1
  184:                  T = CABS1( A( I, J ) )
  185:                  WORK( I ) = WORK( I ) + CABS1( A( I, J ) ) * S( J )
  186:                  WORK( J ) = WORK( J ) + CABS1( A( I, J ) ) * S( I )
  187:               END DO
  188:               WORK( J ) = WORK( J ) + CABS1( A( J, J ) ) * S( J )
  189:            END DO
  190:         ELSE
  191:            DO J = 1, N
  192:               WORK( J ) = WORK( J ) + CABS1( A( J, J ) ) * S( J )
  193:               DO I = J+1, N
  194:                  T = CABS1( A( I, J ) )
  195:                  WORK( I ) = WORK( I ) + CABS1( A( I, J ) ) * S( J )
  196:                  WORK( J ) = WORK( J ) + CABS1( A( I, J ) ) * S( I )
  197:               END DO
  198:            END DO
  199:         END IF
  200: 
  201: *       avg = s^T beta / n
  202:         AVG = 0.0D+0
  203:         DO I = 1, N
  204:           AVG = AVG + S( I )*WORK( I )
  205:         END DO
  206:         AVG = AVG / N
  207: 
  208:         STD = 0.0D+0
  209:         DO I = N+1, 2*N
  210:            WORK( I ) = S( I-N ) * WORK( I-N ) - AVG
  211:         END DO
  212:         CALL ZLASSQ( N, WORK( N+1 ), 1, SCALE, SUMSQ )
  213:         STD = SCALE * SQRT( SUMSQ / N )
  214: 
  215:         IF ( STD .LT. TOL * AVG ) GOTO 999
  216: 
  217:         DO I = 1, N
  218:           T = CABS1( A( I, I ) )
  219:           SI = S( I )
  220:           C2 = ( N-1 ) * T
  221:           C1 = ( N-2 ) * ( WORK( I ) - T*SI )
  222:           C0 = -(T*SI)*SI + 2*WORK( I )*SI - N*AVG
  223:           D = C1*C1 - 4*C0*C2
  224: 
  225:           IF ( D .LE. 0 ) THEN
  226:             INFO = -1
  227:             RETURN
  228:           END IF
  229:           SI = -2*C0 / ( C1 + SQRT( D ) )
  230: 
  231:           D = SI - S( I )
  232:           U = ZERO
  233:           IF ( UP ) THEN
  234:             DO J = 1, I
  235:               T = CABS1( A( J, I ) )
  236:               U = U + S( J )*T
  237:               WORK( J ) = WORK( J ) + D*T
  238:             END DO
  239:             DO J = I+1,N
  240:               T = CABS1( A( I, J ) )
  241:               U = U + S( J )*T
  242:               WORK( J ) = WORK( J ) + D*T
  243:             END DO
  244:           ELSE
  245:             DO J = 1, I
  246:               T = CABS1( A( I, J ) )
  247:               U = U + S( J )*T
  248:               WORK( J ) = WORK( J ) + D*T
  249:             END DO
  250:             DO J = I+1,N
  251:               T = CABS1( A( J, I ) )
  252:               U = U + S( J )*T
  253:               WORK( J ) = WORK( J ) + D*T
  254:             END DO
  255:           END IF
  256:           AVG = AVG + ( U + WORK( I ) ) * D / N
  257:           S( I ) = SI
  258:         END DO
  259:       END DO
  260: 
  261:  999  CONTINUE
  262: 
  263:       SMLNUM = DLAMCH( 'SAFEMIN' )
  264:       BIGNUM = ONE / SMLNUM
  265:       SMIN = BIGNUM
  266:       SMAX = ZERO
  267:       T = ONE / SQRT( AVG )
  268:       BASE = DLAMCH( 'B' )
  269:       U = ONE / LOG( BASE )
  270:       DO I = 1, N
  271:         S( I ) = BASE ** INT( U * LOG( S( I ) * T ) )
  272:         SMIN = MIN( SMIN, S( I ) )
  273:         SMAX = MAX( SMAX, S( I ) )
  274:       END DO
  275:       SCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM )
  276: *
  277:       END

CVSweb interface <joel.bertrand@systella.fr>