LAPACK 3.3.0
|
00001 SUBROUTINE CPPEQU( UPLO, N, AP, S, SCOND, AMAX, INFO ) 00002 * 00003 * -- LAPACK routine (version 3.2) -- 00004 * -- LAPACK is a software package provided by Univ. of Tennessee, -- 00005 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 00006 * November 2006 00007 * 00008 * .. Scalar Arguments .. 00009 CHARACTER UPLO 00010 INTEGER INFO, N 00011 REAL AMAX, SCOND 00012 * .. 00013 * .. Array Arguments .. 00014 REAL S( * ) 00015 COMPLEX AP( * ) 00016 * .. 00017 * 00018 * Purpose 00019 * ======= 00020 * 00021 * CPPEQU computes row and column scalings intended to equilibrate a 00022 * Hermitian positive definite matrix A in packed storage and reduce 00023 * its condition number (with respect to the two-norm). S contains the 00024 * scale factors, S(i)=1/sqrt(A(i,i)), chosen so that the scaled matrix 00025 * B with elements B(i,j)=S(i)*A(i,j)*S(j) has ones on the diagonal. 00026 * This choice of S puts the condition number of B within a factor N of 00027 * the smallest possible condition number over all possible diagonal 00028 * scalings. 00029 * 00030 * Arguments 00031 * ========= 00032 * 00033 * UPLO (input) CHARACTER*1 00034 * = 'U': Upper triangle of A is stored; 00035 * = 'L': Lower triangle of A is stored. 00036 * 00037 * N (input) INTEGER 00038 * The order of the matrix A. N >= 0. 00039 * 00040 * AP (input) COMPLEX array, dimension (N*(N+1)/2) 00041 * The upper or lower triangle of the Hermitian matrix A, packed 00042 * columnwise in a linear array. The j-th column of A is stored 00043 * in the array AP as follows: 00044 * if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j; 00045 * if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n. 00046 * 00047 * S (output) REAL array, dimension (N) 00048 * If INFO = 0, S contains the scale factors for A. 00049 * 00050 * SCOND (output) REAL 00051 * If INFO = 0, S contains the ratio of the smallest S(i) to 00052 * the largest S(i). If SCOND >= 0.1 and AMAX is neither too 00053 * large nor too small, it is not worth scaling by S. 00054 * 00055 * AMAX (output) REAL 00056 * Absolute value of largest matrix element. If AMAX is very 00057 * close to overflow or very close to underflow, the matrix 00058 * should be scaled. 00059 * 00060 * INFO (output) INTEGER 00061 * = 0: successful exit 00062 * < 0: if INFO = -i, the i-th argument had an illegal value 00063 * > 0: if INFO = i, the i-th diagonal element is nonpositive. 00064 * 00065 * ===================================================================== 00066 * 00067 * .. Parameters .. 00068 REAL ONE, ZERO 00069 PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 ) 00070 * .. 00071 * .. Local Scalars .. 00072 LOGICAL UPPER 00073 INTEGER I, JJ 00074 REAL SMIN 00075 * .. 00076 * .. External Functions .. 00077 LOGICAL LSAME 00078 EXTERNAL LSAME 00079 * .. 00080 * .. External Subroutines .. 00081 EXTERNAL XERBLA 00082 * .. 00083 * .. Intrinsic Functions .. 00084 INTRINSIC MAX, MIN, REAL, SQRT 00085 * .. 00086 * .. Executable Statements .. 00087 * 00088 * Test the input parameters. 00089 * 00090 INFO = 0 00091 UPPER = LSAME( UPLO, 'U' ) 00092 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN 00093 INFO = -1 00094 ELSE IF( N.LT.0 ) THEN 00095 INFO = -2 00096 END IF 00097 IF( INFO.NE.0 ) THEN 00098 CALL XERBLA( 'CPPEQU', -INFO ) 00099 RETURN 00100 END IF 00101 * 00102 * Quick return if possible 00103 * 00104 IF( N.EQ.0 ) THEN 00105 SCOND = ONE 00106 AMAX = ZERO 00107 RETURN 00108 END IF 00109 * 00110 * Initialize SMIN and AMAX. 00111 * 00112 S( 1 ) = REAL( AP( 1 ) ) 00113 SMIN = S( 1 ) 00114 AMAX = S( 1 ) 00115 * 00116 IF( UPPER ) THEN 00117 * 00118 * UPLO = 'U': Upper triangle of A is stored. 00119 * Find the minimum and maximum diagonal elements. 00120 * 00121 JJ = 1 00122 DO 10 I = 2, N 00123 JJ = JJ + I 00124 S( I ) = REAL( AP( JJ ) ) 00125 SMIN = MIN( SMIN, S( I ) ) 00126 AMAX = MAX( AMAX, S( I ) ) 00127 10 CONTINUE 00128 * 00129 ELSE 00130 * 00131 * UPLO = 'L': Lower triangle of A is stored. 00132 * Find the minimum and maximum diagonal elements. 00133 * 00134 JJ = 1 00135 DO 20 I = 2, N 00136 JJ = JJ + N - I + 2 00137 S( I ) = REAL( AP( JJ ) ) 00138 SMIN = MIN( SMIN, S( I ) ) 00139 AMAX = MAX( AMAX, S( I ) ) 00140 20 CONTINUE 00141 END IF 00142 * 00143 IF( SMIN.LE.ZERO ) THEN 00144 * 00145 * Find the first non-positive diagonal element and return. 00146 * 00147 DO 30 I = 1, N 00148 IF( S( I ).LE.ZERO ) THEN 00149 INFO = I 00150 RETURN 00151 END IF 00152 30 CONTINUE 00153 ELSE 00154 * 00155 * Set the scale factors to the reciprocals 00156 * of the diagonal elements. 00157 * 00158 DO 40 I = 1, N 00159 S( I ) = ONE / SQRT( S( I ) ) 00160 40 CONTINUE 00161 * 00162 * Compute SCOND = min(S(I)) / max(S(I)) 00163 * 00164 SCOND = SQRT( SMIN ) / SQRT( AMAX ) 00165 END IF 00166 RETURN 00167 * 00168 * End of CPPEQU 00169 * 00170 END