!----------------------------------------------------------------! ! Purpose ! ======= ! ! LA_SPSVX uses the diagonal pivoting factorization A = U*D*U**T or ! A = L*D*L**T to compute the solution to a system of linear ! equations A * X = B, where A is a symmetric real or complex, or ! hermitian matrix stored in packed format and X and B are either ! rectangular matrices or vectors. ! Error bounds on the solution and a condition estimate are also ! provided. ! ! Description ! =========== ! ! The following steps are performed: ! ! 1. If FACT = 'N', the diagonal pivoting method is used to factor A as ! A = U * D * U**T, if UPLO = 'U', or ! A = L * D * L**T, if UPLO = 'L', ! where U (or L) is a product of permutation and unit upper (lower) ! triangular matrices and D is symmetric and block diagonal with ! 1-by-1 and 2-by-2 diagonal blocks. ! ! 2. If some D(i,i)=0, so that D is exactly singular, then the routine ! returns with INFO = i. Otherwise, the factored form of A is used ! to estimate the condition number of the matrix A. If the ! reciprocal of the condition number is less than machine precision, ! INFO = N+1 is returned as a warning, but the routine still goes on ! to solve for X and compute error bounds as described below. ! ! 3. The system of equations is solved for X using the factored form ! of A. ! 4. Iterative refinement is applied to improve the computed solution ! matrix and calculate error bounds and backward error estimates ! for it. ! ! Arguments ! ========= ! ! SUBROUTINE LA_SPSVX( AP, B, X, UPLO, AFP, IPIV, FACT, & ! FERR, BERR, RCOND, INFO ) ! <type>(<wp>), INTENT(IN) :: AP(:), <rhs> ! <type>(<wp>), INTENT(OUT) :: <sol> ! CHARACTER(LEN=1), INTENT(IN), OPTIONAL :: UPLO ! <type>(<wp>), INTENT(INOUT), OPTIONAL :: AFP(:) ! INTEGER, INTENT(INOUT), OPTIONAL :: IPIV(:) ! CHARACTER(LEN=1), INTENT(IN), OPTIONAL :: FACT ! REAL(<wp>), INTENT(OUT), OPTIONAL :: <err>, RCOND ! INTEGER, INTENT(OUT), OPTIONAL :: INFO ! <type> ::= REAL | COMPLEX ! <wp> ::= KIND(1.0) | KIND(1.0D0) ! <rhs> ::= B(:,:) | B(:) ! <sol> ::= X(:,:) | X(:) ! <err> ::= FERR(:), BERR(:) | FERR, BERR ! ! ===================== ! ! AP (input) either REAL or COMPLEX array, shape (:), SIZE(AP) == (n*(n+1)/2) ! The upper or lower triangle of the symmetric matrix A, packed ! columnwise in a linear array. The j-th column of A is stored ! in the array AP as follows: ! if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j; ! if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n. ! See below for further details. ! INFO = -1 if SIZE(AP) < 0 or SIZE(AP) /= n*(n+1)/2. ! ! B (input) either REAL or COMPLEX rectangular array, ! shape either (:,:) or (:), size(B,1) or size(B) == n. ! The right hand side matrix B. ! INFO = -2 if SIZE(B,1) /= n or SIZE(B,2) < 0 ! and if shape of B is (:,:) or ! if SIZE(B) /= n and if shape of B is (:) ! ! X (output) either REAL or COMPLEX rectangular array, ! shape either (:,:) or (:), size(X,1) or size(X) == size(A,1) ! and SIZE(X,2) == SIZE(B,2). ! If INFO = 0 or INFO = n+1, the solution matrix X. ! INFO = -3 if SIZE(X,1) /= n or SIZE(X,2) /= SIZE(B,2) ! and if shape of X is (:,:) or ! if SIZE(X) /= n and if shape of X is (:) ! ! UPLO Optional (input) CHARACTER*1 ! = 'U': Upper triangle of A is stored; ! = 'L': Lower triangle of A is stored. ! If UPLO is not present UPLO = 'U' is assumed. ! INFO -4 if UPLO /= 'U' nor 'L'. ! ! AFP Optional (input/output) either REAL or COMPLEX array, shape (:), ! SIZE(AFP) == SIZE(AP). ! If FACT = 'F', then AFP is an input argument and on entry ! contains the block diagonal matrix D and the multipliers used ! to obtain the factor U or L from the factorization ! A = U*D*U**T or A = L*D*L**T as computed by _SPTRF, stored as ! a packed triangular matrix in the same storage format as A. ! If FACT = 'N', then AFP is an output argument and on exit ! contains the block diagonal matrix D and the multipliers used ! to obtain the factor U or L from the factorization ! A = U*D*U**T or A = L*D*L**T as computed by _SPTRF, stored as ! a packed triangular matrix in the same storage format as A. ! INFO = -5 if SIZE(AFP) /= SIZE(AP) ! ! IPIV Optional (input/output) INTEGER array, shape (:), SIZE(IPIV == n, ! where n*(n+1)/2 == SIZE(AP). ! If FACT = 'F', then IPIV is an input argument and on entry ! contains details of the interchanges and the block structure ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! of D, as determined by _SPTRF. 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. If FACT = 'N', then IPIV is an output argument and on exit contains details of the interchanges and the block structure of D, as determined by _SPTRF. INFO = -6 if SIZE(IPIV) /= n, where n*(n+1)/2 == SIZE(AP). FACT Optional (input) CHARACTER*1 Specifies whether or not the factored form of A has been supplied on entry. = 'F': On entry, AFP and IPIV contain the factored form of A. AP, AFP and IPIV will not be modified. = 'N': The matrix A will be copied to AFP and factored. If FACT is not present FACT = 'N' is assumed. INFO = -7 if ( FACT /= 'F' nor 'N' ) or if FACT ='F' and AF and IPIV are not present. FERR Optional (output) eithe REAL array, shape (:) or REAL scalar. SIZE(FERR) == SIZE(B,2), if FERR is an array The estimated forward error bound for each solution vector X(j) (the j-th column of the solution matrix X). If XTRUE is the true solution corresponding to X(j), FERR(j) is an estimated upper bound for the magnitude of the largest element in (X(j) - XTRUE) divided by the magnitude of the largest element in X(j). The estimate is as reliable as the estimate for RCOND, and is almost always a slight overestimate of the true error. INFO = -8 if SIZE(FERR) /= SIZE(B,2) and if FERR is a vector. BERR Optional (output) eithe REAL array, shape (:) or REAL scalar. SIZE(BERR) == SIZE(B,2), if BERR is an array. 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). INFO = -10 if SIZE(FERR) /= SIZE(B,2) and if BERR is a vector. RCOND Optional (output) REAL The estimate of the reciprocal condition number of the matrix A. If RCOND is less than the machine precision (in particular, if RCOND = 0), the matrix is singular to working precision. This condition is indicated by a return code of INFO > 0. INFO (output) INTEGER = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, and i is <= n: D(i,i) is exactly zero. The factorization ! has been completed but the factor D is exactly ! singular, so the solution and error bounds could ! not be computed. RCOND = 0 is returned. ! = n+1: D is nonsingular, but RCOND is less than machine ! precision, meaning that the matrix is singular ! to working precision. Nevertheless, the ! solution and error bounds are computed because ! there are a number of situations where the ! computed solution can be more accurate than the ! value of RCOND would suggest. ! If INFO is not present and an error occurs, then the program is ! terminated with an error message. ! n*(n+1)/2 = SIZE(AP) is a rank of the matrix A. ! ! Further Details ! =============== ! ! The packed storage scheme is illustrated by the following example ! when n = 4, UPLO = 'U': ! ! Two-dimensional storage of the symmetric matrix A: ! ! a11 a12 a13 a14 ! a22 a23 a24 ! a33 a34 (aij = aji) ! a44 ! Packed storage of the upper triangle of A: ! AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ] ! n*(n+1)/2 == SIZE(AP). !--------------------------------------