LAPACK 3.3.0

# cheequb.f

Go to the documentation of this file.
```00001       SUBROUTINE CHEEQUB( UPLO, N, A, LDA, S, SCOND, AMAX, WORK, INFO )
00002 *
00003 *     -- LAPACK routine (version 3.2.2)                                 --
00004 *     -- Contributed by James Demmel, Deaglan Halligan, Yozo Hida and --
00005 *     -- Jason Riedy of Univ. of California Berkeley.                 --
00006 *     -- June 2010                                                    --
00007 *
00008 *     -- LAPACK is a software package provided by Univ. of Tennessee, --
00009 *     -- Univ. of California Berkeley and NAG Ltd.                    --
00010 *
00011       IMPLICIT NONE
00012 *     ..
00013 *     .. Scalar Arguments ..
00014       INTEGER            INFO, LDA, N
00015       REAL               AMAX, SCOND
00016       CHARACTER          UPLO
00017 *     ..
00018 *     .. Array Arguments ..
00019       COMPLEX            A( LDA, * ), WORK( * )
00020       REAL               S( * )
00021 *     ..
00022 *
00023 *  Purpose
00024 *  =======
00025 *
00026 *  CSYEQUB computes row and column scalings intended to equilibrate a
00027 *  symmetric matrix A and reduce its condition number
00028 *  (with respect to the two-norm).  S contains the scale factors,
00029 *  S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
00030 *  elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
00031 *  choice of S puts the condition number of B within a factor N of the
00032 *  smallest possible condition number over all possible diagonal
00033 *  scalings.
00034 *
00035 *  Arguments
00036 *  =========
00037 *
00038 *  N       (input) INTEGER
00039 *          The order of the matrix A.  N >= 0.
00040 *
00041 *  A       (input) COMPLEX array, dimension (LDA,N)
00042 *          The N-by-N symmetric matrix whose scaling
00043 *          factors are to be computed.  Only the diagonal elements of A
00044 *          are referenced.
00045 *
00046 *  LDA     (input) INTEGER
00047 *          The leading dimension of the array A.  LDA >= max(1,N).
00048 *
00049 *  S       (output) REAL array, dimension (N)
00050 *          If INFO = 0, S contains the scale factors for A.
00051 *
00052 *  SCOND   (output) REAL
00053 *          If INFO = 0, S contains the ratio of the smallest S(i) to
00054 *          the largest S(i).  If SCOND >= 0.1 and AMAX is neither too
00055 *          large nor too small, it is not worth scaling by S.
00056 *
00057 *  AMAX    (output) REAL
00058 *          Absolute value of largest matrix element.  If AMAX is very
00059 *          close to overflow or very close to underflow, the matrix
00060 *          should be scaled.
00061 *  INFO    (output) INTEGER
00062 *          = 0:  successful exit
00063 *          < 0:  if INFO = -i, the i-th argument had an illegal value
00064 *          > 0:  if INFO = i, the i-th diagonal element is nonpositive.
00065 *
00066 *  =====================================================================
00067 *
00068 *     .. Parameters ..
00069       REAL               ONE, ZERO
00070       PARAMETER          ( ONE = 1.0E+0, ZERO = 0.0E+0 )
00071       INTEGER            MAX_ITER
00072       PARAMETER          ( MAX_ITER = 100 )
00073 *     ..
00074 *     .. Local Scalars ..
00075       INTEGER            I, J, ITER
00076       REAL               AVG, STD, TOL, C0, C1, C2, T, U, SI, D,
00077      \$                   BASE, SMIN, SMAX, SMLNUM, BIGNUM, SCALE, SUMSQ
00078       LOGICAL            UP
00079       COMPLEX            ZDUM
00080 *     ..
00081 *     .. External Functions ..
00082       REAL               SLAMCH
00083       LOGICAL            LSAME
00084       EXTERNAL           LSAME, SLAMCH
00085 *     ..
00086 *     .. External Subroutines ..
00087       EXTERNAL           CLASSQ
00088 *     ..
00089 *     .. Intrinsic Functions ..
00090       INTRINSIC          ABS, AIMAG, INT, LOG, MAX, MIN, REAL, SQRT
00091 *     ..
00092 *     .. Statement Functions ..
00093       REAL               CABS1
00094 *     ..
00095 *     .. Statement Function Definitions ..
00096       CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
00097 *
00098 *     Test input parameters.
00099 *
00100       INFO = 0
00101       IF (.NOT. ( LSAME( UPLO, 'U' ) .OR. LSAME( UPLO, 'L' ) ) ) THEN
00102         INFO = -1
00103       ELSE IF ( N .LT. 0 ) THEN
00104         INFO = -2
00105       ELSE IF ( LDA .LT. MAX( 1, N ) ) THEN
00106         INFO = -4
00107       END IF
00108       IF ( INFO .NE. 0 ) THEN
00109         CALL XERBLA( 'CHEEQUB', -INFO )
00110         RETURN
00111       END IF
00112
00113       UP = LSAME( UPLO, 'U' )
00114       AMAX = ZERO
00115 *
00116 *     Quick return if possible.
00117 *
00118       IF ( N .EQ. 0 ) THEN
00119         SCOND = ONE
00120         RETURN
00121       END IF
00122
00123       DO I = 1, N
00124         S( I ) = ZERO
00125       END DO
00126
00127       AMAX = ZERO
00128       IF ( UP ) THEN
00129          DO J = 1, N
00130             DO I = 1, J-1
00131                S( I ) = MAX( S( I ), CABS1( A( I, J ) ) )
00132                S( J ) = MAX( S( J ), CABS1( A( I, J ) ) )
00133                AMAX = MAX( AMAX, CABS1( A( I, J ) ) )
00134             END DO
00135             S( J ) = MAX( S( J ), CABS1( A( J, J ) ) )
00136             AMAX = MAX( AMAX, CABS1( A( J, J ) ) )
00137          END DO
00138       ELSE
00139          DO J = 1, N
00140             S( J ) = MAX( S( J ), CABS1( A( J, J ) ) )
00141             AMAX = MAX( AMAX, CABS1( A( J, J ) ) )
00142             DO I = J+1, N
00143                S( I ) = MAX( S( I ), CABS1( A( I, J ) ) )
00144                S( J ) = MAX( S( J ), CABS1( A( I, J ) ) )
00145                AMAX = MAX( AMAX, CABS1( A(I, J ) ) )
00146             END DO
00147          END DO
00148       END IF
00149       DO J = 1, N
00150          S( J ) = 1.0 / S( J )
00151       END DO
00152
00153       TOL = ONE / SQRT( 2.0E0 * N )
00154
00155       DO ITER = 1, MAX_ITER
00156          SCALE = 0.0
00157          SUMSQ = 0.0
00158 *       beta = |A|s
00159         DO I = 1, N
00160            WORK( I ) = ZERO
00161         END DO
00162         IF ( UP ) THEN
00163            DO J = 1, N
00164               DO I = 1, J-1
00165                  T = CABS1( A( I, J ) )
00166                  WORK( I ) = WORK( I ) + CABS1( A( I, J ) ) * S( J )
00167                  WORK( J ) = WORK( J ) + CABS1( A( I, J ) ) * S( I )
00168               END DO
00169               WORK( J ) = WORK( J ) + CABS1( A( J, J ) ) * S( J )
00170            END DO
00171         ELSE
00172            DO J = 1, N
00173               WORK( J ) = WORK( J ) + CABS1( A( J, J ) ) * S( J )
00174               DO I = J+1, N
00175                  T = CABS1( A( I, J ) )
00176                  WORK( I ) = WORK( I ) + CABS1( A( I, J ) ) * S( J )
00177                  WORK( J ) = WORK( J ) + CABS1( A( I, J ) ) * S( I )
00178               END DO
00179            END DO
00180         END IF
00181
00182 *       avg = s^T beta / n
00183         AVG = 0.0
00184         DO I = 1, N
00185           AVG = AVG + S( I )*WORK( I )
00186         END DO
00187         AVG = AVG / N
00188
00189         STD = 0.0
00190         DO I = 2*N+1, 3*N
00191            WORK( I ) = S( I-2*N ) * WORK( I-2*N ) - AVG
00192         END DO
00193         CALL CLASSQ( N, WORK( 2*N+1 ), 1, SCALE, SUMSQ )
00194         STD = SCALE * SQRT( SUMSQ / N )
00195
00196         IF ( STD .LT. TOL * AVG ) GOTO 999
00197
00198         DO I = 1, N
00199           T = CABS1( A( I, I ) )
00200           SI = S( I )
00201           C2 = ( N-1 ) * T
00202           C1 = ( N-2 ) * ( WORK( I ) - T*SI )
00203           C0 = -(T*SI)*SI + 2*WORK( I )*SI - N*AVG
00204
00205           D = C1*C1 - 4*C0*C2
00206           IF ( D .LE. 0 ) THEN
00207             INFO = -1
00208             RETURN
00209           END IF
00210           SI = -2*C0 / ( C1 + SQRT( D ) )
00211
00212           D = SI - S(I)
00213           U = ZERO
00214           IF ( UP ) THEN
00215             DO J = 1, I
00216               T = CABS1( A( J, I ) )
00217               U = U + S( J )*T
00218               WORK( J ) = WORK( J ) + D*T
00219             END DO
00220             DO J = I+1,N
00221               T = CABS1( A( I, J ) )
00222               U = U + S( J )*T
00223               WORK( J ) = WORK( J ) + D*T
00224             END DO
00225           ELSE
00226             DO J = 1, I
00227               T = CABS1( A( I, J ) )
00228               U = U + S( J )*T
00229               WORK( J ) = WORK( J ) + D*T
00230             END DO
00231             DO J = I+1,N
00232               T = CABS1( A( J, I ) )
00233               U = U + S( J )*T
00234               WORK( J ) = WORK( J ) + D*T
00235             END DO
00236           END IF
00237           AVG = AVG + ( U + WORK( I ) ) * D / N
00238           S( I ) = SI
00239         END DO
00240
00241       END DO
00242
00243  999  CONTINUE
00244
00245       SMLNUM = SLAMCH( 'SAFEMIN' )
00246       BIGNUM = ONE / SMLNUM
00247       SMIN = BIGNUM
00248       SMAX = ZERO
00249       T = ONE / SQRT( AVG )
00250       BASE = SLAMCH( 'B' )
00251       U = ONE / LOG( BASE )
00252       DO I = 1, N
00253         S( I ) = BASE ** INT( U * LOG( S( I ) * T ) )
00254         SMIN = MIN( SMIN, S( I ) )
00255         SMAX = MAX( SMAX, S( I ) )
00256       END DO
00257       SCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM )
00258
00259       END
```