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