001: SUBROUTINE CPPCON( UPLO, N, AP, ANORM, RCOND, WORK, RWORK, INFO ) 002: * 003: * -- LAPACK routine (version 3.2) -- 004: * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. 005: * November 2006 006: * 007: * Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. 008: * 009: * .. Scalar Arguments .. 010: CHARACTER UPLO 011: INTEGER INFO, N 012: REAL ANORM, RCOND 013: * .. 014: * .. Array Arguments .. 015: REAL RWORK( * ) 016: COMPLEX AP( * ), WORK( * ) 017: * .. 018: * 019: * Purpose 020: * ======= 021: * 022: * CPPCON estimates the reciprocal of the condition number (in the 023: * 1-norm) of a complex Hermitian positive definite packed matrix using 024: * the Cholesky factorization A = U**H*U or A = L*L**H computed by 025: * CPPTRF. 026: * 027: * An estimate is obtained for norm(inv(A)), and the reciprocal of the 028: * condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). 029: * 030: * Arguments 031: * ========= 032: * 033: * UPLO (input) CHARACTER*1 034: * = 'U': Upper triangle of A is stored; 035: * = 'L': Lower triangle of A is stored. 036: * 037: * N (input) INTEGER 038: * The order of the matrix A. N >= 0. 039: * 040: * AP (input) COMPLEX array, dimension (N*(N+1)/2) 041: * The triangular factor U or L from the Cholesky factorization 042: * A = U**H*U or A = L*L**H, packed columnwise in a linear 043: * array. The j-th column of U or L is stored in the array AP 044: * as follows: 045: * if UPLO = 'U', AP(i + (j-1)*j/2) = U(i,j) for 1<=i<=j; 046: * if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = L(i,j) for j<=i<=n. 047: * 048: * ANORM (input) REAL 049: * The 1-norm (or infinity-norm) of the Hermitian matrix A. 050: * 051: * RCOND (output) REAL 052: * The reciprocal of the condition number of the matrix A, 053: * computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an 054: * estimate of the 1-norm of inv(A) computed in this routine. 055: * 056: * WORK (workspace) COMPLEX array, dimension (2*N) 057: * 058: * RWORK (workspace) REAL array, dimension (N) 059: * 060: * INFO (output) INTEGER 061: * = 0: successful exit 062: * < 0: if INFO = -i, the i-th argument had an illegal value 063: * 064: * ===================================================================== 065: * 066: * .. Parameters .. 067: REAL ONE, ZERO 068: PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 ) 069: * .. 070: * .. Local Scalars .. 071: LOGICAL UPPER 072: CHARACTER NORMIN 073: INTEGER IX, KASE 074: REAL AINVNM, SCALE, SCALEL, SCALEU, SMLNUM 075: COMPLEX ZDUM 076: * .. 077: * .. Local Arrays .. 078: INTEGER ISAVE( 3 ) 079: * .. 080: * .. External Functions .. 081: LOGICAL LSAME 082: INTEGER ICAMAX 083: REAL SLAMCH 084: EXTERNAL LSAME, ICAMAX, SLAMCH 085: * .. 086: * .. External Subroutines .. 087: EXTERNAL CLACN2, CLATPS, CSRSCL, XERBLA 088: * .. 089: * .. Intrinsic Functions .. 090: INTRINSIC ABS, AIMAG, REAL 091: * .. 092: * .. Statement Functions .. 093: REAL CABS1 094: * .. 095: * .. Statement Function definitions .. 096: CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) ) 097: * .. 098: * .. Executable Statements .. 099: * 100: * Test the input parameters. 101: * 102: INFO = 0 103: UPPER = LSAME( UPLO, 'U' ) 104: IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN 105: INFO = -1 106: ELSE IF( N.LT.0 ) THEN 107: INFO = -2 108: ELSE IF( ANORM.LT.ZERO ) THEN 109: INFO = -4 110: END IF 111: IF( INFO.NE.0 ) THEN 112: CALL XERBLA( 'CPPCON', -INFO ) 113: RETURN 114: END IF 115: * 116: * Quick return if possible 117: * 118: RCOND = ZERO 119: IF( N.EQ.0 ) THEN 120: RCOND = ONE 121: RETURN 122: ELSE IF( ANORM.EQ.ZERO ) THEN 123: RETURN 124: END IF 125: * 126: SMLNUM = SLAMCH( 'Safe minimum' ) 127: * 128: * Estimate the 1-norm of the inverse. 129: * 130: KASE = 0 131: NORMIN = 'N' 132: 10 CONTINUE 133: CALL CLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE ) 134: IF( KASE.NE.0 ) THEN 135: IF( UPPER ) THEN 136: * 137: * Multiply by inv(U'). 138: * 139: CALL CLATPS( 'Upper', 'Conjugate transpose', 'Non-unit', 140: $ NORMIN, N, AP, WORK, SCALEL, RWORK, INFO ) 141: NORMIN = 'Y' 142: * 143: * Multiply by inv(U). 144: * 145: CALL CLATPS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N, 146: $ AP, WORK, SCALEU, RWORK, INFO ) 147: ELSE 148: * 149: * Multiply by inv(L). 150: * 151: CALL CLATPS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N, 152: $ AP, WORK, SCALEL, RWORK, INFO ) 153: NORMIN = 'Y' 154: * 155: * Multiply by inv(L'). 156: * 157: CALL CLATPS( 'Lower', 'Conjugate transpose', 'Non-unit', 158: $ NORMIN, N, AP, WORK, SCALEU, RWORK, INFO ) 159: END IF 160: * 161: * Multiply by 1/SCALE if doing so will not cause overflow. 162: * 163: SCALE = SCALEL*SCALEU 164: IF( SCALE.NE.ONE ) THEN 165: IX = ICAMAX( N, WORK, 1 ) 166: IF( SCALE.LT.CABS1( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO ) 167: $ GO TO 20 168: CALL CSRSCL( N, SCALE, WORK, 1 ) 169: END IF 170: GO TO 10 171: END IF 172: * 173: * Compute the estimate of the reciprocal condition number. 174: * 175: IF( AINVNM.NE.ZERO ) 176: $ RCOND = ( ONE / AINVNM ) / ANORM 177: * 178: 20 CONTINUE 179: RETURN 180: * 181: * End of CPPCON 182: * 183: END 184: