LAPACK 3.3.0
|
00001 REAL FUNCTION SLA_SYRCOND( UPLO, N, A, LDA, AF, LDAF, IPIV, CMODE, 00002 $ C, INFO, WORK, IWORK ) 00003 * 00004 * -- LAPACK routine (version 3.2.1) -- 00005 * -- Contributed by James Demmel, Deaglan Halligan, Yozo Hida and -- 00006 * -- Jason Riedy of Univ. of California Berkeley. -- 00007 * -- April 2009 -- 00008 * 00009 * -- LAPACK is a software package provided by Univ. of Tennessee, -- 00010 * -- Univ. of California Berkeley and NAG Ltd. -- 00011 * 00012 IMPLICIT NONE 00013 * .. 00014 * .. Scalar Arguments .. 00015 CHARACTER UPLO 00016 INTEGER N, LDA, LDAF, INFO, CMODE 00017 * .. 00018 * .. Array Arguments 00019 INTEGER IWORK( * ), IPIV( * ) 00020 REAL A( LDA, * ), AF( LDAF, * ), WORK( * ), C( * ) 00021 * .. 00022 * 00023 * Purpose 00024 * ======= 00025 * 00026 * SLA_SYRCOND estimates the Skeel condition number of op(A) * op2(C) 00027 * where op2 is determined by CMODE as follows 00028 * CMODE = 1 op2(C) = C 00029 * CMODE = 0 op2(C) = I 00030 * CMODE = -1 op2(C) = inv(C) 00031 * The Skeel condition number cond(A) = norminf( |inv(A)||A| ) 00032 * is computed by computing scaling factors R such that 00033 * diag(R)*A*op2(C) is row equilibrated and computing the standard 00034 * infinity-norm condition number. 00035 * 00036 * Arguments 00037 * ========== 00038 * 00039 * UPLO (input) CHARACTER*1 00040 * = 'U': Upper triangle of A is stored; 00041 * = 'L': Lower triangle of A is stored. 00042 * 00043 * N (input) INTEGER 00044 * The number of linear equations, i.e., the order of the 00045 * matrix A. N >= 0. 00046 * 00047 * A (input) REAL array, dimension (LDA,N) 00048 * On entry, the N-by-N matrix A. 00049 * 00050 * LDA (input) INTEGER 00051 * The leading dimension of the array A. LDA >= max(1,N). 00052 * 00053 * AF (input) REAL array, dimension (LDAF,N) 00054 * The block diagonal matrix D and the multipliers used to 00055 * obtain the factor U or L as computed by SSYTRF. 00056 * 00057 * LDAF (input) INTEGER 00058 * The leading dimension of the array AF. LDAF >= max(1,N). 00059 * 00060 * IPIV (input) INTEGER array, dimension (N) 00061 * Details of the interchanges and the block structure of D 00062 * as determined by SSYTRF. 00063 * 00064 * CMODE (input) INTEGER 00065 * Determines op2(C) in the formula op(A) * op2(C) as follows: 00066 * CMODE = 1 op2(C) = C 00067 * CMODE = 0 op2(C) = I 00068 * CMODE = -1 op2(C) = inv(C) 00069 * 00070 * C (input) REAL array, dimension (N) 00071 * The vector C in the formula op(A) * op2(C). 00072 * 00073 * INFO (output) INTEGER 00074 * = 0: Successful exit. 00075 * i > 0: The ith argument is invalid. 00076 * 00077 * WORK (input) REAL array, dimension (3*N). 00078 * Workspace. 00079 * 00080 * IWORK (input) INTEGER array, dimension (N). 00081 * Workspace. 00082 * 00083 * ===================================================================== 00084 * 00085 * .. Local Scalars .. 00086 CHARACTER NORMIN 00087 INTEGER KASE, I, J 00088 REAL AINVNM, SMLNUM, TMP 00089 LOGICAL UP 00090 * .. 00091 * .. Local Arrays .. 00092 INTEGER ISAVE( 3 ) 00093 * .. 00094 * .. External Functions .. 00095 LOGICAL LSAME 00096 INTEGER ISAMAX 00097 REAL SLAMCH 00098 EXTERNAL LSAME, ISAMAX, SLAMCH 00099 * .. 00100 * .. External Subroutines .. 00101 EXTERNAL SLACN2, SLATRS, SRSCL, XERBLA, SSYTRS 00102 * .. 00103 * .. Intrinsic Functions .. 00104 INTRINSIC ABS, MAX 00105 * .. 00106 * .. Executable Statements .. 00107 * 00108 SLA_SYRCOND = 0.0 00109 * 00110 INFO = 0 00111 IF( N.LT.0 ) THEN 00112 INFO = -2 00113 END IF 00114 IF( INFO.NE.0 ) THEN 00115 CALL XERBLA( 'SLA_SYRCOND', -INFO ) 00116 RETURN 00117 END IF 00118 IF( N.EQ.0 ) THEN 00119 SLA_SYRCOND = 1.0 00120 RETURN 00121 END IF 00122 UP = .FALSE. 00123 IF ( LSAME( UPLO, 'U' ) ) UP = .TRUE. 00124 * 00125 * Compute the equilibration matrix R such that 00126 * inv(R)*A*C has unit 1-norm. 00127 * 00128 IF ( UP ) THEN 00129 DO I = 1, N 00130 TMP = 0.0 00131 IF ( CMODE .EQ. 1 ) THEN 00132 DO J = 1, I 00133 TMP = TMP + ABS( A( J, I ) * C( J ) ) 00134 END DO 00135 DO J = I+1, N 00136 TMP = TMP + ABS( A( I, J ) * C( J ) ) 00137 END DO 00138 ELSE IF ( CMODE .EQ. 0 ) THEN 00139 DO J = 1, I 00140 TMP = TMP + ABS( A( J, I ) ) 00141 END DO 00142 DO J = I+1, N 00143 TMP = TMP + ABS( A( I, J ) ) 00144 END DO 00145 ELSE 00146 DO J = 1, I 00147 TMP = TMP + ABS( A( J, I ) / C( J ) ) 00148 END DO 00149 DO J = I+1, N 00150 TMP = TMP + ABS( A( I, J ) / C( J ) ) 00151 END DO 00152 END IF 00153 WORK( 2*N+I ) = TMP 00154 END DO 00155 ELSE 00156 DO I = 1, N 00157 TMP = 0.0 00158 IF ( CMODE .EQ. 1 ) THEN 00159 DO J = 1, I 00160 TMP = TMP + ABS( A( I, J ) * C( J ) ) 00161 END DO 00162 DO J = I+1, N 00163 TMP = TMP + ABS( A( J, I ) * C( J ) ) 00164 END DO 00165 ELSE IF ( CMODE .EQ. 0 ) THEN 00166 DO J = 1, I 00167 TMP = TMP + ABS( A( I, J ) ) 00168 END DO 00169 DO J = I+1, N 00170 TMP = TMP + ABS( A( J, I ) ) 00171 END DO 00172 ELSE 00173 DO J = 1, I 00174 TMP = TMP + ABS( A( I, J) / C( J ) ) 00175 END DO 00176 DO J = I+1, N 00177 TMP = TMP + ABS( A( J, I) / C( J ) ) 00178 END DO 00179 END IF 00180 WORK( 2*N+I ) = TMP 00181 END DO 00182 ENDIF 00183 * 00184 * Estimate the norm of inv(op(A)). 00185 * 00186 SMLNUM = SLAMCH( 'Safe minimum' ) 00187 AINVNM = 0.0 00188 NORMIN = 'N' 00189 00190 KASE = 0 00191 10 CONTINUE 00192 CALL SLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE ) 00193 IF( KASE.NE.0 ) THEN 00194 IF( KASE.EQ.2 ) THEN 00195 * 00196 * Multiply by R. 00197 * 00198 DO I = 1, N 00199 WORK( I ) = WORK( I ) * WORK( 2*N+I ) 00200 END DO 00201 00202 IF ( UP ) THEN 00203 CALL SSYTRS( 'U', N, 1, AF, LDAF, IPIV, WORK, N, INFO ) 00204 ELSE 00205 CALL SSYTRS( 'L', N, 1, AF, LDAF, IPIV, WORK, N, INFO ) 00206 ENDIF 00207 * 00208 * Multiply by inv(C). 00209 * 00210 IF ( CMODE .EQ. 1 ) THEN 00211 DO I = 1, N 00212 WORK( I ) = WORK( I ) / C( I ) 00213 END DO 00214 ELSE IF ( CMODE .EQ. -1 ) THEN 00215 DO I = 1, N 00216 WORK( I ) = WORK( I ) * C( I ) 00217 END DO 00218 END IF 00219 ELSE 00220 * 00221 * Multiply by inv(C'). 00222 * 00223 IF ( CMODE .EQ. 1 ) THEN 00224 DO I = 1, N 00225 WORK( I ) = WORK( I ) / C( I ) 00226 END DO 00227 ELSE IF ( CMODE .EQ. -1 ) THEN 00228 DO I = 1, N 00229 WORK( I ) = WORK( I ) * C( I ) 00230 END DO 00231 END IF 00232 00233 IF ( UP ) THEN 00234 CALL SSYTRS( 'U', N, 1, AF, LDAF, IPIV, WORK, N, INFO ) 00235 ELSE 00236 CALL SSYTRS( 'L', N, 1, AF, LDAF, IPIV, WORK, N, INFO ) 00237 ENDIF 00238 * 00239 * Multiply by R. 00240 * 00241 DO I = 1, N 00242 WORK( I ) = WORK( I ) * WORK( 2*N+I ) 00243 END DO 00244 END IF 00245 * 00246 GO TO 10 00247 END IF 00248 * 00249 * Compute the estimate of the reciprocal condition number. 00250 * 00251 IF( AINVNM .NE. 0.0 ) 00252 $ SLA_SYRCOND = ( 1.0 / AINVNM ) 00253 * 00254 RETURN 00255 * 00256 END