LAPACK 3.3.0
|
00001 SUBROUTINE CHETRF( UPLO, N, A, LDA, IPIV, WORK, LWORK, 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, LDA, LWORK, N 00011 * .. 00012 * .. Array Arguments .. 00013 INTEGER IPIV( * ) 00014 COMPLEX A( LDA, * ), WORK( * ) 00015 * .. 00016 * 00017 * Purpose 00018 * ======= 00019 * 00020 * CHETRF computes the factorization of a complex Hermitian matrix A 00021 * using the Bunch-Kaufman diagonal pivoting method. The form of the 00022 * factorization is 00023 * 00024 * A = U*D*U**H or A = L*D*L**H 00025 * 00026 * where U (or L) is a product of permutation and unit upper (lower) 00027 * triangular matrices, and D is Hermitian and block diagonal with 00028 * 1-by-1 and 2-by-2 diagonal blocks. 00029 * 00030 * This is the blocked version of the algorithm, calling Level 3 BLAS. 00031 * 00032 * Arguments 00033 * ========= 00034 * 00035 * UPLO (input) CHARACTER*1 00036 * = 'U': Upper triangle of A is stored; 00037 * = 'L': Lower triangle of A is stored. 00038 * 00039 * N (input) INTEGER 00040 * The order of the matrix A. N >= 0. 00041 * 00042 * A (input/output) COMPLEX array, dimension (LDA,N) 00043 * On entry, the Hermitian matrix A. If UPLO = 'U', the leading 00044 * N-by-N upper triangular part of A contains the upper 00045 * triangular part of the matrix A, and the strictly lower 00046 * triangular part of A is not referenced. If UPLO = 'L', the 00047 * leading N-by-N lower triangular part of A contains the lower 00048 * triangular part of the matrix A, and the strictly upper 00049 * triangular part of A is not referenced. 00050 * 00051 * On exit, the block diagonal matrix D and the multipliers used 00052 * to obtain the factor U or L (see below for further details). 00053 * 00054 * LDA (input) INTEGER 00055 * The leading dimension of the array A. LDA >= max(1,N). 00056 * 00057 * IPIV (output) INTEGER array, dimension (N) 00058 * Details of the interchanges and the block structure of D. 00059 * If IPIV(k) > 0, then rows and columns k and IPIV(k) were 00060 * interchanged and D(k,k) is a 1-by-1 diagonal block. 00061 * If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and 00062 * columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) 00063 * is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) = 00064 * IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were 00065 * interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block. 00066 * 00067 * WORK (workspace/output) COMPLEX array, dimension (MAX(1,LWORK)) 00068 * On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 00069 * 00070 * LWORK (input) INTEGER 00071 * The length of WORK. LWORK >=1. For best performance 00072 * LWORK >= N*NB, where NB is the block size returned by ILAENV. 00073 * 00074 * INFO (output) INTEGER 00075 * = 0: successful exit 00076 * < 0: if INFO = -i, the i-th argument had an illegal value 00077 * > 0: if INFO = i, D(i,i) is exactly zero. The factorization 00078 * has been completed, but the block diagonal matrix D is 00079 * exactly singular, and division by zero will occur if it 00080 * is used to solve a system of equations. 00081 * 00082 * Further Details 00083 * =============== 00084 * 00085 * If UPLO = 'U', then A = U*D*U', where 00086 * U = P(n)*U(n)* ... *P(k)U(k)* ..., 00087 * i.e., U is a product of terms P(k)*U(k), where k decreases from n to 00088 * 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 00089 * and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as 00090 * defined by IPIV(k), and U(k) is a unit upper triangular matrix, such 00091 * that if the diagonal block D(k) is of order s (s = 1 or 2), then 00092 * 00093 * ( I v 0 ) k-s 00094 * U(k) = ( 0 I 0 ) s 00095 * ( 0 0 I ) n-k 00096 * k-s s n-k 00097 * 00098 * If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k). 00099 * If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k), 00100 * and A(k,k), and v overwrites A(1:k-2,k-1:k). 00101 * 00102 * If UPLO = 'L', then A = L*D*L', where 00103 * L = P(1)*L(1)* ... *P(k)*L(k)* ..., 00104 * i.e., L is a product of terms P(k)*L(k), where k increases from 1 to 00105 * n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 00106 * and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as 00107 * defined by IPIV(k), and L(k) is a unit lower triangular matrix, such 00108 * that if the diagonal block D(k) is of order s (s = 1 or 2), then 00109 * 00110 * ( I 0 0 ) k-1 00111 * L(k) = ( 0 I 0 ) s 00112 * ( 0 v I ) n-k-s+1 00113 * k-1 s n-k-s+1 00114 * 00115 * If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k). 00116 * If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k), 00117 * and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1). 00118 * 00119 * ===================================================================== 00120 * 00121 * .. Local Scalars .. 00122 LOGICAL LQUERY, UPPER 00123 INTEGER IINFO, IWS, J, K, KB, LDWORK, LWKOPT, NB, NBMIN 00124 * .. 00125 * .. External Functions .. 00126 LOGICAL LSAME 00127 INTEGER ILAENV 00128 EXTERNAL LSAME, ILAENV 00129 * .. 00130 * .. External Subroutines .. 00131 EXTERNAL CHETF2, CLAHEF, XERBLA 00132 * .. 00133 * .. Intrinsic Functions .. 00134 INTRINSIC MAX 00135 * .. 00136 * .. Executable Statements .. 00137 * 00138 * Test the input parameters. 00139 * 00140 INFO = 0 00141 UPPER = LSAME( UPLO, 'U' ) 00142 LQUERY = ( LWORK.EQ.-1 ) 00143 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN 00144 INFO = -1 00145 ELSE IF( N.LT.0 ) THEN 00146 INFO = -2 00147 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN 00148 INFO = -4 00149 ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN 00150 INFO = -7 00151 END IF 00152 * 00153 IF( INFO.EQ.0 ) THEN 00154 * 00155 * Determine the block size 00156 * 00157 NB = ILAENV( 1, 'CHETRF', UPLO, N, -1, -1, -1 ) 00158 LWKOPT = N*NB 00159 WORK( 1 ) = LWKOPT 00160 END IF 00161 * 00162 IF( INFO.NE.0 ) THEN 00163 CALL XERBLA( 'CHETRF', -INFO ) 00164 RETURN 00165 ELSE IF( LQUERY ) THEN 00166 RETURN 00167 END IF 00168 * 00169 NBMIN = 2 00170 LDWORK = N 00171 IF( NB.GT.1 .AND. NB.LT.N ) THEN 00172 IWS = LDWORK*NB 00173 IF( LWORK.LT.IWS ) THEN 00174 NB = MAX( LWORK / LDWORK, 1 ) 00175 NBMIN = MAX( 2, ILAENV( 2, 'CHETRF', UPLO, N, -1, -1, -1 ) ) 00176 END IF 00177 ELSE 00178 IWS = 1 00179 END IF 00180 IF( NB.LT.NBMIN ) 00181 $ NB = N 00182 * 00183 IF( UPPER ) THEN 00184 * 00185 * Factorize A as U*D*U' using the upper triangle of A 00186 * 00187 * K is the main loop index, decreasing from N to 1 in steps of 00188 * KB, where KB is the number of columns factorized by CLAHEF; 00189 * KB is either NB or NB-1, or K for the last block 00190 * 00191 K = N 00192 10 CONTINUE 00193 * 00194 * If K < 1, exit from loop 00195 * 00196 IF( K.LT.1 ) 00197 $ GO TO 40 00198 * 00199 IF( K.GT.NB ) THEN 00200 * 00201 * Factorize columns k-kb+1:k of A and use blocked code to 00202 * update columns 1:k-kb 00203 * 00204 CALL CLAHEF( UPLO, K, NB, KB, A, LDA, IPIV, WORK, N, IINFO ) 00205 ELSE 00206 * 00207 * Use unblocked code to factorize columns 1:k of A 00208 * 00209 CALL CHETF2( UPLO, K, A, LDA, IPIV, IINFO ) 00210 KB = K 00211 END IF 00212 * 00213 * Set INFO on the first occurrence of a zero pivot 00214 * 00215 IF( INFO.EQ.0 .AND. IINFO.GT.0 ) 00216 $ INFO = IINFO 00217 * 00218 * Decrease K and return to the start of the main loop 00219 * 00220 K = K - KB 00221 GO TO 10 00222 * 00223 ELSE 00224 * 00225 * Factorize A as L*D*L' using the lower triangle of A 00226 * 00227 * K is the main loop index, increasing from 1 to N in steps of 00228 * KB, where KB is the number of columns factorized by CLAHEF; 00229 * KB is either NB or NB-1, or N-K+1 for the last block 00230 * 00231 K = 1 00232 20 CONTINUE 00233 * 00234 * If K > N, exit from loop 00235 * 00236 IF( K.GT.N ) 00237 $ GO TO 40 00238 * 00239 IF( K.LE.N-NB ) THEN 00240 * 00241 * Factorize columns k:k+kb-1 of A and use blocked code to 00242 * update columns k+kb:n 00243 * 00244 CALL CLAHEF( UPLO, N-K+1, NB, KB, A( K, K ), LDA, IPIV( K ), 00245 $ WORK, N, IINFO ) 00246 ELSE 00247 * 00248 * Use unblocked code to factorize columns k:n of A 00249 * 00250 CALL CHETF2( UPLO, N-K+1, A( K, K ), LDA, IPIV( K ), IINFO ) 00251 KB = N - K + 1 00252 END IF 00253 * 00254 * Set INFO on the first occurrence of a zero pivot 00255 * 00256 IF( INFO.EQ.0 .AND. IINFO.GT.0 ) 00257 $ INFO = IINFO + K - 1 00258 * 00259 * Adjust IPIV 00260 * 00261 DO 30 J = K, K + KB - 1 00262 IF( IPIV( J ).GT.0 ) THEN 00263 IPIV( J ) = IPIV( J ) + K - 1 00264 ELSE 00265 IPIV( J ) = IPIV( J ) - K + 1 00266 END IF 00267 30 CONTINUE 00268 * 00269 * Increase K and return to the start of the main loop 00270 * 00271 K = K + KB 00272 GO TO 20 00273 * 00274 END IF 00275 * 00276 40 CONTINUE 00277 WORK( 1 ) = LWKOPT 00278 RETURN 00279 * 00280 * End of CHETRF 00281 * 00282 END