/home/abui.../zposvxx.f(3)

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

✨ zposvxx.f β€” Library Functions Manual ✨

okay bestie, buckle up πŸ’… this is /home/abui.../zposvxx.f(3), straight out of the LAPACK-verse, and it's literally the glow-up your linear algebra needed.


πŸ’– NAME πŸ’–

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

that's the whole path, yes the whole thing, no I'm not shortening it, she's iconic like that πŸŽ€


πŸ¦‹ SYNOPSIS πŸ¦‹

Functions/Subroutines

subroutine ZPOSVXX (fact, uplo, n, nrhs, a, lda, af, ldaf, equed, s, b,
    ldb, x, ldx, rcond, rpvgrw, berr, n_err_bnds, err_bnds_norm,
    err_bnds_comp, nparams, params, work, rwork, info)

ZPOSVXX computes the solution to system of linear equations A * X = B for PO matrices β€” that's the whole vibe, she solves stuff 🫢


🌸 Function/Subroutine Documentation 🌸

subroutine ZPOSVXX

the full signature, in all her glory, character for character, don't touch a thing:

subroutine ZPOSVXX (character fact, character uplo, integer n, integer nrhs,
    complex*16, dimension( lda, * ) a, integer lda, complex*16, dimension(
    ldaf, * ) af, integer ldaf, character equed, double precision,
    dimension( * ) s, complex*16, dimension( ldb, * ) b, integer ldb,
    complex*16, dimension( ldx, * ) x, integer ldx, double precision rcond,
    double precision rpvgrw, double precision, dimension( * ) berr, integer
    n_err_bnds, double precision, dimension( nrhs, * ) err_bnds_norm, double
    precision, dimension( nrhs, * ) err_bnds_comp, integer nparams, double
    precision, dimension( * ) params, complex*16, dimension( * ) work,
    double precision, dimension( * ) rwork, integer info)

ZPOSVXX computes the solution to system of linear equations A * X = B for PO matrices


πŸ”₯ Purpose πŸ”₯

!> !> ZPOSVXX uses the Cholesky factorization A = U**T*U or A = L*L**T !> to compute the solution to a complex*16 system of linear equations !> A * X = B, where A is an N-by-N Hermitian positive definite matrix !> and X and B are N-by-NRHS matrices. !> !> If requested, both normwise and maximum componentwise error bounds !> are returned. ZPOSVXX will return a solution with a tiny !> guaranteed error (O(eps) where eps is the working machine !> precision) unless the matrix is very ill-conditioned, in which !> case a warning is returned. Relevant condition numbers also are !> calculated and returned. !> !> ZPOSVXX accepts user-provided factorizations and equilibration !> factors; see the definitions of the FACT and EQUED options. !> Solving with refinement and using a factorization from a previous !> ZPOSVXX call will also produce a solution with either O(eps) !> errors or warnings, but we cannot make that claim for general !> user-provided factorizations and equilibration factors if they !> differ from what ZPOSVXX would itself produce. !>

so basically: she does the Cholesky thing, she gives you error bounds if you ask nicely, and if your matrix is a hot mess (like, very ill-conditioned πŸ’€) she'll warn you instead of pretending everything's fine. and ngl, if you hand her your own factorization and it doesn't match what she would've made herself, she's not gonna pinky-promise you anything. that's just honest πŸ’…


🧚 Description 🧚

!> !> The following steps are performed: !> !> 1. If FACT = 'E', double precision scaling factors are computed to equilibrate !> the system: !> !> diag(S)*A*diag(S) *inv(diag(S))*X = diag(S)*B !> !> Whether or not the system will be equilibrated depends on the !> scaling of the matrix A, but if equilibration is used, A is !> overwritten by diag(S)*A*diag(S) and B by diag(S)*B. !> !> 2. If FACT = 'N' or 'E', the Cholesky decomposition is used to !> factor the matrix A (after equilibration if FACT = 'E') as !> A = U**T* U, if UPLO = 'U', or !> A = L * L**T, if UPLO = 'L', !> where U is an upper triangular matrix and L is a lower triangular !> matrix. !> !> 3. If the leading principal minor of order i is not positive, !> then the routine returns with INFO = i. Otherwise, the factored !> form of A is used to estimate the condition number of the matrix !> A (see argument RCOND). If the reciprocal of the condition number !> is less than machine precision, the routine still goes on to solve !> for X and compute error bounds as described below. !> !> 4. The system of equations is solved for X using the factored form !> of A. !> !> 5. By default (unless PARAMS(LA_LINRX_ITREF_I) is set to zero), !> the routine will use iterative refinement to try to get a small !> error and error bounds. Refinement calculates the residual to at !> least twice the working precision. !> !> 6. If equilibration was used, the matrix X is premultiplied by !> diag(S) so that it solves the original system before !> equilibration. !>

so the literal play-by-play is:

  1. if FACT = 'E', she computes double precision scaling factors to equilibrate the system:
diag(S)*A*diag(S)     *inv(diag(S))*X = diag(S)*B

whether the system actually gets equilibrated depends on how A is scaled, but if it happens, A is overwritten by diag(S)*A*diag(S) and B by diag(S)*B.

  1. if FACT = 'N' or 'E', the Cholesky decomposition factors A (post-equilibration if FACT = 'E') as A = U**T* U, if UPLO = 'U', or A = L * L**T, if UPLO = 'L', where U is upper triangular and L is lower triangular. math slay πŸ’…
  2. if the leading principal minor of order i is not positive, she bails with INFO = i. otherwise she estimates the condition number off the factored form of A (see argument RCOND). if the reciprocal of the condition number is less than machine precision, she still goes on to solve for X and compute error bounds like described below. she's not a quitter.
  3. the system of equations is solved for X using the factored form of A.
  4. by default (unless PARAMS(LA_LINRX_ITREF_I) is set to zero), she uses iterative refinement to try to get a small error and error bounds. refinement calculates the residual to at least twice the working precision. double the precision, double the hotness ✨
  5. if equilibration was used, X is premultiplied by diag(S) so it solves the original system from before equilibration.

!> Some optional parameters are bundled in the PARAMS array. These !> settings determine how refinement is performed, but often the !> defaults are acceptable. If the defaults are acceptable, users !> can pass NPARAMS = 0 which prevents the source code from accessing !> the PARAMS argument. !>

like, the PARAMS array has some optional settings for how refinement goes down, but honestly bestie, the defaults usually eat. and if the defaults are fine for you, pass NPARAMS = 0 and the source code won't even touch the PARAMS argument. consider it a boundaries thing πŸ’…


πŸ‘‘ Parameters πŸ‘‘

FACT

!> FACT is CHARACTER*1 !> Specifies whether or not the factored form of the matrix A is !> supplied on entry, and if not, whether the matrix A should be !> equilibrated before it is factored. !> = 'F': On entry, AF contains the factored form of A. !> If EQUED is not 'N', the matrix A has been !> equilibrated with scaling factors given by S. !> A and AF are not modified. !> = 'N': The matrix A will be copied to AF and factored. !> = 'E': The matrix A will be equilibrated if necessary, then !> copied to AF and factored. !>

FACT is CHARACTER*1 and it's the "did you already do the work or not" switch:

  • = 'F' β€” on entry, AF contains the factored form of A. if EQUED is not 'N', then A has already been equilibrated with the scaling factors in S. A and AF are not modified.
  • = 'N' β€” A gets copied to AF and factored. fresh start, love that for her.
  • = 'E' β€” A gets equilibrated if necessary, then copied to AF and factored.

UPLO

!> UPLO is CHARACTER*1 !> = 'U': Upper triangle of A is stored; !> = 'L': Lower triangle of A is stored. !>

UPLO is CHARACTER*1, and it's giving "which half of the matrix are we even looking at":

  • = 'U' β€” upper triangle of A is stored
  • = 'L' β€” lower triangle of A is stored

pick a side, bestie πŸŽ€

N

!> N is INTEGER !> The number of linear equations, i.e., the order of the !> matrix A. N >= 0. !>

N is INTEGER β€” the number of linear equations, aka the order of the matrix A. constraint: N >= 0. zero is allowed, she's chill like that.

NRHS

!> NRHS is INTEGER !> The number of right hand sides, i.e., the number of columns !> of the matrices B and X. NRHS >= 0. !>

NRHS is INTEGER β€” the number of right hand sides, i.e. the number of columns of B and X. constraint: NRHS >= 0. that's right-hand sides, plural, she can handle multiple at once πŸ’…

A

!> A is COMPLEX*16 array, dimension (LDA,N) !> On entry, the Hermitian matrix A, except if FACT = 'F' and EQUED = !> 'Y', then A must contain the equilibrated matrix !> diag(S)*A*diag(S). 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. A is !> not modified if FACT = 'F' or 'N', or if FACT = 'E' and EQUED = !> 'N' on exit. !> !> On exit, if FACT = 'E' and EQUED = 'Y', A is overwritten by !> diag(S)*A*diag(S). !>

A is a COMPLEX*16 array of dimension (LDA,N). on entry it's the Hermitian matrix A β€” except if FACT = 'F' and EQUED = 'Y', in which case A must contain the equilibrated matrix diag(S)*A*diag(S).

if UPLO = 'U', the leading N-by-N upper triangular part of A holds the upper triangular part of the matrix A, and the strictly lower triangular part is not referenced (she doesn't even look at it, king behavior honestly). if UPLO = 'L', the leading N-by-N lower triangular part holds the lower triangular part of A, and the strictly upper triangular part is not referenced.

A is not modified if FACT = 'F' or 'N', or if FACT = 'E' and EQUED = 'N' on exit.

on exit, if FACT = 'E' and EQUED = 'Y', A is overwritten by diag(S)*A*diag(S). she left it different than she found it, and that's on purpose πŸ™ˆ

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. constraint: LDA >= max(1,N). don't skip this one, fr fr.

AF

!> AF is COMPLEX*16 array, dimension (LDAF,N) !> If FACT = 'F', then AF is an input argument and on entry !> contains the triangular factor U or L from the Cholesky !> factorization A = U**T*U or A = L*L**T, in the same storage !> format as A. If EQUED .ne. 'N', then AF is the factored !> form of the equilibrated matrix diag(S)*A*diag(S). !> !> If FACT = 'N', then AF is an output argument and on exit !> returns the triangular factor U or L from the Cholesky !> factorization A = U**T*U or A = L*L**T of the original !> matrix A. !> !> If FACT = 'E', then AF is an output argument and on exit !> returns the triangular factor U or L from the Cholesky !> factorization A = U**T*U or A = L*L**T of the equilibrated !> matrix A (see the description of A for the form of the !> equilibrated matrix). !>

AF is a COMPLEX*16 array of dimension (LDAF,N), and her whole personality depends on FACT:

  • if FACT = 'F', AF is an input argument, and on entry it contains the triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T, in the same storage format as A. if EQUED .ne. 'N', then AF is the factored form of the equilibrated matrix diag(S)*A*diag(S).
  • if FACT = 'N', AF is an output argument, and on exit it returns the triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T of the original matrix A.
  • if FACT = 'E', AF is an output argument, and on exit it returns the triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T of the equilibrated matrix A (peep the description of A to see what form that equilibrated matrix takes).

LDAF

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

LDAF is INTEGER β€” the leading dimension of the array AF. constraint: LDAF >= max(1,N). yes it's a separate one from LDA, yes you need both, no you can't just reuse it πŸ’€

EQUED

!> EQUED is CHARACTER*1 !> Specifies the form of equilibration that was done. !> = 'N': No equilibration (always true if FACT = 'N'). !> = 'Y': Both row and column equilibration, i.e., A has been !> replaced by diag(S) * A * diag(S). !> EQUED is an input argument if FACT = 'F'; otherwise, it is an !> output argument. !>

EQUED is CHARACTER*1 and it tells you what kind of equilibration went down:

  • = 'N' β€” no equilibration (this is always true if FACT = 'N')
  • = 'Y' β€” both row and column equilibration, i.e. A has been replaced by diag(S) * A * diag(S)

she's an input argument if FACT = 'F'; otherwise she's an output argument. main character energy, switching roles like that πŸ‘‘

S

!> S is DOUBLE PRECISION array, dimension (N) !> The row scale factors for A. If EQUED = 'Y', A is multiplied on !> the left and right by diag(S). S is an input argument if FACT = !> 'F'; otherwise, S is an output argument. If FACT = 'F' and EQUED !> = 'Y', each element of S must be positive. If S is output, each !> element of S is a power of the radix. If S is input, each element !> of S should be a power of the radix to ensure a reliable solution !> and error estimates. Scaling by powers of the radix does not cause !> rounding errors unless the result underflows or overflows. !> Rounding errors during scaling lead to refining with a matrix that !> is not equivalent to the input matrix, producing error estimates !> that may not be reliable. !>

S is a DOUBLE PRECISION array of dimension (N) β€” the row scale factors for A. if EQUED = 'Y', A gets multiplied on the left and right by diag(S).

S is an input argument if FACT = 'F'; otherwise it's an output argument. if FACT = 'F' and EQUED = 'Y', every element of S must be positive.

if S is output, each element of S is a power of the radix. if S is input, each element of S should be a power of the radix to ensure a reliable solution and error estimates β€” scaling by powers of the radix doesn't cause rounding errors unless the result underflows or overflows.

⚠️ and listen: rounding errors during scaling lead to refining with a matrix that is not equivalent to the input matrix, which produces error estimates that may not be reliable. so like… don't do that. seriously 🫢

B

!> B is COMPLEX*16 array, dimension (LDB,NRHS) !> On entry, the N-by-NRHS right hand side matrix B. !> On exit, !> if EQUED = 'N', B is not modified; !> if EQUED = 'Y', B is overwritten by diag(S)*B; !>

B is a COMPLEX*16 array of dimension (LDB,NRHS). on entry, it's the N-by-NRHS right hand side matrix B. on exit:

  • if EQUED = 'N', B is not modified (untouched, unbothered ✨)
  • if EQUED = 'Y', B is overwritten by diag(S)*B

LDB

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

LDB is INTEGER β€” the leading dimension of the array B. constraint: LDB >= max(1,N). yep, same pattern, you got this πŸ’…

X

!> X is COMPLEX*16 array, dimension (LDX,NRHS) !> If INFO = 0, the N-by-NRHS solution matrix X to the original !> system of equations. Note that A and B are modified on exit if !> EQUED .ne. 'N', and the solution to the equilibrated system is !> inv(diag(S))*X. !>

X is a COMPLEX*16 array of dimension (LDX,NRHS). if INFO = 0, this is the N-by-NRHS solution matrix X to the original system of equations. note that A and B are modified on exit if EQUED .ne. 'N', and the solution to the equilibrated system is inv(diag(S))*X. she's the answer, but you gotta read the fine print, iykyk 🌈

LDX

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

LDX is INTEGER β€” the leading dimension of the array X. constraint: LDX >= max(1,N). last of the three leading dimensions, collect the whole set πŸŽ€

RCOND

!> RCOND is DOUBLE PRECISION !> Reciprocal scaled condition number. This is an estimate of the !> reciprocal Skeel condition number of the matrix A after !> equilibration (if done). If this is less than the machine !> precision (in particular, if it is zero), the matrix is singular !> to working precision. Note that the error may still be small even !> if this number is very small and the matrix appears ill- !> conditioned. !>

RCOND is DOUBLE PRECISION β€” the reciprocal scaled condition number. it's an estimate of the reciprocal Skeel condition number of the matrix A after equilibration (if that happened).

if this is less than the machine precision β€” and especially if it's zero β€” the matrix is singular to working precision. πŸ’€

but note: the error may still be small even if this number is very small and the matrix looks ill-conditioned. so don't panic-text her just because RCOND came back tiny, okay??

RPVGRW

…and that's exactly where part 2 picks up, bestie πŸ«ΆπŸ’–

  • RPVGRW β€” DOUBLE PRECISION. Okay so this one is the reciprocal pivot growth, bestie. On exit it contains the reciprocal pivot growth factor norm(A)/norm(U). The norm is used. If this is much less than 1, then the stability of the LU factorization of the (equilibrated) matrix A could be poor. That also means the solution X, estimated condition numbers, and error bounds could be unreliable. If factorization fails with 0<INFO<=N, then this contains the reciprocal pivot growth factor for the leading INFO columns of A.
  • BERR β€” DOUBLE PRECISION array, dimension (NRHS). Componentwise relative backward error. This is the componentwise relative backward error of each solution vector X(j) (i.e., the smallest relative change in any element of A or B that makes X(j) an exact solution).
  • N_ERR_BNDS β€” INTEGER. Number of error bounds to return for each right hand side and each type (normwise or componentwise). See ERR_BNDS_NORM and ERR_BNDS_COMP below.
  • ERR_BNDS_NORM β€” DOUBLE PRECISION array, dimension (NRHS, N_ERR_BNDS). For each right-hand side, this array contains information about various error bounds and condition numbers corresponding to the normwise relative error, which is defined as follows:

Normwise relative error in the ith solution vector:

        max_j (abs(XTRUE(j,i) - X(j,i)))
       ------------------------------
             max_j abs(X(j,i))

The array is indexed by the type of error information as described below. There currently are up to three pieces of information returned.

The first index in ERR_BNDS_NORM(i,:) corresponds to the ith right-hand side.

The second index in ERR_BNDS_NORM(:,err) contains the following three fields:

  • err = 1 β€” boolean. Trust the answer if the reciprocal condition number is less than the threshold sqrt(n) * dlamch('Epsilon').
  • err = 2 β€” error bound: The estimated forward error, almost certainly within a factor of 10 of the true error so long as the next entry is greater than the threshold sqrt(n) * dlamch('Epsilon'). This error bound should only be trusted if the previous boolean is true.
  • err = 3 β€” Reciprocal condition number: Estimated normwise reciprocal condition number. Compared with the threshold sqrt(n) * dlamch('Epsilon') to determine if the error estimate is . These reciprocal condition numbers are 1 / (norm(Z^{-1},inf) * norm(Z,inf)) for some appropriately scaled matrix Z. Let Z = S*A, where S scales each row by a power of the radix so all absolute row sums of Z are approximately 1.

See Lapack Working Note 165 for further details and extra cautions.

  • ERR_BNDS_COMP β€” DOUBLE PRECISION array, dimension (NRHS, N_ERR_BNDS). For each right-hand side, this array contains information about various error bounds and condition numbers corresponding to the componentwise relative error, which is defined as follows:

Componentwise relative error in the ith solution vector:

               abs(XTRUE(j,i) - X(j,i))
        max_j ----------------------
                    abs(X(j,i))

The array is indexed by the right-hand side i (on which the componentwise relative error depends), and the type of error information as described below. There currently are up to three pieces of information returned for each right-hand side. If componentwise accuracy is not requested (PARAMS(3) = 0.0), then ERR_BNDS_COMP is not accessed. If N_ERR_BNDS < 3, then at most the first (:,N_ERR_BNDS) entries are returned.

The first index in ERR_BNDS_COMP(i,:) corresponds to the ith right-hand side.

The second index in ERR_BNDS_COMP(:,err) contains the following three fields:

  • err = 1 β€” boolean. Trust the answer if the reciprocal condition number is less than the threshold sqrt(n) * dlamch('Epsilon').
  • err = 2 β€” error bound: The estimated forward error, almost certainly within a factor of 10 of the true error so long as the next entry is greater than the threshold sqrt(n) * dlamch('Epsilon'). This error bound should only be trusted if the previous boolean is true.
  • err = 3 β€” Reciprocal condition number: Estimated componentwise reciprocal condition number. Compared with the threshold sqrt(n) * dlamch('Epsilon') to determine if the error estimate is . These reciprocal condition numbers are 1 / (norm(Z^{-1},inf) * norm(Z,inf)) for some appropriately scaled matrix Z. Let Z = S*(A*diag(x)), where x is the solution for the current right-hand side and S scales each row of A*diag(x) by a power of the radix so all absolute row sums of Z are approximately 1.

See Lapack Working Note 165 for further details and extra cautions.

  • NPARAMS β€” INTEGER. Specifies the number of parameters set in PARAMS. If <= 0, the PARAMS array is never referenced and default values are used.
  • PARAMS β€” DOUBLE PRECISION array, dimension NPARAMS. Specifies algorithm parameters. If an entry is < 0.0, then that entry will be filled with default value used for that parameter. Only positions up to NPARAMS are accessed; defaults are used for higher-numbered parameters.
    • PARAMS(LA_LINRX_ITREF_I = 1) β€” Whether to perform iterative refinement or not.
      • Default: 1.0D+0
      • = 0.0: No refinement is performed, and no error bounds are computed.
      • = 1.0: Use the extra-precise refinement algorithm.
      • (other values are reserved for future use)
    • PARAMS(LA_LINRX_ITHRESH_I = 2) β€” Maximum number of residual computations allowed for refinement.
      • Default: 10
      • Aggressive: Set to 100 to permit convergence using approximate factorizations or factorizations other than LU. If the factorization uses a technique other than Gaussian elimination, the guarantees in err_bnds_norm and err_bnds_comp may no longer be trustworthy.
    • PARAMS(LA_LINRX_CWISE_I = 3) β€” Flag determining if the code will attempt to find a solution with small componentwise relative error in the double-precision algorithm. Positive is true, 0.0 is false.
      • Default: 1.0 (attempt componentwise convergence)
  • WORK β€” COMPLEX*16 array, dimension (2*N).
  • RWORK β€” DOUBLE PRECISION array, dimension (2*N).
  • INFO β€” INTEGER.
    • = 0: Successful exit. The solution to every right-hand side is guaranteed.
    • < 0: If INFO = -i, the i-th argument had an illegal value.
    • > 0 and <= N: U(INFO,INFO) is exactly zero. The factorization has been completed, but the factor U is exactly singular, so the solution and error bounds could not be computed. RCOND = 0 is returned.
    • = N+J: The solution corresponding to the Jth right-hand side is not guaranteed. The solutions corresponding to other right-hand sides K with K > J may not be guaranteed as well, but only the first such right-hand side is reported. If a small componentwise error is not requested (PARAMS(3) = 0.0) then the Jth right-hand side is the first with a normwise error bound that is not guaranteed (the smallest J such that ERR_BNDS_NORM(J,1) = 0.0). By default (PARAMS(3) = 1.0) the Jth right-hand side is the first with either a normwise or componentwise error bound that is not guaranteed (the smallest J such that either ERR_BNDS_NORM(J,1) = 0.0 or ERR_BNDS_COMP(J,1) = 0.0). See the definition of ERR_BNDS_NORM(:,1) and ERR_BNDS_COMP(:,1). To get information about all of the right-hand sides check ERR_BNDS_NORM or ERR_BNDS_COMP.

πŸ‘‘ Author

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

Definition at line 489 of file zposvxx.f.

🌸 Author

Generated automatically by Doxygen for LAPACK from the source code.


That’s the whole vibe check, bestie β€” signed off by LAPACK Version 3.12.0 πŸ’…βœ¨ from /home/abui.../zposvxx.f(3).

πŸ“¦ where this page comes from