LAPACK 3.3.0
|
00001 SUBROUTINE SPOCON( UPLO, N, A, LDA, ANORM, RCOND, WORK, IWORK, 00002 $ INFO ) 00003 * 00004 * -- LAPACK routine (version 3.2) -- 00005 * -- LAPACK is a software package provided by Univ. of Tennessee, -- 00006 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 00007 * November 2006 00008 * 00009 * Modified to call SLACN2 in place of SLACON, 7 Feb 03, SJH. 00010 * 00011 * .. Scalar Arguments .. 00012 CHARACTER UPLO 00013 INTEGER INFO, LDA, N 00014 REAL ANORM, RCOND 00015 * .. 00016 * .. Array Arguments .. 00017 INTEGER IWORK( * ) 00018 REAL A( LDA, * ), WORK( * ) 00019 * .. 00020 * 00021 * Purpose 00022 * ======= 00023 * 00024 * SPOCON estimates the reciprocal of the condition number (in the 00025 * 1-norm) of a real symmetric positive definite matrix using the 00026 * Cholesky factorization A = U**T*U or A = L*L**T computed by SPOTRF. 00027 * 00028 * An estimate is obtained for norm(inv(A)), and the reciprocal of the 00029 * condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). 00030 * 00031 * Arguments 00032 * ========= 00033 * 00034 * UPLO (input) CHARACTER*1 00035 * = 'U': Upper triangle of A is stored; 00036 * = 'L': Lower triangle of A is stored. 00037 * 00038 * N (input) INTEGER 00039 * The order of the matrix A. N >= 0. 00040 * 00041 * A (input) REAL array, dimension (LDA,N) 00042 * The triangular factor U or L from the Cholesky factorization 00043 * A = U**T*U or A = L*L**T, as computed by SPOTRF. 00044 * 00045 * LDA (input) INTEGER 00046 * The leading dimension of the array A. LDA >= max(1,N). 00047 * 00048 * ANORM (input) REAL 00049 * The 1-norm (or infinity-norm) of the symmetric matrix A. 00050 * 00051 * RCOND (output) REAL 00052 * The reciprocal of the condition number of the matrix A, 00053 * computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an 00054 * estimate of the 1-norm of inv(A) computed in this routine. 00055 * 00056 * WORK (workspace) REAL array, dimension (3*N) 00057 * 00058 * IWORK (workspace) INTEGER array, dimension (N) 00059 * 00060 * INFO (output) INTEGER 00061 * = 0: successful exit 00062 * < 0: if INFO = -i, the i-th argument had an illegal value 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 CHARACTER NORMIN 00073 INTEGER IX, KASE 00074 REAL AINVNM, SCALE, SCALEL, SCALEU, SMLNUM 00075 * .. 00076 * .. Local Arrays .. 00077 INTEGER ISAVE( 3 ) 00078 * .. 00079 * .. External Functions .. 00080 LOGICAL LSAME 00081 INTEGER ISAMAX 00082 REAL SLAMCH 00083 EXTERNAL LSAME, ISAMAX, SLAMCH 00084 * .. 00085 * .. External Subroutines .. 00086 EXTERNAL SLACN2, SLATRS, SRSCL, XERBLA 00087 * .. 00088 * .. Intrinsic Functions .. 00089 INTRINSIC ABS, MAX 00090 * .. 00091 * .. Executable Statements .. 00092 * 00093 * Test the input parameters. 00094 * 00095 INFO = 0 00096 UPPER = LSAME( UPLO, 'U' ) 00097 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN 00098 INFO = -1 00099 ELSE IF( N.LT.0 ) THEN 00100 INFO = -2 00101 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN 00102 INFO = -4 00103 ELSE IF( ANORM.LT.ZERO ) THEN 00104 INFO = -5 00105 END IF 00106 IF( INFO.NE.0 ) THEN 00107 CALL XERBLA( 'SPOCON', -INFO ) 00108 RETURN 00109 END IF 00110 * 00111 * Quick return if possible 00112 * 00113 RCOND = ZERO 00114 IF( N.EQ.0 ) THEN 00115 RCOND = ONE 00116 RETURN 00117 ELSE IF( ANORM.EQ.ZERO ) THEN 00118 RETURN 00119 END IF 00120 * 00121 SMLNUM = SLAMCH( 'Safe minimum' ) 00122 * 00123 * Estimate the 1-norm of inv(A). 00124 * 00125 KASE = 0 00126 NORMIN = 'N' 00127 10 CONTINUE 00128 CALL SLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE ) 00129 IF( KASE.NE.0 ) THEN 00130 IF( UPPER ) THEN 00131 * 00132 * Multiply by inv(U'). 00133 * 00134 CALL SLATRS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N, A, 00135 $ LDA, WORK, SCALEL, WORK( 2*N+1 ), INFO ) 00136 NORMIN = 'Y' 00137 * 00138 * Multiply by inv(U). 00139 * 00140 CALL SLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N, 00141 $ A, LDA, WORK, SCALEU, WORK( 2*N+1 ), INFO ) 00142 ELSE 00143 * 00144 * Multiply by inv(L). 00145 * 00146 CALL SLATRS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N, 00147 $ A, LDA, WORK, SCALEL, WORK( 2*N+1 ), INFO ) 00148 NORMIN = 'Y' 00149 * 00150 * Multiply by inv(L'). 00151 * 00152 CALL SLATRS( 'Lower', 'Transpose', 'Non-unit', NORMIN, N, A, 00153 $ LDA, WORK, SCALEU, WORK( 2*N+1 ), INFO ) 00154 END IF 00155 * 00156 * Multiply by 1/SCALE if doing so will not cause overflow. 00157 * 00158 SCALE = SCALEL*SCALEU 00159 IF( SCALE.NE.ONE ) THEN 00160 IX = ISAMAX( N, WORK, 1 ) 00161 IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO ) 00162 $ GO TO 20 00163 CALL SRSCL( N, SCALE, WORK, 1 ) 00164 END IF 00165 GO TO 10 00166 END IF 00167 * 00168 * Compute the estimate of the reciprocal condition number. 00169 * 00170 IF( AINVNM.NE.ZERO ) 00171 $ RCOND = ( ONE / AINVNM ) / ANORM 00172 * 00173 20 CONTINUE 00174 RETURN 00175 * 00176 * End of SPOCON 00177 * 00178 END