Those are just cosmetic changes to update version number and various other minor change.
283 lines
8.8 KiB
FortranFixed
283 lines
8.8 KiB
FortranFixed
SUBROUTINE CHETRF( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )
|
|
*
|
|
* -- LAPACK routine (version 3.2) --
|
|
* -- LAPACK is a software package provided by Univ. of Tennessee, --
|
|
* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
|
|
* November 2006
|
|
*
|
|
* .. Scalar Arguments ..
|
|
CHARACTER UPLO
|
|
INTEGER INFO, LDA, LWORK, N
|
|
* ..
|
|
* .. Array Arguments ..
|
|
INTEGER IPIV( * )
|
|
COMPLEX A( LDA, * ), WORK( * )
|
|
* ..
|
|
*
|
|
* Purpose
|
|
* =======
|
|
*
|
|
* CHETRF computes the factorization of a complex Hermitian matrix A
|
|
* using the Bunch-Kaufman diagonal pivoting method. The form of the
|
|
* factorization is
|
|
*
|
|
* A = U*D*U**H or A = L*D*L**H
|
|
*
|
|
* where U (or L) is a product of permutation and unit upper (lower)
|
|
* triangular matrices, and D is Hermitian and block diagonal with
|
|
* 1-by-1 and 2-by-2 diagonal blocks.
|
|
*
|
|
* This is the blocked version of the algorithm, calling Level 3 BLAS.
|
|
*
|
|
* Arguments
|
|
* =========
|
|
*
|
|
* UPLO (input) CHARACTER*1
|
|
* = 'U': Upper triangle of A is stored;
|
|
* = 'L': Lower triangle of A is stored.
|
|
*
|
|
* N (input) INTEGER
|
|
* The order of the matrix A. N >= 0.
|
|
*
|
|
* A (input/output) COMPLEX array, dimension (LDA,N)
|
|
* On entry, the Hermitian matrix A. If UPLO = 'U', the leading
|
|
* N-by-N upper triangular part of A contains the upper
|
|
* triangular part of the matrix A, and the strictly lower
|
|
* triangular part of A is not referenced. If UPLO = 'L', the
|
|
* leading N-by-N lower triangular part of A contains the lower
|
|
* triangular part of the matrix A, and the strictly upper
|
|
* triangular part of A is not referenced.
|
|
*
|
|
* On exit, the block diagonal matrix D and the multipliers used
|
|
* to obtain the factor U or L (see below for further details).
|
|
*
|
|
* LDA (input) INTEGER
|
|
* The leading dimension of the array A. LDA >= max(1,N).
|
|
*
|
|
* IPIV (output) INTEGER array, dimension (N)
|
|
* Details of the interchanges and the block structure of D.
|
|
* If IPIV(k) > 0, then rows and columns k and IPIV(k) were
|
|
* interchanged and D(k,k) is a 1-by-1 diagonal block.
|
|
* If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and
|
|
* columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k)
|
|
* is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) =
|
|
* IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were
|
|
* interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block.
|
|
*
|
|
* WORK (workspace/output) COMPLEX array, dimension (MAX(1,LWORK))
|
|
* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
|
|
*
|
|
* LWORK (input) INTEGER
|
|
* The length of WORK. LWORK >=1. For best performance
|
|
* LWORK >= N*NB, where NB is the block size returned by ILAENV.
|
|
*
|
|
* INFO (output) INTEGER
|
|
* = 0: successful exit
|
|
* < 0: if INFO = -i, the i-th argument had an illegal value
|
|
* > 0: if INFO = i, D(i,i) is exactly zero. The factorization
|
|
* has been completed, but the block diagonal matrix D is
|
|
* exactly singular, and division by zero will occur if it
|
|
* is used to solve a system of equations.
|
|
*
|
|
* Further Details
|
|
* ===============
|
|
*
|
|
* If UPLO = 'U', then A = U*D*U', where
|
|
* U = P(n)*U(n)* ... *P(k)U(k)* ...,
|
|
* i.e., U is a product of terms P(k)*U(k), where k decreases from n to
|
|
* 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1
|
|
* and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as
|
|
* defined by IPIV(k), and U(k) is a unit upper triangular matrix, such
|
|
* that if the diagonal block D(k) is of order s (s = 1 or 2), then
|
|
*
|
|
* ( I v 0 ) k-s
|
|
* U(k) = ( 0 I 0 ) s
|
|
* ( 0 0 I ) n-k
|
|
* k-s s n-k
|
|
*
|
|
* If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k).
|
|
* If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k),
|
|
* and A(k,k), and v overwrites A(1:k-2,k-1:k).
|
|
*
|
|
* If UPLO = 'L', then A = L*D*L', where
|
|
* L = P(1)*L(1)* ... *P(k)*L(k)* ...,
|
|
* i.e., L is a product of terms P(k)*L(k), where k increases from 1 to
|
|
* n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1
|
|
* and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as
|
|
* defined by IPIV(k), and L(k) is a unit lower triangular matrix, such
|
|
* that if the diagonal block D(k) is of order s (s = 1 or 2), then
|
|
*
|
|
* ( I 0 0 ) k-1
|
|
* L(k) = ( 0 I 0 ) s
|
|
* ( 0 v I ) n-k-s+1
|
|
* k-1 s n-k-s+1
|
|
*
|
|
* If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k).
|
|
* If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k),
|
|
* and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1).
|
|
*
|
|
* =====================================================================
|
|
*
|
|
* .. Local Scalars ..
|
|
LOGICAL LQUERY, UPPER
|
|
INTEGER IINFO, IWS, J, K, KB, LDWORK, LWKOPT, NB, NBMIN
|
|
* ..
|
|
* .. External Functions ..
|
|
LOGICAL LSAME
|
|
INTEGER ILAENV
|
|
EXTERNAL LSAME, ILAENV
|
|
* ..
|
|
* .. External Subroutines ..
|
|
EXTERNAL CHETF2, CLAHEF, XERBLA
|
|
* ..
|
|
* .. Intrinsic Functions ..
|
|
INTRINSIC MAX
|
|
* ..
|
|
* .. Executable Statements ..
|
|
*
|
|
* Test the input parameters.
|
|
*
|
|
INFO = 0
|
|
UPPER = LSAME( UPLO, 'U' )
|
|
LQUERY = ( LWORK.EQ.-1 )
|
|
IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
|
|
INFO = -1
|
|
ELSE IF( N.LT.0 ) THEN
|
|
INFO = -2
|
|
ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
|
|
INFO = -4
|
|
ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN
|
|
INFO = -7
|
|
END IF
|
|
*
|
|
IF( INFO.EQ.0 ) THEN
|
|
*
|
|
* Determine the block size
|
|
*
|
|
NB = ILAENV( 1, 'CHETRF', UPLO, N, -1, -1, -1 )
|
|
LWKOPT = N*NB
|
|
WORK( 1 ) = LWKOPT
|
|
END IF
|
|
*
|
|
IF( INFO.NE.0 ) THEN
|
|
CALL XERBLA( 'CHETRF', -INFO )
|
|
RETURN
|
|
ELSE IF( LQUERY ) THEN
|
|
RETURN
|
|
END IF
|
|
*
|
|
NBMIN = 2
|
|
LDWORK = N
|
|
IF( NB.GT.1 .AND. NB.LT.N ) THEN
|
|
IWS = LDWORK*NB
|
|
IF( LWORK.LT.IWS ) THEN
|
|
NB = MAX( LWORK / LDWORK, 1 )
|
|
NBMIN = MAX( 2, ILAENV( 2, 'CHETRF', UPLO, N, -1, -1, -1 ) )
|
|
END IF
|
|
ELSE
|
|
IWS = 1
|
|
END IF
|
|
IF( NB.LT.NBMIN )
|
|
$ NB = N
|
|
*
|
|
IF( UPPER ) THEN
|
|
*
|
|
* Factorize A as U*D*U' using the upper triangle of A
|
|
*
|
|
* K is the main loop index, decreasing from N to 1 in steps of
|
|
* KB, where KB is the number of columns factorized by CLAHEF;
|
|
* KB is either NB or NB-1, or K for the last block
|
|
*
|
|
K = N
|
|
10 CONTINUE
|
|
*
|
|
* If K < 1, exit from loop
|
|
*
|
|
IF( K.LT.1 )
|
|
$ GO TO 40
|
|
*
|
|
IF( K.GT.NB ) THEN
|
|
*
|
|
* Factorize columns k-kb+1:k of A and use blocked code to
|
|
* update columns 1:k-kb
|
|
*
|
|
CALL CLAHEF( UPLO, K, NB, KB, A, LDA, IPIV, WORK, N, IINFO )
|
|
ELSE
|
|
*
|
|
* Use unblocked code to factorize columns 1:k of A
|
|
*
|
|
CALL CHETF2( UPLO, K, A, LDA, IPIV, IINFO )
|
|
KB = K
|
|
END IF
|
|
*
|
|
* Set INFO on the first occurrence of a zero pivot
|
|
*
|
|
IF( INFO.EQ.0 .AND. IINFO.GT.0 )
|
|
$ INFO = IINFO
|
|
*
|
|
* Decrease K and return to the start of the main loop
|
|
*
|
|
K = K - KB
|
|
GO TO 10
|
|
*
|
|
ELSE
|
|
*
|
|
* Factorize A as L*D*L' using the lower triangle of A
|
|
*
|
|
* K is the main loop index, increasing from 1 to N in steps of
|
|
* KB, where KB is the number of columns factorized by CLAHEF;
|
|
* KB is either NB or NB-1, or N-K+1 for the last block
|
|
*
|
|
K = 1
|
|
20 CONTINUE
|
|
*
|
|
* If K > N, exit from loop
|
|
*
|
|
IF( K.GT.N )
|
|
$ GO TO 40
|
|
*
|
|
IF( K.LE.N-NB ) THEN
|
|
*
|
|
* Factorize columns k:k+kb-1 of A and use blocked code to
|
|
* update columns k+kb:n
|
|
*
|
|
CALL CLAHEF( UPLO, N-K+1, NB, KB, A( K, K ), LDA, IPIV( K ),
|
|
$ WORK, N, IINFO )
|
|
ELSE
|
|
*
|
|
* Use unblocked code to factorize columns k:n of A
|
|
*
|
|
CALL CHETF2( UPLO, N-K+1, A( K, K ), LDA, IPIV( K ), IINFO )
|
|
KB = N - K + 1
|
|
END IF
|
|
*
|
|
* Set INFO on the first occurrence of a zero pivot
|
|
*
|
|
IF( INFO.EQ.0 .AND. IINFO.GT.0 )
|
|
$ INFO = IINFO + K - 1
|
|
*
|
|
* Adjust IPIV
|
|
*
|
|
DO 30 J = K, K + KB - 1
|
|
IF( IPIV( J ).GT.0 ) THEN
|
|
IPIV( J ) = IPIV( J ) + K - 1
|
|
ELSE
|
|
IPIV( J ) = IPIV( J ) - K + 1
|
|
END IF
|
|
30 CONTINUE
|
|
*
|
|
* Increase K and return to the start of the main loop
|
|
*
|
|
K = K + KB
|
|
GO TO 20
|
|
*
|
|
END IF
|
|
*
|
|
40 CONTINUE
|
|
WORK( 1 ) = LWKOPT
|
|
RETURN
|
|
*
|
|
* End of CHETRF
|
|
*
|
|
END
|