CHETF2(3)

πŸ“¦ version 3.12.0, in opensuse-leap 16.0

🌸 CHETF2(3) 🌸 β€” the one where your Hermitian matrix gets factored πŸ’…

okay bestie so this page lives at /home/abui...RC/chetf2.f(3), and the actual source file it's documenting is

/home/abuild/rpmbuild/BUILD/lapack-static-3.12.0-build/lapack-3.12.0/SRC/chetf2.f

like that's the whole file path, no cap, it's long but it's iconic πŸŽ€


✨ SYNOPSIS ✨

Functions/Subroutines

  • subroutine CHETF2 (uplo, n, a, lda, ipiv, info) β€” CHETF2 computes the factorization of a complex Hermitian matrix, using the diagonal pivoting method (unblocked algorithm calling Level 2 BLAS).

πŸ¦‹ Function/Subroutine Documentation πŸ¦‹

subroutine CHETF2 (character uplo, integer n, complex, dimension( lda, * )
    a, integer lda, integer, dimension( * ) ipiv, integer info)

CHETF2 computes the factorization of a complex Hermitian matrix, using the diagonal pivoting method (unblocked algorithm calling Level 2 BLAS).

πŸ’œ Purpose:

!>
!> CHETF2 computes the factorization of a complex Hermitian matrix A
!> using the Bunch-Kaufman diagonal pivoting method:
!>
!>    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, U**H is the conjugate transpose of U, and D is
!> Hermitian and block diagonal with 1-by-1 and 2-by-2 diagonal blocks.
!>
!> This is the unblocked version of the algorithm, calling Level 2 BLAS.
!>

so like, you hand it a complex Hermitian matrix A and it hands you back A = U*D*U**H or A = L*D*L**H β€” Bunch-Kaufman diagonal pivoting, the whole vibe 😌. U (or L) is a product of permutation and unit upper (lower) triangular matrices, U**H is the conjugate transpose of U, and D is Hermitian, block diagonal, with 1-by-1 and 2-by-2 diagonal blocks. and yes bestie, this is the unblocked version, calling Level 2 BLAS β€” the lowkey one 🫢


πŸŽ€ Parameters πŸŽ€

UPLO

!>          UPLO is CHARACTER*1
!>          Specifies whether the upper or lower triangular part of the
!>          Hermitian matrix A is stored:
!>          = 'U':  Upper triangular
!>          = 'L':  Lower triangular
!>

UPLO is CHARACTER*1 and it tells the routine which triangle of the Hermitian matrix A you actually stored β€” 'U' for upper triangular, 'L' for lower triangular. choose wisely πŸ’…

N

!>          N is INTEGER
!>          The order of the matrix A.  N >= 0.
!>

N is INTEGER, the order of the matrix A, and it has to be N >= 0. no negative orders, bestie, that's not the vibe πŸ’€

A

!>          A is 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).
!>

A is a COMPLEX array of dimension (LDA,N). on entry it's your Hermitian matrix A: if UPLO = 'U' the leading n-by-n upper triangular part of A holds the upper triangular part of the matrix, and the strictly lower triangular part is not referenced; if UPLO = 'L' the leading n-by-n lower triangular part holds the lower triangular part, and the strictly upper triangular part is not referenced πŸ™ˆ

on exit? it's serving the block diagonal matrix D and the multipliers used to obtain the factor U or L (see below for the full tea β˜•).

LDA

!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!>

LDA is INTEGER, the leading dimension of the array A, and the rule is LDA >= max(1,N). respect it 🫢

IPIV

!>          IPIV is INTEGER array, dimension (N)
!>          Details of the interchanges and the block structure of D.
!>
!>          If UPLO = 'U':
!>             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 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':
!>             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 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.
!>

IPIV is an INTEGER array of dimension (N) and it holds the details of the interchanges and the block structure of D β€” this is the receipts of what got swapped where πŸ‘‘

if UPLO = 'U':

  • 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 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':

  • 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 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.

INFO

!>          INFO is INTEGER
!>          = 0: successful exit
!>          < 0: if INFO = -k, the k-th argument had an illegal value
!>          > 0: if INFO = k, D(k,k) 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.
!>

INFO is INTEGER, the vibe check report:

  • = 0: successful exit, slay ✨
  • < 0: if INFO = -k, the k-th argument had an illegal value 🚩
  • > 0: if INFO = k, D(k,k) 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.
⚠️ bestie that last one is a real warning β€” the factorization finished, but D is singular, so if you go solve a system with it you're gonna divide by zero. INFO > 0 is not a warning to ignore 😭

πŸ‘‘ Author πŸ‘‘

  • Univ. of Tennessee
  • Univ. of California Berkeley
  • Univ. of Colorado Denver
  • NAG Ltd.

🌈 Further Details:

!>
!>  09-29-06 - patch from
!>    Bobby Cheng, MathWorks
!>
!>    Replace l.210 and l.392
!>         IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN
!>    by
!>         IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) .OR. SISNAN(ABSAKK) ) THEN
!>
!>  01-01-96 - Based on modifications by
!>    J. Lewis, Boeing Computer Services Company
!>    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
!>

so the lore: on 09-29-06 there was a patch from Bobby Cheng, MathWorks, that replaced lines l.210 and l.392:

IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN

became

IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) .OR. SISNAN(ABSAKK) ) THEN

and on 01-01-96 it was based on modifications by J. Lewis (Boeing Computer Services Company) and A. Petitet (Computer Science Dept., Univ. of Tenn., Knoxville, USA). history, fr fr πŸŽ€


okay now the actual math part, stay with me bestie πŸ’–

if UPLO = 'U', then A = U*D*U**H, 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**H, 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).


Definition at line 185 of file chetf2.f. πŸ¦‹


⭐ Author ⭐

Generated automatically by Doxygen for LAPACK from the source code.


and that's the whole page bestie, no notes πŸ’… β€” this one's from LAPACK, Version 3.12.0, and it's filed under /home/abui...RC/chetf2.f(3). go factor something Hermitian and text me when INFO = 0 πŸŒΈβœ¨πŸŽ€πŸ«Ά

πŸ“¦ where this page comes from