LAPACK 3.3.0
|
00001 SUBROUTINE ZGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK, 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 ZLACN2 in place of ZLACON, 10 Feb 03, SJH. 00010 * 00011 * .. Scalar Arguments .. 00012 CHARACTER NORM 00013 INTEGER INFO, LDA, N 00014 DOUBLE PRECISION ANORM, RCOND 00015 * .. 00016 * .. Array Arguments .. 00017 DOUBLE PRECISION RWORK( * ) 00018 COMPLEX*16 A( LDA, * ), WORK( * ) 00019 * .. 00020 * 00021 * Purpose 00022 * ======= 00023 * 00024 * ZGECON estimates the reciprocal of the condition number of a general 00025 * complex matrix A, in either the 1-norm or the infinity-norm, using 00026 * the LU factorization computed by ZGETRF. 00027 * 00028 * An estimate is obtained for norm(inv(A)), and the reciprocal of the 00029 * condition number is computed as 00030 * RCOND = 1 / ( norm(A) * norm(inv(A)) ). 00031 * 00032 * Arguments 00033 * ========= 00034 * 00035 * NORM (input) CHARACTER*1 00036 * Specifies whether the 1-norm condition number or the 00037 * infinity-norm condition number is required: 00038 * = '1' or 'O': 1-norm; 00039 * = 'I': Infinity-norm. 00040 * 00041 * N (input) INTEGER 00042 * The order of the matrix A. N >= 0. 00043 * 00044 * A (input) COMPLEX*16 array, dimension (LDA,N) 00045 * The factors L and U from the factorization A = P*L*U 00046 * as computed by ZGETRF. 00047 * 00048 * LDA (input) INTEGER 00049 * The leading dimension of the array A. LDA >= max(1,N). 00050 * 00051 * ANORM (input) DOUBLE PRECISION 00052 * If NORM = '1' or 'O', the 1-norm of the original matrix A. 00053 * If NORM = 'I', the infinity-norm of the original matrix A. 00054 * 00055 * RCOND (output) DOUBLE PRECISION 00056 * The reciprocal of the condition number of the matrix A, 00057 * computed as RCOND = 1/(norm(A) * norm(inv(A))). 00058 * 00059 * WORK (workspace) COMPLEX*16 array, dimension (2*N) 00060 * 00061 * RWORK (workspace) DOUBLE PRECISION array, dimension (2*N) 00062 * 00063 * INFO (output) INTEGER 00064 * = 0: successful exit 00065 * < 0: if INFO = -i, the i-th argument had an illegal value 00066 * 00067 * ===================================================================== 00068 * 00069 * .. Parameters .. 00070 DOUBLE PRECISION ONE, ZERO 00071 PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) 00072 * .. 00073 * .. Local Scalars .. 00074 LOGICAL ONENRM 00075 CHARACTER NORMIN 00076 INTEGER IX, KASE, KASE1 00077 DOUBLE PRECISION AINVNM, SCALE, SL, SMLNUM, SU 00078 COMPLEX*16 ZDUM 00079 * .. 00080 * .. Local Arrays .. 00081 INTEGER ISAVE( 3 ) 00082 * .. 00083 * .. External Functions .. 00084 LOGICAL LSAME 00085 INTEGER IZAMAX 00086 DOUBLE PRECISION DLAMCH 00087 EXTERNAL LSAME, IZAMAX, DLAMCH 00088 * .. 00089 * .. External Subroutines .. 00090 EXTERNAL XERBLA, ZDRSCL, ZLACN2, ZLATRS 00091 * .. 00092 * .. Intrinsic Functions .. 00093 INTRINSIC ABS, DBLE, DIMAG, MAX 00094 * .. 00095 * .. Statement Functions .. 00096 DOUBLE PRECISION CABS1 00097 * .. 00098 * .. Statement Function definitions .. 00099 CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) ) 00100 * .. 00101 * .. Executable Statements .. 00102 * 00103 * Test the input parameters. 00104 * 00105 INFO = 0 00106 ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' ) 00107 IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN 00108 INFO = -1 00109 ELSE IF( N.LT.0 ) THEN 00110 INFO = -2 00111 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN 00112 INFO = -4 00113 ELSE IF( ANORM.LT.ZERO ) THEN 00114 INFO = -5 00115 END IF 00116 IF( INFO.NE.0 ) THEN 00117 CALL XERBLA( 'ZGECON', -INFO ) 00118 RETURN 00119 END IF 00120 * 00121 * Quick return if possible 00122 * 00123 RCOND = ZERO 00124 IF( N.EQ.0 ) THEN 00125 RCOND = ONE 00126 RETURN 00127 ELSE IF( ANORM.EQ.ZERO ) THEN 00128 RETURN 00129 END IF 00130 * 00131 SMLNUM = DLAMCH( 'Safe minimum' ) 00132 * 00133 * Estimate the norm of inv(A). 00134 * 00135 AINVNM = ZERO 00136 NORMIN = 'N' 00137 IF( ONENRM ) THEN 00138 KASE1 = 1 00139 ELSE 00140 KASE1 = 2 00141 END IF 00142 KASE = 0 00143 10 CONTINUE 00144 CALL ZLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE ) 00145 IF( KASE.NE.0 ) THEN 00146 IF( KASE.EQ.KASE1 ) THEN 00147 * 00148 * Multiply by inv(L). 00149 * 00150 CALL ZLATRS( 'Lower', 'No transpose', 'Unit', NORMIN, N, A, 00151 $ LDA, WORK, SL, RWORK, INFO ) 00152 * 00153 * Multiply by inv(U). 00154 * 00155 CALL ZLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N, 00156 $ A, LDA, WORK, SU, RWORK( N+1 ), INFO ) 00157 ELSE 00158 * 00159 * Multiply by inv(U'). 00160 * 00161 CALL ZLATRS( 'Upper', 'Conjugate transpose', 'Non-unit', 00162 $ NORMIN, N, A, LDA, WORK, SU, RWORK( N+1 ), 00163 $ INFO ) 00164 * 00165 * Multiply by inv(L'). 00166 * 00167 CALL ZLATRS( 'Lower', 'Conjugate transpose', 'Unit', NORMIN, 00168 $ N, A, LDA, WORK, SL, RWORK, INFO ) 00169 END IF 00170 * 00171 * Divide X by 1/(SL*SU) if doing so will not cause overflow. 00172 * 00173 SCALE = SL*SU 00174 NORMIN = 'Y' 00175 IF( SCALE.NE.ONE ) THEN 00176 IX = IZAMAX( N, WORK, 1 ) 00177 IF( SCALE.LT.CABS1( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO ) 00178 $ GO TO 20 00179 CALL ZDRSCL( N, SCALE, WORK, 1 ) 00180 END IF 00181 GO TO 10 00182 END IF 00183 * 00184 * Compute the estimate of the reciprocal condition number. 00185 * 00186 IF( AINVNM.NE.ZERO ) 00187 $ RCOND = ( ONE / AINVNM ) / ANORM 00188 * 00189 20 CONTINUE 00190 RETURN 00191 * 00192 * End of ZGECON 00193 * 00194 END