*> \brief \b CGEMM * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * SUBROUTINE CGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC) * * .. Scalar Arguments .. * COMPLEX ALPHA,BETA * INTEGER K,LDA,LDB,LDC,M,N * CHARACTER TRANSA,TRANSB * .. * .. Array Arguments .. * COMPLEX A(LDA,*),B(LDB,*),C(LDC,*) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> CGEMM performs one of the matrix-matrix operations *> *> C := alpha*op( A )*op( B ) + beta*C, *> *> where op( X ) is one of *> *> op( X ) = X or op( X ) = X**T or op( X ) = X**H, *> *> alpha and beta are scalars, and A, B and C are matrices, with op( A ) *> an m by k matrix, op( B ) a k by n matrix and C an m by n matrix. *> \endverbatim * * Arguments: * ========== * *> \param[in] TRANSA *> \verbatim *> TRANSA is CHARACTER*1 *> On entry, TRANSA specifies the form of op( A ) to be used in *> the matrix multiplication as follows: *> *> TRANSA = 'N' or 'n', op( A ) = A. *> *> TRANSA = 'T' or 't', op( A ) = A**T. *> *> TRANSA = 'C' or 'c', op( A ) = A**H. *> \endverbatim *> *> \param[in] TRANSB *> \verbatim *> TRANSB is CHARACTER*1 *> On entry, TRANSB specifies the form of op( B ) to be used in *> the matrix multiplication as follows: *> *> TRANSB = 'N' or 'n', op( B ) = B. *> *> TRANSB = 'T' or 't', op( B ) = B**T. *> *> TRANSB = 'C' or 'c', op( B ) = B**H. *> \endverbatim *> *> \param[in] M *> \verbatim *> M is INTEGER *> On entry, M specifies the number of rows of the matrix *> op( A ) and of the matrix C. M must be at least zero. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> On entry, N specifies the number of columns of the matrix *> op( B ) and the number of columns of the matrix C. N must be *> at least zero. *> \endverbatim *> *> \param[in] K *> \verbatim *> K is INTEGER *> On entry, K specifies the number of columns of the matrix *> op( A ) and the number of rows of the matrix op( B ). K must *> be at least zero. *> \endverbatim *> *> \param[in] ALPHA *> \verbatim *> ALPHA is COMPLEX *> On entry, ALPHA specifies the scalar alpha. *> \endverbatim *> *> \param[in] A *> \verbatim *> A is COMPLEX array, dimension ( LDA, ka ), where ka is *> k when TRANSA = 'N' or 'n', and is m otherwise. *> Before entry with TRANSA = 'N' or 'n', the leading m by k *> part of the array A must contain the matrix A, otherwise *> the leading k by m part of the array A must contain the *> matrix A. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> On entry, LDA specifies the first dimension of A as declared *> in the calling (sub) program. When TRANSA = 'N' or 'n' then *> LDA must be at least max( 1, m ), otherwise LDA must be at *> least max( 1, k ). *> \endverbatim *> *> \param[in] B *> \verbatim *> B is COMPLEX array, dimension ( LDB, kb ), where kb is *> n when TRANSB = 'N' or 'n', and is k otherwise. *> Before entry with TRANSB = 'N' or 'n', the leading k by n *> part of the array B must contain the matrix B, otherwise *> the leading n by k part of the array B must contain the *> matrix B. *> \endverbatim *> *> \param[in] LDB *> \verbatim *> LDB is INTEGER *> On entry, LDB specifies the first dimension of B as declared *> in the calling (sub) program. When TRANSB = 'N' or 'n' then *> LDB must be at least max( 1, k ), otherwise LDB must be at *> least max( 1, n ). *> \endverbatim *> *> \param[in] BETA *> \verbatim *> BETA is COMPLEX *> On entry, BETA specifies the scalar beta. When BETA is *> supplied as zero then C need not be set on input. *> \endverbatim *> *> \param[in,out] C *> \verbatim *> C is COMPLEX array, dimension ( LDC, N ) *> Before entry, the leading m by n part of the array C must *> contain the matrix C, except when beta is zero, in which *> case C need not be set on entry. *> On exit, the array C is overwritten by the m by n matrix *> ( alpha*op( A )*op( B ) + beta*C ). *> \endverbatim *> *> \param[in] LDC *> \verbatim *> LDC is INTEGER *> On entry, LDC specifies the first dimension of C as declared *> in the calling (sub) program. LDC must be at least *> max( 1, m ). *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup gemm * *> \par Further Details: * ===================== *> *> \verbatim *> *> Level 3 Blas routine. *> *> -- Written on 8-February-1989. *> Jack Dongarra, Argonne National Laboratory. *> Iain Duff, AERE Harwell. *> Jeremy Du Croz, Numerical Algorithms Group Ltd. *> Sven Hammarling, Numerical Algorithms Group Ltd. *> \endverbatim *> * ===================================================================== SUBROUTINE CGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB, + BETA,C,LDC) * * -- Reference BLAS level3 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. COMPLEX ALPHA,BETA INTEGER K,LDA,LDB,LDC,M,N CHARACTER TRANSA,TRANSB * .. * .. Array Arguments .. COMPLEX A(LDA,*),B(LDB,*),C(LDC,*) * .. * * ===================================================================== * * .. External Functions .. LOGICAL LSAME EXTERNAL LSAME * .. * .. External Subroutines .. EXTERNAL XERBLA * .. * .. Intrinsic Functions .. INTRINSIC CONJG,MAX * .. * .. Local Scalars .. COMPLEX TEMP INTEGER I,INFO,J,L,NROWA,NROWB LOGICAL CONJA,CONJB,NOTA,NOTB * .. * .. Parameters .. COMPLEX ONE PARAMETER (ONE= (1.0E+0,0.0E+0)) COMPLEX ZERO PARAMETER (ZERO= (0.0E+0,0.0E+0)) * .. * * Set NOTA and NOTB as true if A and B respectively are not * conjugated or transposed, set CONJA and CONJB as true if A and * B respectively are to be transposed but not conjugated and set * NROWA and NROWB as the number of rows of A and B respectively. * NOTA = LSAME(TRANSA,'N') NOTB = LSAME(TRANSB,'N') CONJA = LSAME(TRANSA,'C') CONJB = LSAME(TRANSB,'C') IF (NOTA) THEN NROWA = M ELSE NROWA = K END IF IF (NOTB) THEN NROWB = K ELSE NROWB = N END IF * * Test the input parameters. * INFO = 0 IF ((.NOT.NOTA) .AND. (.NOT.CONJA) .AND. + (.NOT.LSAME(TRANSA,'T'))) THEN INFO = 1 ELSE IF ((.NOT.NOTB) .AND. (.NOT.CONJB) .AND. + (.NOT.LSAME(TRANSB,'T'))) THEN INFO = 2 ELSE IF (M.LT.0) THEN INFO = 3 ELSE IF (N.LT.0) THEN INFO = 4 ELSE IF (K.LT.0) THEN INFO = 5 ELSE IF (LDA.LT.MAX(1,NROWA)) THEN INFO = 8 ELSE IF (LDB.LT.MAX(1,NROWB)) THEN INFO = 10 ELSE IF (LDC.LT.MAX(1,M)) THEN INFO = 13 END IF IF (INFO.NE.0) THEN CALL XERBLA('CGEMM ',INFO) RETURN END IF * * Quick return if possible. * IF ((M.EQ.0) .OR. (N.EQ.0) .OR. + (((ALPHA.EQ.ZERO).OR. (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN * * And when alpha.eq.zero. * IF (ALPHA.EQ.ZERO) THEN IF (BETA.EQ.ZERO) THEN DO 20 J = 1,N DO 10 I = 1,M C(I,J) = ZERO 10 CONTINUE 20 CONTINUE ELSE DO 40 J = 1,N DO 30 I = 1,M C(I,J) = BETA*C(I,J) 30 CONTINUE 40 CONTINUE END IF RETURN END IF * * Start the operations. * IF (NOTB) THEN IF (NOTA) THEN * * Form C := alpha*A*B + beta*C. * DO 90 J = 1,N IF (BETA.EQ.ZERO) THEN DO 50 I = 1,M C(I,J) = ZERO 50 CONTINUE ELSE IF (BETA.NE.ONE) THEN DO 60 I = 1,M C(I,J) = BETA*C(I,J) 60 CONTINUE END IF DO 80 L = 1,K TEMP = ALPHA*B(L,J) DO 70 I = 1,M C(I,J) = C(I,J) + TEMP*A(I,L) 70 CONTINUE 80 CONTINUE 90 CONTINUE ELSE IF (CONJA) THEN * * Form C := alpha*A**H*B + beta*C. * DO 120 J = 1,N DO 110 I = 1,M TEMP = ZERO DO 100 L = 1,K TEMP = TEMP + CONJG(A(L,I))*B(L,J) 100 CONTINUE IF (BETA.EQ.ZERO) THEN C(I,J) = ALPHA*TEMP ELSE C(I,J) = ALPHA*TEMP + BETA*C(I,J) END IF 110 CONTINUE 120 CONTINUE ELSE * * Form C := alpha*A**T*B + beta*C * DO 150 J = 1,N DO 140 I = 1,M TEMP = ZERO DO 130 L = 1,K TEMP = TEMP + A(L,I)*B(L,J) 130 CONTINUE IF (BETA.EQ.ZERO) THEN C(I,J) = ALPHA*TEMP ELSE C(I,J) = ALPHA*TEMP + BETA*C(I,J) END IF 140 CONTINUE 150 CONTINUE END IF ELSE IF (NOTA) THEN IF (CONJB) THEN * * Form C := alpha*A*B**H + beta*C. * DO 200 J = 1,N IF (BETA.EQ.ZERO) THEN DO 160 I = 1,M C(I,J) = ZERO 160 CONTINUE ELSE IF (BETA.NE.ONE) THEN DO 170 I = 1,M C(I,J) = BETA*C(I,J) 170 CONTINUE END IF DO 190 L = 1,K TEMP = ALPHA*CONJG(B(J,L)) DO 180 I = 1,M C(I,J) = C(I,J) + TEMP*A(I,L) 180 CONTINUE 190 CONTINUE 200 CONTINUE ELSE * * Form C := alpha*A*B**T + beta*C * DO 250 J = 1,N IF (BETA.EQ.ZERO) THEN DO 210 I = 1,M C(I,J) = ZERO 210 CONTINUE ELSE IF (BETA.NE.ONE) THEN DO 220 I = 1,M C(I,J) = BETA*C(I,J) 220 CONTINUE END IF DO 240 L = 1,K TEMP = ALPHA*B(J,L) DO 230 I = 1,M C(I,J) = C(I,J) + TEMP*A(I,L) 230 CONTINUE 240 CONTINUE 250 CONTINUE END IF ELSE IF (CONJA) THEN IF (CONJB) THEN * * Form C := alpha*A**H*B**H + beta*C. * DO 280 J = 1,N DO 270 I = 1,M TEMP = ZERO DO 260 L = 1,K TEMP = TEMP + CONJG(A(L,I))*CONJG(B(J,L)) 260 CONTINUE IF (BETA.EQ.ZERO) THEN C(I,J) = ALPHA*TEMP ELSE C(I,J) = ALPHA*TEMP + BETA*C(I,J) END IF 270 CONTINUE 280 CONTINUE ELSE * * Form C := alpha*A**H*B**T + beta*C * DO 310 J = 1,N DO 300 I = 1,M TEMP = ZERO DO 290 L = 1,K TEMP = TEMP + CONJG(A(L,I))*B(J,L) 290 CONTINUE IF (BETA.EQ.ZERO) THEN C(I,J) = ALPHA*TEMP ELSE C(I,J) = ALPHA*TEMP + BETA*C(I,J) END IF 300 CONTINUE 310 CONTINUE END IF ELSE IF (CONJB) THEN * * Form C := alpha*A**T*B**H + beta*C * DO 340 J = 1,N DO 330 I = 1,M TEMP = ZERO DO 320 L = 1,K TEMP = TEMP + A(L,I)*CONJG(B(J,L)) 320 CONTINUE IF (BETA.EQ.ZERO) THEN C(I,J) = ALPHA*TEMP ELSE C(I,J) = ALPHA*TEMP + BETA*C(I,J) END IF 330 CONTINUE 340 CONTINUE ELSE * * Form C := alpha*A**T*B**T + beta*C * DO 370 J = 1,N DO 360 I = 1,M TEMP = ZERO DO 350 L = 1,K TEMP = TEMP + A(L,I)*B(J,L) 350 CONTINUE IF (BETA.EQ.ZERO) THEN C(I,J) = ALPHA*TEMP ELSE C(I,J) = ALPHA*TEMP + BETA*C(I,J) END IF 360 CONTINUE 370 CONTINUE END IF END IF * RETURN * * End of CGEMM * END *> \brief \b CGETRF * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download CGETRF + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * SUBROUTINE CGETRF( M, N, A, LDA, IPIV, INFO ) * * .. Scalar Arguments .. * INTEGER INFO, LDA, M, N * .. * .. Array Arguments .. * INTEGER IPIV( * ) * COMPLEX A( LDA, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> CGETRF computes an LU factorization of a general M-by-N matrix A *> using partial pivoting with row interchanges. *> *> The factorization has the form *> A = P * L * U *> where P is a permutation matrix, L is lower triangular with unit *> diagonal elements (lower trapezoidal if m > n), and U is upper *> triangular (upper trapezoidal if m < n). *> *> This is the right-looking Level 3 BLAS version of the algorithm. *> \endverbatim * * Arguments: * ========== * *> \param[in] M *> \verbatim *> M is INTEGER *> The number of rows of the matrix A. M >= 0. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> The number of columns of the matrix A. N >= 0. *> \endverbatim *> *> \param[in,out] A *> \verbatim *> A is COMPLEX array, dimension (LDA,N) *> On entry, the M-by-N matrix to be factored. *> On exit, the factors L and U from the factorization *> A = P*L*U; the unit diagonal elements of L are not stored. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. LDA >= max(1,M). *> \endverbatim *> *> \param[out] IPIV *> \verbatim *> IPIV is INTEGER array, dimension (min(M,N)) *> The pivot indices; for 1 <= i <= min(M,N), row i of the *> matrix was interchanged with row IPIV(i). *> \endverbatim *> *> \param[out] INFO *> \verbatim *> INFO is INTEGER *> = 0: successful exit *> < 0: if INFO = -i, the i-th argument had an illegal value *> > 0: if INFO = i, U(i,i) is exactly zero. The factorization *> has been completed, but the factor U is exactly *> singular, and division by zero will occur if it is used *> to solve a system of equations. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup getrf * * ===================================================================== SUBROUTINE CGETRF( M, N, A, LDA, IPIV, INFO ) * * -- LAPACK computational routine -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. INTEGER INFO, LDA, M, N * .. * .. Array Arguments .. INTEGER IPIV( * ) COMPLEX A( LDA, * ) * .. * * ===================================================================== * * .. Parameters .. COMPLEX ONE PARAMETER ( ONE = ( 1.0E+0, 0.0E+0 ) ) * .. * .. Local Scalars .. INTEGER I, IINFO, J, JB, NB * .. * .. External Subroutines .. EXTERNAL CGEMM, CGETRF2, CLASWP, CTRSM, $ XERBLA * .. * .. External Functions .. INTEGER ILAENV EXTERNAL ILAENV * .. * .. Intrinsic Functions .. INTRINSIC MAX, MIN * .. * .. Executable Statements .. * * Test the input parameters. * INFO = 0 IF( M.LT.0 ) THEN INFO = -1 ELSE IF( N.LT.0 ) THEN INFO = -2 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN INFO = -4 END IF IF( INFO.NE.0 ) THEN CALL XERBLA( 'CGETRF', -INFO ) RETURN END IF * * Quick return if possible * IF( M.EQ.0 .OR. N.EQ.0 ) $ RETURN * * Determine the block size for this environment. * NB = ILAENV( 1, 'CGETRF', ' ', M, N, -1, -1 ) IF( NB.LE.1 .OR. NB.GE.MIN( M, N ) ) THEN * * Use unblocked code. * CALL CGETRF2( M, N, A, LDA, IPIV, INFO ) ELSE * * Use blocked code. * DO 20 J = 1, MIN( M, N ), NB JB = MIN( MIN( M, N )-J+1, NB ) * * Factor diagonal and subdiagonal blocks and test for exact * singularity. * CALL CGETRF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), $ IINFO ) * * Adjust INFO and the pivot indices. * IF( INFO.EQ.0 .AND. IINFO.GT.0 ) $ INFO = IINFO + J - 1 DO 10 I = J, MIN( M, J+JB-1 ) IPIV( I ) = J - 1 + IPIV( I ) 10 CONTINUE * * Apply interchanges to columns 1:J-1. * CALL CLASWP( J-1, A, LDA, J, J+JB-1, IPIV, 1 ) * IF( J+JB.LE.N ) THEN * * Apply interchanges to columns J+JB:N. * CALL CLASWP( N-J-JB+1, A( 1, J+JB ), LDA, J, J+JB-1, $ IPIV, 1 ) * * Compute block row of U. * CALL CTRSM( 'Left', 'Lower', 'No transpose', 'Unit', $ JB, $ N-J-JB+1, ONE, A( J, J ), LDA, A( J, J+JB ), $ LDA ) IF( J+JB.LE.M ) THEN * * Update trailing submatrix. * CALL CGEMM( 'No transpose', 'No transpose', $ M-J-JB+1, $ N-J-JB+1, JB, -ONE, A( J+JB, J ), LDA, $ A( J, J+JB ), LDA, ONE, A( J+JB, J+JB ), $ LDA ) END IF END IF 20 CONTINUE END IF RETURN * * End of CGETRF * END *> \brief \b CGETRF2 * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * RECURSIVE SUBROUTINE CGETRF2( M, N, A, LDA, IPIV, INFO ) * * .. Scalar Arguments .. * INTEGER INFO, LDA, M, N * .. * .. Array Arguments .. * INTEGER IPIV( * ) * COMPLEX A( LDA, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> CGETRF2 computes an LU factorization of a general M-by-N matrix A *> using partial pivoting with row interchanges. *> *> The factorization has the form *> A = P * L * U *> where P is a permutation matrix, L is lower triangular with unit *> diagonal elements (lower trapezoidal if m > n), and U is upper *> triangular (upper trapezoidal if m < n). *> *> This is the recursive version of the algorithm. It divides *> the matrix into four submatrices: *> *> [ A11 | A12 ] where A11 is n1 by n1 and A22 is n2 by n2 *> A = [ -----|----- ] with n1 = min(m,n)/2 *> [ A21 | A22 ] n2 = n-n1 *> *> [ A11 ] *> The subroutine calls itself to factor [ --- ], *> [ A12 ] *> [ A12 ] *> do the swaps on [ --- ], solve A12, update A22, *> [ A22 ] *> *> then calls itself to factor A22 and do the swaps on A21. *> *> \endverbatim * * Arguments: * ========== * *> \param[in] M *> \verbatim *> M is INTEGER *> The number of rows of the matrix A. M >= 0. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> The number of columns of the matrix A. N >= 0. *> \endverbatim *> *> \param[in,out] A *> \verbatim *> A is COMPLEX array, dimension (LDA,N) *> On entry, the M-by-N matrix to be factored. *> On exit, the factors L and U from the factorization *> A = P*L*U; the unit diagonal elements of L are not stored. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. LDA >= max(1,M). *> \endverbatim *> *> \param[out] IPIV *> \verbatim *> IPIV is INTEGER array, dimension (min(M,N)) *> The pivot indices; for 1 <= i <= min(M,N), row i of the *> matrix was interchanged with row IPIV(i). *> \endverbatim *> *> \param[out] INFO *> \verbatim *> INFO is INTEGER *> = 0: successful exit *> < 0: if INFO = -i, the i-th argument had an illegal value *> > 0: if INFO = i, U(i,i) is exactly zero. The factorization *> has been completed, but the factor U is exactly *> singular, and division by zero will occur if it is used *> to solve a system of equations. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup getrf2 * * ===================================================================== RECURSIVE SUBROUTINE CGETRF2( M, N, A, LDA, IPIV, INFO ) * * -- LAPACK computational routine -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. INTEGER INFO, LDA, M, N * .. * .. Array Arguments .. INTEGER IPIV( * ) COMPLEX A( LDA, * ) * .. * * ===================================================================== * * .. Parameters .. COMPLEX ONE, ZERO PARAMETER ( ONE = ( 1.0E+0, 0.0E+0 ), $ ZERO = ( 0.0E+0, 0.0E+0 ) ) * .. * .. Local Scalars .. REAL SFMIN COMPLEX TEMP INTEGER I, IINFO, N1, N2 * .. * .. External Functions .. REAL SLAMCH INTEGER ICAMAX EXTERNAL SLAMCH, ICAMAX * .. * .. External Subroutines .. EXTERNAL CGEMM, CSCAL, CLASWP, CTRSM, XERBLA * .. * .. Intrinsic Functions .. INTRINSIC MAX, MIN * .. * .. Executable Statements .. * * Test the input parameters * INFO = 0 IF( M.LT.0 ) THEN INFO = -1 ELSE IF( N.LT.0 ) THEN INFO = -2 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN INFO = -4 END IF IF( INFO.NE.0 ) THEN CALL XERBLA( 'CGETRF2', -INFO ) RETURN END IF * * Quick return if possible * IF( M.EQ.0 .OR. N.EQ.0 ) $ RETURN IF ( M.EQ.1 ) THEN * * Use unblocked code for one row case * Just need to handle IPIV and INFO * IPIV( 1 ) = 1 IF ( A(1,1).EQ.ZERO ) $ INFO = 1 * ELSE IF( N.EQ.1 ) THEN * * Use unblocked code for one column case * * * Compute machine safe minimum * SFMIN = SLAMCH('S') * * Find pivot and test for singularity * I = ICAMAX( M, A( 1, 1 ), 1 ) IPIV( 1 ) = I IF( A( I, 1 ).NE.ZERO ) THEN * * Apply the interchange * IF( I.NE.1 ) THEN TEMP = A( 1, 1 ) A( 1, 1 ) = A( I, 1 ) A( I, 1 ) = TEMP END IF * * Compute elements 2:M of the column * IF( ABS(A( 1, 1 )) .GE. SFMIN ) THEN CALL CSCAL( M-1, ONE / A( 1, 1 ), A( 2, 1 ), 1 ) ELSE DO 10 I = 1, M-1 A( 1+I, 1 ) = A( 1+I, 1 ) / A( 1, 1 ) 10 CONTINUE END IF * ELSE INFO = 1 END IF * ELSE * * Use recursive code * N1 = MIN( M, N ) / 2 N2 = N-N1 * * [ A11 ] * Factor [ --- ] * [ A21 ] * CALL CGETRF2( M, N1, A, LDA, IPIV, IINFO ) IF ( INFO.EQ.0 .AND. IINFO.GT.0 ) $ INFO = IINFO * * [ A12 ] * Apply interchanges to [ --- ] * [ A22 ] * CALL CLASWP( N2, A( 1, N1+1 ), LDA, 1, N1, IPIV, 1 ) * * Solve A12 * CALL CTRSM( 'L', 'L', 'N', 'U', N1, N2, ONE, A, LDA, $ A( 1, N1+1 ), LDA ) * * Update A22 * CALL CGEMM( 'N', 'N', M-N1, N2, N1, -ONE, A( N1+1, 1 ), LDA, $ A( 1, N1+1 ), LDA, ONE, A( N1+1, N1+1 ), LDA ) * * Factor A22 * CALL CGETRF2( M-N1, N2, A( N1+1, N1+1 ), LDA, IPIV( N1+1 ), $ IINFO ) * * Adjust INFO and the pivot indices * IF ( INFO.EQ.0 .AND. IINFO.GT.0 ) $ INFO = IINFO + N1 DO 20 I = N1+1, MIN( M, N ) IPIV( I ) = IPIV( I ) + N1 20 CONTINUE * * Apply interchanges to A21 * CALL CLASWP( N1, A( 1, 1 ), LDA, N1+1, MIN( M, N), IPIV, 1 ) * END IF RETURN * * End of CGETRF2 * END *> \brief \b CGETRS * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download CGETRS + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * SUBROUTINE CGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO ) * * .. Scalar Arguments .. * CHARACTER TRANS * INTEGER INFO, LDA, LDB, N, NRHS * .. * .. Array Arguments .. * INTEGER IPIV( * ) * COMPLEX A( LDA, * ), B( LDB, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> CGETRS solves a system of linear equations *> A * X = B, A**T * X = B, or A**H * X = B *> with a general N-by-N matrix A using the LU factorization computed *> by CGETRF. *> \endverbatim * * Arguments: * ========== * *> \param[in] TRANS *> \verbatim *> TRANS is CHARACTER*1 *> Specifies the form of the system of equations: *> = 'N': A * X = B (No transpose) *> = 'T': A**T * X = B (Transpose) *> = 'C': A**H * X = B (Conjugate transpose) *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> The order of the matrix A. N >= 0. *> \endverbatim *> *> \param[in] NRHS *> \verbatim *> NRHS is INTEGER *> The number of right hand sides, i.e., the number of columns *> of the matrix B. NRHS >= 0. *> \endverbatim *> *> \param[in] A *> \verbatim *> A is COMPLEX array, dimension (LDA,N) *> The factors L and U from the factorization A = P*L*U *> as computed by CGETRF. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. LDA >= max(1,N). *> \endverbatim *> *> \param[in] IPIV *> \verbatim *> IPIV is INTEGER array, dimension (N) *> The pivot indices from CGETRF; for 1<=i<=N, row i of the *> matrix was interchanged with row IPIV(i). *> \endverbatim *> *> \param[in,out] B *> \verbatim *> B is COMPLEX array, dimension (LDB,NRHS) *> On entry, the right hand side matrix B. *> On exit, the solution matrix X. *> \endverbatim *> *> \param[in] LDB *> \verbatim *> LDB is INTEGER *> The leading dimension of the array B. LDB >= max(1,N). *> \endverbatim *> *> \param[out] INFO *> \verbatim *> INFO is INTEGER *> = 0: successful exit *> < 0: if INFO = -i, the i-th argument had an illegal value *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup getrs * * ===================================================================== SUBROUTINE CGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO ) * * -- LAPACK computational routine -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. CHARACTER TRANS INTEGER INFO, LDA, LDB, N, NRHS * .. * .. Array Arguments .. INTEGER IPIV( * ) COMPLEX A( LDA, * ), B( LDB, * ) * .. * * ===================================================================== * * .. Parameters .. COMPLEX ONE PARAMETER ( ONE = ( 1.0E+0, 0.0E+0 ) ) * .. * .. Local Scalars .. LOGICAL NOTRAN * .. * .. External Functions .. LOGICAL LSAME EXTERNAL LSAME * .. * .. External Subroutines .. EXTERNAL CLASWP, CTRSM, XERBLA * .. * .. Intrinsic Functions .. INTRINSIC MAX * .. * .. Executable Statements .. * * Test the input parameters. * INFO = 0 NOTRAN = LSAME( TRANS, 'N' ) IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT. $ LSAME( TRANS, 'C' ) ) THEN INFO = -1 ELSE IF( N.LT.0 ) THEN INFO = -2 ELSE IF( NRHS.LT.0 ) THEN INFO = -3 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN INFO = -5 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN INFO = -8 END IF IF( INFO.NE.0 ) THEN CALL XERBLA( 'CGETRS', -INFO ) RETURN END IF * * Quick return if possible * IF( N.EQ.0 .OR. NRHS.EQ.0 ) $ RETURN * IF( NOTRAN ) THEN * * Solve A * X = B. * * Apply row interchanges to the right hand sides. * CALL CLASWP( NRHS, B, LDB, 1, N, IPIV, 1 ) * * Solve L*X = B, overwriting B with X. * CALL CTRSM( 'Left', 'Lower', 'No transpose', 'Unit', N, $ NRHS, $ ONE, A, LDA, B, LDB ) * * Solve U*X = B, overwriting B with X. * CALL CTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N, $ NRHS, ONE, A, LDA, B, LDB ) ELSE * * Solve A**T * X = B or A**H * X = B. * * Solve U**T *X = B or U**H *X = B, overwriting B with X. * CALL CTRSM( 'Left', 'Upper', TRANS, 'Non-unit', N, NRHS, $ ONE, $ A, LDA, B, LDB ) * * Solve L**T *X = B, or L**H *X = B overwriting B with X. * CALL CTRSM( 'Left', 'Lower', TRANS, 'Unit', N, NRHS, ONE, A, $ LDA, B, LDB ) * * Apply row interchanges to the solution vectors. * CALL CLASWP( NRHS, B, LDB, 1, N, IPIV, -1 ) END IF * RETURN * * End of CGETRS * END *> \brief \b CLAG2Z converts a complex single precision matrix to a complex double precision matrix. * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download CLAG2Z + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * SUBROUTINE CLAG2Z( M, N, SA, LDSA, A, LDA, INFO ) * * .. Scalar Arguments .. * INTEGER INFO, LDA, LDSA, M, N * .. * .. Array Arguments .. * COMPLEX SA( LDSA, * ) * COMPLEX*16 A( LDA, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> CLAG2Z converts a COMPLEX matrix, SA, to a COMPLEX*16 matrix, A. *> *> Note that while it is possible to overflow while converting *> from double to single, it is not possible to overflow when *> converting from single to double. *> *> This is an auxiliary routine so there is no argument checking. *> \endverbatim * * Arguments: * ========== * *> \param[in] M *> \verbatim *> M is INTEGER *> The number of lines of the matrix A. M >= 0. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> The number of columns of the matrix A. N >= 0. *> \endverbatim *> *> \param[in] SA *> \verbatim *> SA is COMPLEX array, dimension (LDSA,N) *> On entry, the M-by-N coefficient matrix SA. *> \endverbatim *> *> \param[in] LDSA *> \verbatim *> LDSA is INTEGER *> The leading dimension of the array SA. LDSA >= max(1,M). *> \endverbatim *> *> \param[out] A *> \verbatim *> A is COMPLEX*16 array, dimension (LDA,N) *> On exit, the M-by-N coefficient matrix A. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. LDA >= max(1,M). *> \endverbatim *> *> \param[out] INFO *> \verbatim *> INFO is INTEGER *> = 0: successful exit *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup _lag2_ * * ===================================================================== SUBROUTINE CLAG2Z( M, N, SA, LDSA, A, LDA, INFO ) * * -- LAPACK auxiliary routine -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. INTEGER INFO, LDA, LDSA, M, N * .. * .. Array Arguments .. COMPLEX SA( LDSA, * ) COMPLEX*16 A( LDA, * ) * .. * * ===================================================================== * * .. Local Scalars .. INTEGER I, J * .. * .. Executable Statements .. * INFO = 0 DO 20 J = 1, N DO 10 I = 1, M A( I, J ) = SA( I, J ) 10 CONTINUE 20 CONTINUE RETURN * * End of CLAG2Z * END *> \brief \b CLASWP performs a series of row interchanges on a general rectangular matrix. * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download CLASWP + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * SUBROUTINE CLASWP( N, A, LDA, K1, K2, IPIV, INCX ) * * .. Scalar Arguments .. * INTEGER INCX, K1, K2, LDA, N * .. * .. Array Arguments .. * INTEGER IPIV( * ) * COMPLEX A( LDA, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> CLASWP performs a series of row interchanges on the matrix A. *> One row interchange is initiated for each of rows K1 through K2 of A. *> \endverbatim * * Arguments: * ========== * *> \param[in] N *> \verbatim *> N is INTEGER *> The number of columns of the matrix A. *> \endverbatim *> *> \param[in,out] A *> \verbatim *> A is COMPLEX array, dimension (LDA,N) *> On entry, the matrix of column dimension N to which the row *> interchanges will be applied. *> On exit, the permuted matrix. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. *> \endverbatim *> *> \param[in] K1 *> \verbatim *> K1 is INTEGER *> The first element of IPIV for which a row interchange will *> be done. *> \endverbatim *> *> \param[in] K2 *> \verbatim *> K2 is INTEGER *> (K2-K1+1) is the number of elements of IPIV for which a row *> interchange will be done. *> \endverbatim *> *> \param[in] IPIV *> \verbatim *> IPIV is INTEGER array, dimension (K1+(K2-K1)*abs(INCX)) *> The vector of pivot indices. Only the elements in positions *> K1 through K1+(K2-K1)*abs(INCX) of IPIV are accessed. *> IPIV(K1+(K-K1)*abs(INCX)) = L implies rows K and L are to be *> interchanged. *> \endverbatim *> *> \param[in] INCX *> \verbatim *> INCX is INTEGER *> The increment between successive values of IPIV. If INCX *> is negative, the pivots are applied in reverse order. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup laswp * *> \par Further Details: * ===================== *> *> \verbatim *> *> Modified by *> R. C. Whaley, Computer Science Dept., Univ. of Tenn., Knoxville, USA *> \endverbatim *> * ===================================================================== SUBROUTINE CLASWP( N, A, LDA, K1, K2, IPIV, INCX ) * * -- LAPACK auxiliary routine -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. INTEGER INCX, K1, K2, LDA, N * .. * .. Array Arguments .. INTEGER IPIV( * ) COMPLEX A( LDA, * ) * .. * * ===================================================================== * * .. Local Scalars .. INTEGER I, I1, I2, INC, IP, IX, IX0, J, K, N32 COMPLEX TEMP * .. * .. Executable Statements .. * * Interchange row I with row IPIV(K1+(I-K1)*abs(INCX)) for each of rows * K1 through K2. * IF( INCX.GT.0 ) THEN IX0 = K1 I1 = K1 I2 = K2 INC = 1 ELSE IF( INCX.LT.0 ) THEN IX0 = K1 + ( K1-K2 )*INCX I1 = K2 I2 = K1 INC = -1 ELSE RETURN END IF * N32 = ( N / 32 )*32 IF( N32.NE.0 ) THEN DO 30 J = 1, N32, 32 IX = IX0 DO 20 I = I1, I2, INC IP = IPIV( IX ) IF( IP.NE.I ) THEN DO 10 K = J, J + 31 TEMP = A( I, K ) A( I, K ) = A( IP, K ) A( IP, K ) = TEMP 10 CONTINUE END IF IX = IX + INCX 20 CONTINUE 30 CONTINUE END IF IF( N32.NE.N ) THEN N32 = N32 + 1 IX = IX0 DO 50 I = I1, I2, INC IP = IPIV( IX ) IF( IP.NE.I ) THEN DO 40 K = N32, N TEMP = A( I, K ) A( I, K ) = A( IP, K ) A( IP, K ) = TEMP 40 CONTINUE END IF IX = IX + INCX 50 CONTINUE END IF * RETURN * * End of CLASWP * END *> \brief \b CSCAL * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * SUBROUTINE CSCAL(N,CA,CX,INCX) * * .. Scalar Arguments .. * COMPLEX CA * INTEGER INCX,N * .. * .. Array Arguments .. * COMPLEX CX(*) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> CSCAL scales a vector by a constant. *> \endverbatim * * Arguments: * ========== * *> \param[in] N *> \verbatim *> N is INTEGER *> number of elements in input vector(s) *> \endverbatim *> *> \param[in] CA *> \verbatim *> CA is COMPLEX *> On entry, CA specifies the scalar alpha. *> \endverbatim *> *> \param[in,out] CX *> \verbatim *> CX is COMPLEX array, dimension ( 1 + ( N - 1 )*abs( INCX ) ) *> \endverbatim *> *> \param[in] INCX *> \verbatim *> INCX is INTEGER *> storage spacing between elements of CX *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup scal * *> \par Further Details: * ===================== *> *> \verbatim *> *> jack dongarra, linpack, 3/11/78. *> modified 3/93 to return if incx .le. 0. *> modified 12/3/93, array(1) declarations changed to array(*) *> \endverbatim *> * ===================================================================== SUBROUTINE CSCAL(N,CA,CX,INCX) * * -- Reference BLAS level1 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. COMPLEX CA INTEGER INCX,N * .. * .. Array Arguments .. COMPLEX CX(*) * .. * * ===================================================================== * * .. Local Scalars .. INTEGER I,NINCX * .. * .. Parameters .. COMPLEX ONE PARAMETER (ONE= (1.0E+0,0.0E+0)) * .. IF (N.LE.0 .OR. INCX.LE.0 .OR. CA.EQ.ONE) RETURN IF (INCX.EQ.1) THEN * * code for increment equal to 1 * DO I = 1,N CX(I) = CA*CX(I) END DO ELSE * * code for increment not equal to 1 * NINCX = N*INCX DO I = 1,NINCX,INCX CX(I) = CA*CX(I) END DO END IF RETURN * * End of CSCAL * END *> \brief \b CTRSM * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * SUBROUTINE CTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB) * * .. Scalar Arguments .. * COMPLEX ALPHA * INTEGER LDA,LDB,M,N * CHARACTER DIAG,SIDE,TRANSA,UPLO * .. * .. Array Arguments .. * COMPLEX A(LDA,*),B(LDB,*) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> CTRSM solves one of the matrix equations *> *> op( A )*X = alpha*B, or X*op( A ) = alpha*B, *> *> where alpha is a scalar, X and B are m by n matrices, A is a unit, or *> non-unit, upper or lower triangular matrix and op( A ) is one of *> *> op( A ) = A or op( A ) = A**T or op( A ) = A**H. *> *> The matrix X is overwritten on B. *> \endverbatim * * Arguments: * ========== * *> \param[in] SIDE *> \verbatim *> SIDE is CHARACTER*1 *> On entry, SIDE specifies whether op( A ) appears on the left *> or right of X as follows: *> *> SIDE = 'L' or 'l' op( A )*X = alpha*B. *> *> SIDE = 'R' or 'r' X*op( A ) = alpha*B. *> \endverbatim *> *> \param[in] UPLO *> \verbatim *> UPLO is CHARACTER*1 *> On entry, UPLO specifies whether the matrix A is an upper or *> lower triangular matrix as follows: *> *> UPLO = 'U' or 'u' A is an upper triangular matrix. *> *> UPLO = 'L' or 'l' A is a lower triangular matrix. *> \endverbatim *> *> \param[in] TRANSA *> \verbatim *> TRANSA is CHARACTER*1 *> On entry, TRANSA specifies the form of op( A ) to be used in *> the matrix multiplication as follows: *> *> TRANSA = 'N' or 'n' op( A ) = A. *> *> TRANSA = 'T' or 't' op( A ) = A**T. *> *> TRANSA = 'C' or 'c' op( A ) = A**H. *> \endverbatim *> *> \param[in] DIAG *> \verbatim *> DIAG is CHARACTER*1 *> On entry, DIAG specifies whether or not A is unit triangular *> as follows: *> *> DIAG = 'U' or 'u' A is assumed to be unit triangular. *> *> DIAG = 'N' or 'n' A is not assumed to be unit *> triangular. *> \endverbatim *> *> \param[in] M *> \verbatim *> M is INTEGER *> On entry, M specifies the number of rows of B. M must be at *> least zero. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> On entry, N specifies the number of columns of B. N must be *> at least zero. *> \endverbatim *> *> \param[in] ALPHA *> \verbatim *> ALPHA is COMPLEX *> On entry, ALPHA specifies the scalar alpha. When alpha is *> zero then A is not referenced and B need not be set before *> entry. *> \endverbatim *> *> \param[in] A *> \verbatim *> A is COMPLEX array, dimension ( LDA, k ), *> where k is m when SIDE = 'L' or 'l' *> and k is n when SIDE = 'R' or 'r'. *> Before entry with UPLO = 'U' or 'u', the leading k by k *> upper triangular part of the array A must contain the upper *> triangular matrix and the strictly lower triangular part of *> A is not referenced. *> Before entry with UPLO = 'L' or 'l', the leading k by k *> lower triangular part of the array A must contain the lower *> triangular matrix and the strictly upper triangular part of *> A is not referenced. *> Note that when DIAG = 'U' or 'u', the diagonal elements of *> A are not referenced either, but are assumed to be unity. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> On entry, LDA specifies the first dimension of A as declared *> in the calling (sub) program. When SIDE = 'L' or 'l' then *> LDA must be at least max( 1, m ), when SIDE = 'R' or 'r' *> then LDA must be at least max( 1, n ). *> \endverbatim *> *> \param[in,out] B *> \verbatim *> B is COMPLEX array, dimension ( LDB, N ) *> Before entry, the leading m by n part of the array B must *> contain the right-hand side matrix B, and on exit is *> overwritten by the solution matrix X. *> \endverbatim *> *> \param[in] LDB *> \verbatim *> LDB is INTEGER *> On entry, LDB specifies the first dimension of B as declared *> in the calling (sub) program. LDB must be at least *> max( 1, m ). *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup trsm * *> \par Further Details: * ===================== *> *> \verbatim *> *> Level 3 Blas routine. *> *> -- Written on 8-February-1989. *> Jack Dongarra, Argonne National Laboratory. *> Iain Duff, AERE Harwell. *> Jeremy Du Croz, Numerical Algorithms Group Ltd. *> Sven Hammarling, Numerical Algorithms Group Ltd. *> \endverbatim *> * ===================================================================== SUBROUTINE CTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB) * * -- Reference BLAS level3 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. COMPLEX ALPHA INTEGER LDA,LDB,M,N CHARACTER DIAG,SIDE,TRANSA,UPLO * .. * .. Array Arguments .. COMPLEX A(LDA,*),B(LDB,*) * .. * * ===================================================================== * * .. External Functions .. LOGICAL LSAME EXTERNAL LSAME * .. * .. External Subroutines .. EXTERNAL XERBLA * .. * .. Intrinsic Functions .. INTRINSIC CONJG,MAX * .. * .. Local Scalars .. COMPLEX TEMP INTEGER I,INFO,J,K,NROWA LOGICAL LSIDE,NOCONJ,NOUNIT,UPPER * .. * .. Parameters .. COMPLEX ONE PARAMETER (ONE= (1.0E+0,0.0E+0)) COMPLEX ZERO PARAMETER (ZERO= (0.0E+0,0.0E+0)) * .. * * Test the input parameters. * LSIDE = LSAME(SIDE,'L') IF (LSIDE) THEN NROWA = M ELSE NROWA = N END IF NOCONJ = LSAME(TRANSA,'T') NOUNIT = LSAME(DIAG,'N') UPPER = LSAME(UPLO,'U') * INFO = 0 IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN INFO = 1 ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN INFO = 2 ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND. + (.NOT.LSAME(TRANSA,'T')) .AND. + (.NOT.LSAME(TRANSA,'C'))) THEN INFO = 3 ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. + (.NOT.LSAME(DIAG,'N'))) THEN INFO = 4 ELSE IF (M.LT.0) THEN INFO = 5 ELSE IF (N.LT.0) THEN INFO = 6 ELSE IF (LDA.LT.MAX(1,NROWA)) THEN INFO = 9 ELSE IF (LDB.LT.MAX(1,M)) THEN INFO = 11 END IF IF (INFO.NE.0) THEN CALL XERBLA('CTRSM ',INFO) RETURN END IF * * Quick return if possible. * IF (M.EQ.0 .OR. N.EQ.0) RETURN * * And when alpha.eq.zero. * IF (ALPHA.EQ.ZERO) THEN DO 20 J = 1,N DO 10 I = 1,M B(I,J) = ZERO 10 CONTINUE 20 CONTINUE RETURN END IF * * Start the operations. * IF (LSIDE) THEN IF (LSAME(TRANSA,'N')) THEN * * Form B := alpha*inv( A )*B. * IF (UPPER) THEN DO 60 J = 1,N IF (ALPHA.NE.ONE) THEN DO 30 I = 1,M B(I,J) = ALPHA*B(I,J) 30 CONTINUE END IF DO 50 K = M,1,-1 IF (B(K,J).NE.ZERO) THEN IF (NOUNIT) B(K,J) = B(K,J)/A(K,K) DO 40 I = 1,K - 1 B(I,J) = B(I,J) - B(K,J)*A(I,K) 40 CONTINUE END IF 50 CONTINUE 60 CONTINUE ELSE DO 100 J = 1,N IF (ALPHA.NE.ONE) THEN DO 70 I = 1,M B(I,J) = ALPHA*B(I,J) 70 CONTINUE END IF DO 90 K = 1,M IF (B(K,J).NE.ZERO) THEN IF (NOUNIT) B(K,J) = B(K,J)/A(K,K) DO 80 I = K + 1,M B(I,J) = B(I,J) - B(K,J)*A(I,K) 80 CONTINUE END IF 90 CONTINUE 100 CONTINUE END IF ELSE * * Form B := alpha*inv( A**T )*B * or B := alpha*inv( A**H )*B. * IF (UPPER) THEN DO 140 J = 1,N DO 130 I = 1,M TEMP = ALPHA*B(I,J) IF (NOCONJ) THEN DO 110 K = 1,I - 1 TEMP = TEMP - A(K,I)*B(K,J) 110 CONTINUE IF (NOUNIT) TEMP = TEMP/A(I,I) ELSE DO 120 K = 1,I - 1 TEMP = TEMP - CONJG(A(K,I))*B(K,J) 120 CONTINUE IF (NOUNIT) TEMP = TEMP/CONJG(A(I,I)) END IF B(I,J) = TEMP 130 CONTINUE 140 CONTINUE ELSE DO 180 J = 1,N DO 170 I = M,1,-1 TEMP = ALPHA*B(I,J) IF (NOCONJ) THEN DO 150 K = I + 1,M TEMP = TEMP - A(K,I)*B(K,J) 150 CONTINUE IF (NOUNIT) TEMP = TEMP/A(I,I) ELSE DO 160 K = I + 1,M TEMP = TEMP - CONJG(A(K,I))*B(K,J) 160 CONTINUE IF (NOUNIT) TEMP = TEMP/CONJG(A(I,I)) END IF B(I,J) = TEMP 170 CONTINUE 180 CONTINUE END IF END IF ELSE IF (LSAME(TRANSA,'N')) THEN * * Form B := alpha*B*inv( A ). * IF (UPPER) THEN DO 230 J = 1,N IF (ALPHA.NE.ONE) THEN DO 190 I = 1,M B(I,J) = ALPHA*B(I,J) 190 CONTINUE END IF DO 210 K = 1,J - 1 IF (A(K,J).NE.ZERO) THEN DO 200 I = 1,M B(I,J) = B(I,J) - A(K,J)*B(I,K) 200 CONTINUE END IF 210 CONTINUE IF (NOUNIT) THEN TEMP = ONE/A(J,J) DO 220 I = 1,M B(I,J) = TEMP*B(I,J) 220 CONTINUE END IF 230 CONTINUE ELSE DO 280 J = N,1,-1 IF (ALPHA.NE.ONE) THEN DO 240 I = 1,M B(I,J) = ALPHA*B(I,J) 240 CONTINUE END IF DO 260 K = J + 1,N IF (A(K,J).NE.ZERO) THEN DO 250 I = 1,M B(I,J) = B(I,J) - A(K,J)*B(I,K) 250 CONTINUE END IF 260 CONTINUE IF (NOUNIT) THEN TEMP = ONE/A(J,J) DO 270 I = 1,M B(I,J) = TEMP*B(I,J) 270 CONTINUE END IF 280 CONTINUE END IF ELSE * * Form B := alpha*B*inv( A**T ) * or B := alpha*B*inv( A**H ). * IF (UPPER) THEN DO 330 K = N,1,-1 IF (NOUNIT) THEN IF (NOCONJ) THEN TEMP = ONE/A(K,K) ELSE TEMP = ONE/CONJG(A(K,K)) END IF DO 290 I = 1,M B(I,K) = TEMP*B(I,K) 290 CONTINUE END IF DO 310 J = 1,K - 1 IF (A(J,K).NE.ZERO) THEN IF (NOCONJ) THEN TEMP = A(J,K) ELSE TEMP = CONJG(A(J,K)) END IF DO 300 I = 1,M B(I,J) = B(I,J) - TEMP*B(I,K) 300 CONTINUE END IF 310 CONTINUE IF (ALPHA.NE.ONE) THEN DO 320 I = 1,M B(I,K) = ALPHA*B(I,K) 320 CONTINUE END IF 330 CONTINUE ELSE DO 380 K = 1,N IF (NOUNIT) THEN IF (NOCONJ) THEN TEMP = ONE/A(K,K) ELSE TEMP = ONE/CONJG(A(K,K)) END IF DO 340 I = 1,M B(I,K) = TEMP*B(I,K) 340 CONTINUE END IF DO 360 J = K + 1,N IF (A(J,K).NE.ZERO) THEN IF (NOCONJ) THEN TEMP = A(J,K) ELSE TEMP = CONJG(A(J,K)) END IF DO 350 I = 1,M B(I,J) = B(I,J) - TEMP*B(I,K) 350 CONTINUE END IF 360 CONTINUE IF (ALPHA.NE.ONE) THEN DO 370 I = 1,M B(I,K) = ALPHA*B(I,K) 370 CONTINUE END IF 380 CONTINUE END IF END IF END IF * RETURN * * End of CTRSM * END *> \brief \b DCABS1 * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * DOUBLE PRECISION FUNCTION DCABS1(Z) * * .. Scalar Arguments .. * COMPLEX*16 Z * .. * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> DCABS1 computes |Re(.)| + |Im(.)| of a double complex number *> \endverbatim * * Arguments: * ========== * *> \param[in] Z *> \verbatim *> Z is COMPLEX*16 *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup abs1 * * ===================================================================== DOUBLE PRECISION FUNCTION DCABS1(Z) * * -- Reference BLAS level1 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. COMPLEX*16 Z * .. * .. * ===================================================================== * * .. Intrinsic Functions .. INTRINSIC ABS,DBLE,DIMAG * DCABS1 = ABS(DBLE(Z)) + ABS(DIMAG(Z)) RETURN * * End of DCABS1 * END *> \brief \b DISNAN tests input for NaN. * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download DISNAN + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * LOGICAL FUNCTION DISNAN( DIN ) * * .. Scalar Arguments .. * DOUBLE PRECISION, INTENT(IN) :: DIN * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> DISNAN returns .TRUE. if its argument is NaN, and .FALSE. *> otherwise. To be replaced by the Fortran 2003 intrinsic in the *> future. *> \endverbatim * * Arguments: * ========== * *> \param[in] DIN *> \verbatim *> DIN is DOUBLE PRECISION *> Input to test for NaN. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup isnan * * ===================================================================== LOGICAL FUNCTION DISNAN( DIN ) * * -- LAPACK auxiliary routine -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. DOUBLE PRECISION, INTENT(IN) :: DIN * .. * * ===================================================================== * * .. External Functions .. LOGICAL DLAISNAN EXTERNAL DLAISNAN * .. * .. Executable Statements .. DISNAN = DLAISNAN(DIN,DIN) RETURN END *> \brief \b DLAISNAN tests input for NaN by comparing two arguments for inequality. * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download DLAISNAN + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * LOGICAL FUNCTION DLAISNAN( DIN1, DIN2 ) * * .. Scalar Arguments .. * DOUBLE PRECISION, INTENT(IN) :: DIN1, DIN2 * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> This routine is not for general use. It exists solely to avoid *> over-optimization in DISNAN. *> *> DLAISNAN checks for NaNs by comparing its two arguments for *> inequality. NaN is the only floating-point value where NaN != NaN *> returns .TRUE. To check for NaNs, pass the same variable as both *> arguments. *> *> A compiler must assume that the two arguments are *> not the same variable, and the test will not be optimized away. *> Interprocedural or whole-program optimization may delete this *> test. The ISNAN functions will be replaced by the correct *> Fortran 03 intrinsic once the intrinsic is widely available. *> \endverbatim * * Arguments: * ========== * *> \param[in] DIN1 *> \verbatim *> DIN1 is DOUBLE PRECISION *> \endverbatim *> *> \param[in] DIN2 *> \verbatim *> DIN2 is DOUBLE PRECISION *> Two numbers to compare for inequality. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup laisnan * * ===================================================================== LOGICAL FUNCTION DLAISNAN( DIN1, DIN2 ) * * -- LAPACK auxiliary routine -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. DOUBLE PRECISION, INTENT(IN) :: DIN1, DIN2 * .. * * ===================================================================== * * .. Executable Statements .. DLAISNAN = (DIN1.NE.DIN2) RETURN END *> \brief \b ICAMAX * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * INTEGER FUNCTION ICAMAX(N,CX,INCX) * * .. Scalar Arguments .. * INTEGER INCX,N * .. * .. Array Arguments .. * COMPLEX CX(*) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ICAMAX finds the index of the first element having maximum |Re(.)| + |Im(.)| *> \endverbatim * * Arguments: * ========== * *> \param[in] N *> \verbatim *> N is INTEGER *> number of elements in input vector(s) *> \endverbatim *> *> \param[in] CX *> \verbatim *> CX is COMPLEX array, dimension ( 1 + ( N - 1 )*abs( INCX ) ) *> \endverbatim *> *> \param[in] INCX *> \verbatim *> INCX is INTEGER *> storage spacing between elements of CX *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup iamax * *> \par Further Details: * ===================== *> *> \verbatim *> *> jack dongarra, linpack, 3/11/78. *> modified 3/93 to return if incx .le. 0. *> modified 12/3/93, array(1) declarations changed to array(*) *> \endverbatim *> * ===================================================================== INTEGER FUNCTION ICAMAX(N,CX,INCX) * * -- Reference BLAS level1 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. INTEGER INCX,N * .. * .. Array Arguments .. COMPLEX CX(*) * .. * * ===================================================================== * * .. Local Scalars .. REAL SMAX INTEGER I,IX * .. * .. External Functions .. REAL SCABS1 EXTERNAL SCABS1 * .. ICAMAX = 0 IF (N.LT.1 .OR. INCX.LE.0) RETURN ICAMAX = 1 IF (N.EQ.1) RETURN IF (INCX.EQ.1) THEN * * code for increment equal to 1 * SMAX = SCABS1(CX(1)) DO I = 2,N IF (SCABS1(CX(I)).GT.SMAX) THEN ICAMAX = I SMAX = SCABS1(CX(I)) END IF END DO ELSE * * code for increment not equal to 1 * IX = 1 SMAX = SCABS1(CX(1)) IX = IX + INCX DO I = 2,N IF (SCABS1(CX(IX)).GT.SMAX) THEN ICAMAX = I SMAX = SCABS1(CX(IX)) END IF IX = IX + INCX END DO END IF RETURN * * End of ICAMAX * END *> \brief \b IEEECK * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download IEEECK + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * INTEGER FUNCTION IEEECK( ISPEC, ZERO, ONE ) * * .. Scalar Arguments .. * INTEGER ISPEC * REAL ONE, ZERO * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> IEEECK is called from the ILAENV to verify that Infinity and *> possibly NaN arithmetic is safe (i.e. will not trap). *> \endverbatim * * Arguments: * ========== * *> \param[in] ISPEC *> \verbatim *> ISPEC is INTEGER *> Specifies whether to test just for infinity arithmetic *> or whether to test for infinity and NaN arithmetic. *> = 0: Verify infinity arithmetic only. *> = 1: Verify infinity and NaN arithmetic. *> \endverbatim *> *> \param[in] ZERO *> \verbatim *> ZERO is REAL *> Must contain the value 0.0 *> This is passed to prevent the compiler from optimizing *> away this code. *> \endverbatim *> *> \param[in] ONE *> \verbatim *> ONE is REAL *> Must contain the value 1.0 *> This is passed to prevent the compiler from optimizing *> away this code. *> *> RETURN VALUE: INTEGER *> = 0: Arithmetic failed to produce the correct answers *> = 1: Arithmetic produced the correct answers *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup ieeeck * * ===================================================================== INTEGER FUNCTION IEEECK( ISPEC, ZERO, ONE ) * * -- LAPACK auxiliary routine -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. INTEGER ISPEC REAL ONE, ZERO * .. * * ===================================================================== * * .. Local Scalars .. REAL NAN1, NAN2, NAN3, NAN4, NAN5, NAN6, NEGINF, $ NEGZRO, NEWZRO, POSINF * .. * .. Executable Statements .. IEEECK = 1 * POSINF = ONE / ZERO IF( POSINF.LE.ONE ) THEN IEEECK = 0 RETURN END IF * NEGINF = -ONE / ZERO IF( NEGINF.GE.ZERO ) THEN IEEECK = 0 RETURN END IF * NEGZRO = ONE / ( NEGINF+ONE ) IF( NEGZRO.NE.ZERO ) THEN IEEECK = 0 RETURN END IF * NEGINF = ONE / NEGZRO IF( NEGINF.GE.ZERO ) THEN IEEECK = 0 RETURN END IF * NEWZRO = NEGZRO + ZERO IF( NEWZRO.NE.ZERO ) THEN IEEECK = 0 RETURN END IF * POSINF = ONE / NEWZRO IF( POSINF.LE.ONE ) THEN IEEECK = 0 RETURN END IF * NEGINF = NEGINF*POSINF IF( NEGINF.GE.ZERO ) THEN IEEECK = 0 RETURN END IF * POSINF = POSINF*POSINF IF( POSINF.LE.ONE ) THEN IEEECK = 0 RETURN END IF * * * * * Return if we were only asked to check infinity arithmetic * IF( ISPEC.EQ.0 ) $ RETURN * NAN1 = POSINF + NEGINF * NAN2 = POSINF / NEGINF * NAN3 = POSINF / POSINF * NAN4 = POSINF*ZERO * NAN5 = NEGINF*NEGZRO * NAN6 = NAN5*ZERO * IF( NAN1.EQ.NAN1 ) THEN IEEECK = 0 RETURN END IF * IF( NAN2.EQ.NAN2 ) THEN IEEECK = 0 RETURN END IF * IF( NAN3.EQ.NAN3 ) THEN IEEECK = 0 RETURN END IF * IF( NAN4.EQ.NAN4 ) THEN IEEECK = 0 RETURN END IF * IF( NAN5.EQ.NAN5 ) THEN IEEECK = 0 RETURN END IF * IF( NAN6.EQ.NAN6 ) THEN IEEECK = 0 RETURN END IF * RETURN END *> \brief \b ILAENV * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download ILAENV + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * INTEGER FUNCTION ILAENV( ISPEC, NAME, OPTS, N1, N2, N3, N4 ) * * .. Scalar Arguments .. * CHARACTER*( * ) NAME, OPTS * INTEGER ISPEC, N1, N2, N3, N4 * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ILAENV is called from the LAPACK routines to choose problem-dependent *> parameters for the local environment. See ISPEC for a description of *> the parameters. *> *> ILAENV returns an INTEGER *> if ILAENV >= 0: ILAENV returns the value of the parameter specified by ISPEC *> if ILAENV < 0: if ILAENV = -k, the k-th argument had an illegal value. *> *> This version provides a set of parameters which should give good, *> but not optimal, performance on many of the currently available *> computers. Users are encouraged to modify this subroutine to set *> the tuning parameters for their particular machine using the option *> and problem size information in the arguments. *> *> This routine will not function correctly if it is converted to all *> lower case. Converting it to all upper case is allowed. *> \endverbatim * * Arguments: * ========== * *> \param[in] ISPEC *> \verbatim *> ISPEC is INTEGER *> Specifies the parameter to be returned as the value of *> ILAENV. *> = 1: the optimal blocksize; if this value is 1, an unblocked *> algorithm will give the best performance. *> = 2: the minimum block size for which the block routine *> should be used; if the usable block size is less than *> this value, an unblocked routine should be used. *> = 3: the crossover point (in a block routine, for N less *> than this value, an unblocked routine should be used) *> = 4: the number of shifts, used in the nonsymmetric *> eigenvalue routines (DEPRECATED) *> = 5: the minimum column dimension for blocking to be used; *> rectangular blocks must have dimension at least k by m, *> where k is given by ILAENV(2,...) and m by ILAENV(5,...) *> = 6: the crossover point for the SVD (when reducing an m by n *> matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds *> this value, a QR factorization is used first to reduce *> the matrix to a triangular form.) *> = 7: the number of processors *> = 8: the crossover point for the multishift QR method *> for nonsymmetric eigenvalue problems (DEPRECATED) *> = 9: maximum size of the subproblems at the bottom of the *> computation tree in the divide-and-conquer algorithm *> (used by xGELSD and xGESDD) *> =10: ieee infinity and NaN arithmetic can be trusted not to trap *> =11: infinity arithmetic can be trusted not to trap *> 12 <= ISPEC <= 17: *> xHSEQR or related subroutines, *> see IPARMQ for detailed explanation *> \endverbatim *> *> \param[in] NAME *> \verbatim *> NAME is CHARACTER*(*) *> The name of the calling subroutine, in either upper case or *> lower case. *> \endverbatim *> *> \param[in] OPTS *> \verbatim *> OPTS is CHARACTER*(*) *> The character options to the subroutine NAME, concatenated *> into a single character string. For example, UPLO = 'U', *> TRANS = 'T', and DIAG = 'N' for a triangular routine would *> be specified as OPTS = 'UTN'. *> \endverbatim *> *> \param[in] N1 *> \verbatim *> N1 is INTEGER *> \endverbatim *> *> \param[in] N2 *> \verbatim *> N2 is INTEGER *> \endverbatim *> *> \param[in] N3 *> \verbatim *> N3 is INTEGER *> \endverbatim *> *> \param[in] N4 *> \verbatim *> N4 is INTEGER *> Problem dimensions for the subroutine NAME; these may not all *> be required. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup ilaenv * *> \par Further Details: * ===================== *> *> \verbatim *> *> The following conventions have been used when calling ILAENV from the *> LAPACK routines: *> 1) OPTS is a concatenation of all of the character options to *> subroutine NAME, in the same order that they appear in the *> argument list for NAME, even if they are not used in determining *> the value of the parameter specified by ISPEC. *> 2) The problem dimensions N1, N2, N3, N4 are specified in the order *> that they appear in the argument list for NAME. N1 is used *> first, N2 second, and so on, and unused problem dimensions are *> passed a value of -1. *> 3) The parameter value returned by ILAENV is checked for validity in *> the calling subroutine. For example, ILAENV is used to retrieve *> the optimal blocksize for STRTRI as follows: *> *> NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 ) *> IF( NB.LE.1 ) NB = MAX( 1, N ) *> \endverbatim *> * ===================================================================== INTEGER FUNCTION ILAENV( ISPEC, NAME, OPTS, N1, N2, N3, N4 ) * * -- LAPACK auxiliary routine -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. CHARACTER*( * ) NAME, OPTS INTEGER ISPEC, N1, N2, N3, N4 * .. * * ===================================================================== * * .. Local Scalars .. INTEGER I, IC, IZ, NB, NBMIN, NX LOGICAL CNAME, SNAME, TWOSTAGE CHARACTER C1*1, C2*2, C4*2, C3*3, SUBNAM*16 * .. * .. Intrinsic Functions .. INTRINSIC CHAR, ICHAR, INT, MIN, REAL * .. * .. External Functions .. INTEGER IEEECK, IPARMQ, IPARAM2STAGE EXTERNAL IEEECK, IPARMQ, IPARAM2STAGE * .. * .. Executable Statements .. * GO TO ( 10, 10, 10, 80, 90, 100, 110, 120, $ 130, 140, 150, 160, 160, 160, 160, 160, 160)ISPEC * * Invalid value for ISPEC * ILAENV = -1 RETURN * 10 CONTINUE * * Convert NAME to upper case if the first character is lower case. * ILAENV = 1 SUBNAM = NAME IC = ICHAR( SUBNAM( 1: 1 ) ) IZ = ICHAR( 'Z' ) IF( IZ.EQ.90 .OR. IZ.EQ.122 ) THEN * * ASCII character set * IF( IC.GE.97 .AND. IC.LE.122 ) THEN SUBNAM( 1: 1 ) = CHAR( IC-32 ) DO 20 I = 2, 6 IC = ICHAR( SUBNAM( I: I ) ) IF( IC.GE.97 .AND. IC.LE.122 ) $ SUBNAM( I: I ) = CHAR( IC-32 ) 20 CONTINUE END IF * ELSE IF( IZ.EQ.233 .OR. IZ.EQ.169 ) THEN * * EBCDIC character set * IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR. $ ( IC.GE.145 .AND. IC.LE.153 ) .OR. $ ( IC.GE.162 .AND. IC.LE.169 ) ) THEN SUBNAM( 1: 1 ) = CHAR( IC+64 ) DO 30 I = 2, 6 IC = ICHAR( SUBNAM( I: I ) ) IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR. $ ( IC.GE.145 .AND. IC.LE.153 ) .OR. $ ( IC.GE.162 .AND. IC.LE.169 ) )SUBNAM( I: $ I ) = CHAR( IC+64 ) 30 CONTINUE END IF * ELSE IF( IZ.EQ.218 .OR. IZ.EQ.250 ) THEN * * Prime machines: ASCII+128 * IF( IC.GE.225 .AND. IC.LE.250 ) THEN SUBNAM( 1: 1 ) = CHAR( IC-32 ) DO 40 I = 2, 6 IC = ICHAR( SUBNAM( I: I ) ) IF( IC.GE.225 .AND. IC.LE.250 ) $ SUBNAM( I: I ) = CHAR( IC-32 ) 40 CONTINUE END IF END IF * C1 = SUBNAM( 1: 1 ) SNAME = C1.EQ.'S' .OR. C1.EQ.'D' CNAME = C1.EQ.'C' .OR. C1.EQ.'Z' IF( .NOT.( CNAME .OR. SNAME ) ) $ RETURN C2 = SUBNAM( 2: 3 ) C3 = SUBNAM( 4: 6 ) C4 = C3( 2: 3 ) TWOSTAGE = LEN( SUBNAM ).GE.11 $ .AND. SUBNAM( 11: 11 ).EQ.'2' * GO TO ( 50, 60, 70 )ISPEC * 50 CONTINUE * * ISPEC = 1: block size * * In these examples, separate code is provided for setting NB for * real and complex. We assume that NB will take the same value in * single or double precision. * NB = 1 * IF( SUBNAM(2:6).EQ.'LAORH' ) THEN * * This is for *LAORHR_GETRFNP routine * IF( SNAME ) THEN NB = 32 ELSE NB = 32 END IF ELSE IF( C2.EQ.'GE' ) THEN IF( C3.EQ.'TRF' ) THEN IF( SNAME ) THEN NB = 64 ELSE NB = 64 END IF ELSE IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. $ C3.EQ.'QLF' ) THEN IF( SNAME ) THEN NB = 32 ELSE NB = 32 END IF ELSE IF( C3.EQ.'QR ') THEN IF( N3 .EQ. 1) THEN IF( SNAME ) THEN * M*N IF ((N1*N2.LE.131072).OR.(N1.LE.8192)) THEN NB = N1 ELSE NB = 32768/N2 END IF ELSE IF ((N1*N2.LE.131072).OR.(N1.LE.8192)) THEN NB = N1 ELSE NB = 32768/N2 END IF END IF ELSE IF( SNAME ) THEN NB = 1 ELSE NB = 1 END IF END IF ELSE IF( C3.EQ.'LQ ') THEN IF( N3 .EQ. 2) THEN IF( SNAME ) THEN * M*N IF ((N1*N2.LE.131072).OR.(N1.LE.8192)) THEN NB = N1 ELSE NB = 32768/N2 END IF ELSE IF ((N1*N2.LE.131072).OR.(N1.LE.8192)) THEN NB = N1 ELSE NB = 32768/N2 END IF END IF ELSE IF( SNAME ) THEN NB = 1 ELSE NB = 1 END IF END IF ELSE IF( C3.EQ.'HRD' ) THEN IF( SNAME ) THEN NB = 32 ELSE NB = 32 END IF ELSE IF( C3.EQ.'BRD' ) THEN IF( SNAME ) THEN NB = 32 ELSE NB = 32 END IF ELSE IF( C3.EQ.'TRI' ) THEN IF( SNAME ) THEN NB = 64 ELSE NB = 64 END IF ELSE IF( SUBNAM( 4: 7 ).EQ.'QP3RK' ) THEN IF( SNAME ) THEN NB = 32 ELSE NB = 32 END IF END IF ELSE IF( C2.EQ.'PO' ) THEN IF( C3.EQ.'TRF' ) THEN IF( SNAME ) THEN NB = 64 ELSE NB = 64 END IF END IF ELSE IF( C2.EQ.'SY' ) THEN IF( C3.EQ.'TRF' ) THEN IF( SNAME ) THEN IF( TWOSTAGE ) THEN NB = 192 ELSE NB = 64 END IF ELSE IF( TWOSTAGE ) THEN NB = 192 ELSE NB = 64 END IF END IF ELSE IF( SNAME .AND. C3.EQ.'TRD' ) THEN NB = 32 ELSE IF( SNAME .AND. C3.EQ.'GST' ) THEN NB = 64 END IF ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN IF( C3.EQ.'TRF' ) THEN IF( TWOSTAGE ) THEN NB = 192 ELSE NB = 64 END IF ELSE IF( C3.EQ.'TRD' ) THEN NB = 32 ELSE IF( C3.EQ.'GST' ) THEN NB = 64 END IF ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN IF( C3( 1: 1 ).EQ.'G' ) THEN IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) $ THEN NB = 32 END IF ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) $ THEN NB = 32 END IF END IF ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN IF( C3( 1: 1 ).EQ.'G' ) THEN IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) $ THEN NB = 32 END IF ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) $ THEN NB = 32 END IF END IF ELSE IF( C2.EQ.'GB' ) THEN IF( C3.EQ.'TRF' ) THEN IF( SNAME ) THEN IF( N4.LE.64 ) THEN NB = 1 ELSE NB = 32 END IF ELSE IF( N4.LE.64 ) THEN NB = 1 ELSE NB = 32 END IF END IF END IF ELSE IF( C2.EQ.'PB' ) THEN IF( C3.EQ.'TRF' ) THEN IF( SNAME ) THEN IF( N2.LE.64 ) THEN NB = 1 ELSE NB = 32 END IF ELSE IF( N2.LE.64 ) THEN NB = 1 ELSE NB = 32 END IF END IF END IF ELSE IF( C2.EQ.'TR' ) THEN IF( C3.EQ.'TRI' ) THEN IF( SNAME ) THEN NB = 64 ELSE NB = 64 END IF ELSE IF ( C3.EQ.'EVC' ) THEN IF( SNAME ) THEN NB = 64 ELSE NB = 64 END IF ELSE IF( C3.EQ.'SYL' ) THEN * The upper bound is to prevent overly aggressive scaling. IF( SNAME ) THEN NB = MIN( MAX( 48, INT( ( MIN( N1, N2 ) * 16 ) / 100) ), $ 240 ) ELSE NB = MIN( MAX( 24, INT( ( MIN( N1, N2 ) * 8 ) / 100) ), $ 80 ) END IF END IF ELSE IF( C2.EQ.'LA' ) THEN IF( C3.EQ.'UUM' ) THEN IF( SNAME ) THEN NB = 64 ELSE NB = 64 END IF ELSE IF( C3.EQ.'TRS' ) THEN IF( SNAME ) THEN NB = 32 ELSE NB = 32 END IF END IF ELSE IF( SNAME .AND. C2.EQ.'ST' ) THEN IF( C3.EQ.'EBZ' ) THEN NB = 1 END IF ELSE IF( C2.EQ.'GG' ) THEN NB = 32 IF( C3.EQ.'HD3' ) THEN IF( SNAME ) THEN NB = 32 ELSE NB = 32 END IF END IF END IF ILAENV = NB RETURN * 60 CONTINUE * * ISPEC = 2: minimum block size * NBMIN = 2 IF( C2.EQ.'GE' ) THEN IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. C3.EQ. $ 'QLF' ) THEN IF( SNAME ) THEN NBMIN = 2 ELSE NBMIN = 2 END IF ELSE IF( C3.EQ.'HRD' ) THEN IF( SNAME ) THEN NBMIN = 2 ELSE NBMIN = 2 END IF ELSE IF( C3.EQ.'BRD' ) THEN IF( SNAME ) THEN NBMIN = 2 ELSE NBMIN = 2 END IF ELSE IF( C3.EQ.'TRI' ) THEN IF( SNAME ) THEN NBMIN = 2 ELSE NBMIN = 2 END IF ELSE IF( SUBNAM( 4: 7 ).EQ.'QP3RK' ) THEN IF( SNAME ) THEN NBMIN = 2 ELSE NBMIN = 2 END IF END IF ELSE IF( C2.EQ.'SY' ) THEN IF( C3.EQ.'TRF' ) THEN IF( SNAME ) THEN NBMIN = 8 ELSE NBMIN = 8 END IF ELSE IF( SNAME .AND. C3.EQ.'TRD' ) THEN NBMIN = 2 END IF ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN IF( C3.EQ.'TRD' ) THEN NBMIN = 2 END IF ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN IF( C3( 1: 1 ).EQ.'G' ) THEN IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) $ THEN NBMIN = 2 END IF ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) $ THEN NBMIN = 2 END IF END IF ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN IF( C3( 1: 1 ).EQ.'G' ) THEN IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) $ THEN NBMIN = 2 END IF ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) $ THEN NBMIN = 2 END IF END IF ELSE IF( C2.EQ.'GG' ) THEN NBMIN = 2 IF( C3.EQ.'HD3' ) THEN NBMIN = 2 END IF END IF ILAENV = NBMIN RETURN * 70 CONTINUE * * ISPEC = 3: crossover point * NX = 0 IF( C2.EQ.'GE' ) THEN IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. C3.EQ. $ 'QLF' ) THEN IF( SNAME ) THEN NX = 128 ELSE NX = 128 END IF ELSE IF( C3.EQ.'HRD' ) THEN IF( SNAME ) THEN NX = 128 ELSE NX = 128 END IF ELSE IF( C3.EQ.'BRD' ) THEN IF( SNAME ) THEN NX = 128 ELSE NX = 128 END IF ELSE IF( SUBNAM( 4: 7 ).EQ.'QP3RK' ) THEN IF( SNAME ) THEN NX = 128 ELSE NX = 128 END IF END IF ELSE IF( C2.EQ.'SY' ) THEN IF( SNAME .AND. C3.EQ.'TRD' ) THEN NX = 32 END IF ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN IF( C3.EQ.'TRD' ) THEN NX = 32 END IF ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN IF( C3( 1: 1 ).EQ.'G' ) THEN IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) $ THEN NX = 128 END IF END IF ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN IF( C3( 1: 1 ).EQ.'G' ) THEN IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) $ THEN NX = 128 END IF END IF ELSE IF( C2.EQ.'GG' ) THEN NX = 128 IF( C3.EQ.'HD3' ) THEN NX = 128 END IF END IF ILAENV = NX RETURN * 80 CONTINUE * * ISPEC = 4: number of shifts (used by xHSEQR) * ILAENV = 6 RETURN * 90 CONTINUE * * ISPEC = 5: minimum column dimension (not used) * ILAENV = 2 RETURN * 100 CONTINUE * * ISPEC = 6: crossover point for SVD (used by xGELSS and xGESVD) * ILAENV = INT( REAL( MIN( N1, N2 ) )*1.6E0 ) RETURN * 110 CONTINUE * * ISPEC = 7: number of processors (not used) * ILAENV = 1 RETURN * 120 CONTINUE * * ISPEC = 8: crossover point for multishift (used by xHSEQR) * ILAENV = 50 RETURN * 130 CONTINUE * * ISPEC = 9: maximum size of the subproblems at the bottom of the * computation tree in the divide-and-conquer algorithm * (used by xGELSD and xGESDD) * ILAENV = 25 RETURN * 140 CONTINUE * * ISPEC = 10: ieee and infinity NaN arithmetic can be trusted not to trap * * ILAENV = 0 ILAENV = 1 IF( ILAENV.EQ.1 ) THEN ILAENV = IEEECK( 1, 0.0, 1.0 ) END IF RETURN * 150 CONTINUE * * ISPEC = 11: ieee infinity arithmetic can be trusted not to trap * * ILAENV = 0 ILAENV = 1 IF( ILAENV.EQ.1 ) THEN ILAENV = IEEECK( 0, 0.0, 1.0 ) END IF RETURN * 160 CONTINUE * * 12 <= ISPEC <= 17: xHSEQR or related subroutines. * ILAENV = IPARMQ( ISPEC, NAME, OPTS, N1, N2, N3, N4 ) RETURN * * End of ILAENV * END *> \brief \b IPARMQ * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download IPARMQ + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * INTEGER FUNCTION IPARMQ( ISPEC, NAME, OPTS, N, ILO, IHI, LWORK ) * * .. Scalar Arguments .. * INTEGER IHI, ILO, ISPEC, LWORK, N * CHARACTER NAME*( * ), OPTS*( * ) * * *> \par Purpose: * ============= *> *> \verbatim *> *> This program sets problem and machine dependent parameters *> useful for xHSEQR and related subroutines for eigenvalue *> problems. It is called whenever *> IPARMQ is called with 12 <= ISPEC <= 16 *> \endverbatim * * Arguments: * ========== * *> \param[in] ISPEC *> \verbatim *> ISPEC is INTEGER *> ISPEC specifies which tunable parameter IPARMQ should *> return. *> *> ISPEC=12: (INMIN) Matrices of order nmin or less *> are sent directly to xLAHQR, the implicit *> double shift QR algorithm. NMIN must be *> at least 11. *> *> ISPEC=13: (INWIN) Size of the deflation window. *> This is best set greater than or equal to *> the number of simultaneous shifts NS. *> Larger matrices benefit from larger deflation *> windows. *> *> ISPEC=14: (INIBL) Determines when to stop nibbling and *> invest in an (expensive) multi-shift QR sweep. *> If the aggressive early deflation subroutine *> finds LD converged eigenvalues from an order *> NW deflation window and LD > (NW*NIBBLE)/100, *> then the next QR sweep is skipped and early *> deflation is applied immediately to the *> remaining active diagonal block. Setting *> IPARMQ(ISPEC=14) = 0 causes TTQRE to skip a *> multi-shift QR sweep whenever early deflation *> finds a converged eigenvalue. Setting *> IPARMQ(ISPEC=14) greater than or equal to 100 *> prevents TTQRE from skipping a multi-shift *> QR sweep. *> *> ISPEC=15: (NSHFTS) The number of simultaneous shifts in *> a multi-shift QR iteration. *> *> ISPEC=16: (IACC22) IPARMQ is set to 0, 1 or 2 with the *> following meanings. *> 0: During the multi-shift QR/QZ sweep, *> blocked eigenvalue reordering, blocked *> Hessenberg-triangular reduction, *> reflections and/or rotations are not *> accumulated when updating the *> far-from-diagonal matrix entries. *> 1: During the multi-shift QR/QZ sweep, *> blocked eigenvalue reordering, blocked *> Hessenberg-triangular reduction, *> reflections and/or rotations are *> accumulated, and matrix-matrix *> multiplication is used to update the *> far-from-diagonal matrix entries. *> 2: During the multi-shift QR/QZ sweep, *> blocked eigenvalue reordering, blocked *> Hessenberg-triangular reduction, *> reflections and/or rotations are *> accumulated, and 2-by-2 block structure *> is exploited during matrix-matrix *> multiplies. *> (If xTRMM is slower than xGEMM, then *> IPARMQ(ISPEC=16)=1 may be more efficient than *> IPARMQ(ISPEC=16)=2 despite the greater level of *> arithmetic work implied by the latter choice.) *> *> ISPEC=17: (ICOST) An estimate of the relative cost of flops *> within the near-the-diagonal shift chase compared *> to flops within the BLAS calls of a QZ sweep. *> \endverbatim *> *> \param[in] NAME *> \verbatim *> NAME is CHARACTER string *> Name of the calling subroutine *> \endverbatim *> *> \param[in] OPTS *> \verbatim *> OPTS is CHARACTER string *> This is a concatenation of the string arguments to *> TTQRE. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> N is the order of the Hessenberg matrix H. *> \endverbatim *> *> \param[in] ILO *> \verbatim *> ILO is INTEGER *> \endverbatim *> *> \param[in] IHI *> \verbatim *> IHI is INTEGER *> It is assumed that H is already upper triangular *> in rows and columns 1:ILO-1 and IHI+1:N. *> \endverbatim *> *> \param[in] LWORK *> \verbatim *> LWORK is INTEGER *> The amount of workspace available. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup iparmq * *> \par Further Details: * ===================== *> *> \verbatim *> *> Little is known about how best to choose these parameters. *> It is possible to use different values of the parameters *> for each of CHSEQR, DHSEQR, SHSEQR and ZHSEQR. *> *> It is probably best to choose different parameters for *> different matrices and different parameters at different *> times during the iteration, but this has not been *> implemented --- yet. *> *> *> The best choices of most of the parameters depend *> in an ill-understood way on the relative execution *> rate of xLAQR3 and xLAQR5 and on the nature of each *> particular eigenvalue problem. Experiment may be the *> only practical way to determine which choices are most *> effective. *> *> Following is a list of default values supplied by IPARMQ. *> These defaults may be adjusted in order to attain better *> performance in any particular computational environment. *> *> IPARMQ(ISPEC=12) The xLAHQR vs xLAQR0 crossover point. *> Default: 75. (Must be at least 11.) *> *> IPARMQ(ISPEC=13) Recommended deflation window size. *> This depends on ILO, IHI and NS, the *> number of simultaneous shifts returned *> by IPARMQ(ISPEC=15). The default for *> (IHI-ILO+1) <= 500 is NS. The default *> for (IHI-ILO+1) > 500 is 3*NS/2. *> *> IPARMQ(ISPEC=14) Nibble crossover point. Default: 14. *> *> IPARMQ(ISPEC=15) Number of simultaneous shifts, NS. *> a multi-shift QR iteration. *> *> If IHI-ILO+1 is ... *> *> greater than ...but less ... the *> or equal to ... than default is *> *> 0 30 NS = 2+ *> 30 60 NS = 4+ *> 60 150 NS = 10 *> 150 590 NS = ** *> 590 3000 NS = 64 *> 3000 6000 NS = 128 *> 6000 infinity NS = 256 *> *> (+) By default matrices of this order are *> passed to the implicit double shift routine *> xLAHQR. See IPARMQ(ISPEC=12) above. These *> values of NS are used only in case of a rare *> xLAHQR failure. *> *> (**) The asterisks (**) indicate an ad-hoc *> function increasing from 10 to 64. *> *> IPARMQ(ISPEC=16) Select structured matrix multiply. *> (See ISPEC=16 above for details.) *> Default: 3. *> *> IPARMQ(ISPEC=17) Relative cost heuristic for blocksize selection. *> Expressed as a percentage. *> Default: 10. *> \endverbatim *> * ===================================================================== INTEGER FUNCTION IPARMQ( ISPEC, NAME, OPTS, N, ILO, IHI, $ LWORK ) * * -- LAPACK auxiliary routine -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. INTEGER IHI, ILO, ISPEC, LWORK, N CHARACTER NAME*( * ), OPTS*( * ) * * ================================================================ * .. Parameters .. INTEGER INMIN, INWIN, INIBL, ISHFTS, IACC22, ICOST PARAMETER ( INMIN = 12, INWIN = 13, INIBL = 14, $ ISHFTS = 15, IACC22 = 16, ICOST = 17 ) INTEGER NMIN, K22MIN, KACMIN, NIBBLE, KNWSWP, RCOST PARAMETER ( NMIN = 75, K22MIN = 14, KACMIN = 14, $ NIBBLE = 14, KNWSWP = 500, RCOST = 10 ) REAL TWO PARAMETER ( TWO = 2.0 ) * .. * .. Local Scalars .. INTEGER NH, NS INTEGER I, IC, IZ CHARACTER SUBNAM*6 * .. * .. Intrinsic Functions .. INTRINSIC LOG, MAX, MOD, NINT, REAL * .. * .. Executable Statements .. IF( ( ISPEC.EQ.ISHFTS ) .OR. ( ISPEC.EQ.INWIN ) .OR. $ ( ISPEC.EQ.IACC22 ) ) THEN * * ==== Set the number simultaneous shifts ==== * NH = IHI - ILO + 1 NS = 2 IF( NH.GE.30 ) $ NS = 4 IF( NH.GE.60 ) $ NS = 10 IF( NH.GE.150 ) $ NS = MAX( 10, NH / NINT( LOG( REAL( NH ) ) / LOG( TWO ) ) ) IF( NH.GE.590 ) $ NS = 64 IF( NH.GE.3000 ) $ NS = 128 IF( NH.GE.6000 ) $ NS = 256 NS = MAX( 2, NS-MOD( NS, 2 ) ) END IF * IF( ISPEC.EQ.INMIN ) THEN * * * ===== Matrices of order smaller than NMIN get sent * . to xLAHQR, the classic double shift algorithm. * . This must be at least 11. ==== * IPARMQ = NMIN * ELSE IF( ISPEC.EQ.INIBL ) THEN * * ==== INIBL: skip a multi-shift qr iteration and * . whenever aggressive early deflation finds * . at least (NIBBLE*(window size)/100) deflations. ==== * IPARMQ = NIBBLE * ELSE IF( ISPEC.EQ.ISHFTS ) THEN * * ==== NSHFTS: The number of simultaneous shifts ===== * IPARMQ = NS * ELSE IF( ISPEC.EQ.INWIN ) THEN * * ==== NW: deflation window size. ==== * IF( NH.LE.KNWSWP ) THEN IPARMQ = NS ELSE IPARMQ = 3*NS / 2 END IF * ELSE IF( ISPEC.EQ.IACC22 ) THEN * * ==== IACC22: Whether to accumulate reflections * . before updating the far-from-diagonal elements * . and whether to use 2-by-2 block structure while * . doing it. A small amount of work could be saved * . by making this choice dependent also upon the * . NH=IHI-ILO+1. * * * Convert NAME to upper case if the first character is lower case. * IPARMQ = 0 SUBNAM = NAME IC = ICHAR( SUBNAM( 1: 1 ) ) IZ = ICHAR( 'Z' ) IF( IZ.EQ.90 .OR. IZ.EQ.122 ) THEN * * ASCII character set * IF( IC.GE.97 .AND. IC.LE.122 ) THEN SUBNAM( 1: 1 ) = CHAR( IC-32 ) DO I = 2, 6 IC = ICHAR( SUBNAM( I: I ) ) IF( IC.GE.97 .AND. IC.LE.122 ) $ SUBNAM( I: I ) = CHAR( IC-32 ) END DO END IF * ELSE IF( IZ.EQ.233 .OR. IZ.EQ.169 ) THEN * * EBCDIC character set * IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR. $ ( IC.GE.145 .AND. IC.LE.153 ) .OR. $ ( IC.GE.162 .AND. IC.LE.169 ) ) THEN SUBNAM( 1: 1 ) = CHAR( IC+64 ) DO I = 2, 6 IC = ICHAR( SUBNAM( I: I ) ) IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR. $ ( IC.GE.145 .AND. IC.LE.153 ) .OR. $ ( IC.GE.162 .AND. IC.LE.169 ) )SUBNAM( I: $ I ) = CHAR( IC+64 ) END DO END IF * ELSE IF( IZ.EQ.218 .OR. IZ.EQ.250 ) THEN * * Prime machines: ASCII+128 * IF( IC.GE.225 .AND. IC.LE.250 ) THEN SUBNAM( 1: 1 ) = CHAR( IC-32 ) DO I = 2, 6 IC = ICHAR( SUBNAM( I: I ) ) IF( IC.GE.225 .AND. IC.LE.250 ) $ SUBNAM( I: I ) = CHAR( IC-32 ) END DO END IF END IF * IF( SUBNAM( 2:6 ).EQ.'GGHRD' .OR. $ SUBNAM( 2:6 ).EQ.'GGHD3' ) THEN IPARMQ = 1 IF( NH.GE.K22MIN ) $ IPARMQ = 2 ELSE IF ( SUBNAM( 4:6 ).EQ.'EXC' ) THEN IF( NH.GE.KACMIN ) $ IPARMQ = 1 IF( NH.GE.K22MIN ) $ IPARMQ = 2 ELSE IF ( SUBNAM( 2:6 ).EQ.'HSEQR' .OR. $ SUBNAM( 2:5 ).EQ.'LAQR' ) THEN IF( NS.GE.KACMIN ) $ IPARMQ = 1 IF( NS.GE.K22MIN ) $ IPARMQ = 2 END IF * ELSE IF( ISPEC.EQ.ICOST ) THEN * * === Relative cost of near-the-diagonal chase vs * BLAS updates === * IPARMQ = RCOST ELSE * ===== invalid value of ispec ===== IPARMQ = -1 * END IF * * ==== End of IPARMQ ==== * END *> \brief \b IZAMAX * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * INTEGER FUNCTION IZAMAX(N,ZX,INCX) * * .. Scalar Arguments .. * INTEGER INCX,N * .. * .. Array Arguments .. * COMPLEX*16 ZX(*) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> IZAMAX finds the index of the first element having maximum |Re(.)| + |Im(.)| *> \endverbatim * * Arguments: * ========== * *> \param[in] N *> \verbatim *> N is INTEGER *> number of elements in input vector(s) *> \endverbatim *> *> \param[in] ZX *> \verbatim *> ZX is COMPLEX*16 array, dimension ( 1 + ( N - 1 )*abs( INCX ) ) *> \endverbatim *> *> \param[in] INCX *> \verbatim *> INCX is INTEGER *> storage spacing between elements of ZX *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup iamax * *> \par Further Details: * ===================== *> *> \verbatim *> *> jack dongarra, 1/15/85. *> modified 3/93 to return if incx .le. 0. *> modified 12/3/93, array(1) declarations changed to array(*) *> \endverbatim *> * ===================================================================== INTEGER FUNCTION IZAMAX(N,ZX,INCX) * * -- Reference BLAS level1 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. INTEGER INCX,N * .. * .. Array Arguments .. COMPLEX*16 ZX(*) * .. * * ===================================================================== * * .. Local Scalars .. DOUBLE PRECISION DMAX INTEGER I,IX * .. * .. External Functions .. DOUBLE PRECISION DCABS1 EXTERNAL DCABS1 * .. IZAMAX = 0 IF (N.LT.1 .OR. INCX.LE.0) RETURN IZAMAX = 1 IF (N.EQ.1) RETURN IF (INCX.EQ.1) THEN * * code for increment equal to 1 * DMAX = DCABS1(ZX(1)) DO I = 2,N IF (DCABS1(ZX(I)).GT.DMAX) THEN IZAMAX = I DMAX = DCABS1(ZX(I)) END IF END DO ELSE * * code for increment not equal to 1 * IX = 1 DMAX = DCABS1(ZX(1)) IX = IX + INCX DO I = 2,N IF (DCABS1(ZX(IX)).GT.DMAX) THEN IZAMAX = I DMAX = DCABS1(ZX(IX)) END IF IX = IX + INCX END DO END IF RETURN * * End of IZAMAX * END *> \brief \b LSAME * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * LOGICAL FUNCTION LSAME(CA,CB) * * .. Scalar Arguments .. * CHARACTER CA,CB * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> LSAME returns .TRUE. if CA is the same letter as CB regardless of *> case. *> \endverbatim * * Arguments: * ========== * *> \param[in] CA *> \verbatim *> CA is CHARACTER*1 *> \endverbatim *> *> \param[in] CB *> \verbatim *> CB is CHARACTER*1 *> CA and CB specify the single characters to be compared. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup lsame * * ===================================================================== LOGICAL FUNCTION LSAME(CA,CB) * * -- Reference BLAS level1 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. CHARACTER CA,CB * .. * * ===================================================================== * * .. Intrinsic Functions .. INTRINSIC ICHAR * .. * .. Local Scalars .. INTEGER INTA,INTB,ZCODE * .. * * Test if the characters are equal * LSAME = CA .EQ. CB IF (LSAME) RETURN * * Now test for equivalence if both characters are alphabetic. * ZCODE = ICHAR('Z') * * Use 'Z' rather than 'A' so that ASCII can be detected on Prime * machines, on which ICHAR returns a value with bit 8 set. * ICHAR('A') on Prime machines returns 193 which is the same as * ICHAR('A') on an EBCDIC machine. * INTA = ICHAR(CA) INTB = ICHAR(CB) * IF (ZCODE.EQ.90 .OR. ZCODE.EQ.122) THEN * * ASCII is assumed - ZCODE is the ASCII code of either lower or * upper case 'Z'. * IF (INTA.GE.97 .AND. INTA.LE.122) INTA = INTA - 32 IF (INTB.GE.97 .AND. INTB.LE.122) INTB = INTB - 32 * ELSE IF (ZCODE.EQ.233 .OR. ZCODE.EQ.169) THEN * * EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or * upper case 'Z'. * IF (INTA.GE.129 .AND. INTA.LE.137 .OR. + INTA.GE.145 .AND. INTA.LE.153 .OR. + INTA.GE.162 .AND. INTA.LE.169) INTA = INTA + 64 IF (INTB.GE.129 .AND. INTB.LE.137 .OR. + INTB.GE.145 .AND. INTB.LE.153 .OR. + INTB.GE.162 .AND. INTB.LE.169) INTB = INTB + 64 * ELSE IF (ZCODE.EQ.218 .OR. ZCODE.EQ.250) THEN * * ASCII is assumed, on Prime machines - ZCODE is the ASCII code * plus 128 of either lower or upper case 'Z'. * IF (INTA.GE.225 .AND. INTA.LE.250) INTA = INTA - 32 IF (INTB.GE.225 .AND. INTB.LE.250) INTB = INTB - 32 END IF LSAME = INTA .EQ. INTB * * RETURN * * End of LSAME * END *> \brief \b SCABS1 * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * REAL FUNCTION SCABS1(Z) * * .. Scalar Arguments .. * COMPLEX Z * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> SCABS1 computes |Re(.)| + |Im(.)| of a complex number *> \endverbatim * * Arguments: * ========== * *> \param[in] Z *> \verbatim *> Z is COMPLEX *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup abs1 * * ===================================================================== REAL FUNCTION SCABS1(Z) * * -- Reference BLAS level1 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. COMPLEX Z * .. * * ===================================================================== * * .. Intrinsic Functions .. INTRINSIC ABS,AIMAG,REAL * .. SCABS1 = ABS(REAL(Z)) + ABS(AIMAG(Z)) RETURN * * End of SCABS1 * END *> \brief \b XERBLA * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * SUBROUTINE XERBLA( SRNAME, INFO ) * * .. Scalar Arguments .. * CHARACTER*(*) SRNAME * INTEGER INFO * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> XERBLA is an error handler for the LAPACK routines. *> It is called by an LAPACK routine if an input parameter has an *> invalid value. A message is printed and execution stops. *> *> Installers may consider modifying the STOP statement in order to *> call system-specific exception-handling facilities. *> \endverbatim * * Arguments: * ========== * *> \param[in] SRNAME *> \verbatim *> SRNAME is CHARACTER*(*) *> The name of the routine which called XERBLA. *> \endverbatim *> *> \param[in] INFO *> \verbatim *> INFO is INTEGER *> The position of the invalid parameter in the parameter list *> of the calling routine. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup xerbla * * ===================================================================== SUBROUTINE XERBLA( SRNAME, INFO ) * * -- Reference BLAS level1 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. CHARACTER*(*) SRNAME INTEGER INFO * .. * * ===================================================================== * * .. Intrinsic Functions .. INTRINSIC LEN_TRIM * .. * .. Executable Statements .. * WRITE( *, FMT = 9999 )SRNAME( 1:LEN_TRIM( SRNAME ) ), INFO * STOP * 9999 FORMAT( ' ** On entry to ', A, ' parameter number ', I2, ' had ', $ 'an illegal value' ) * * End of XERBLA * END *> \brief \b ZAXPY * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * SUBROUTINE ZAXPY(N,ZA,ZX,INCX,ZY,INCY) * * .. Scalar Arguments .. * COMPLEX*16 ZA * INTEGER INCX,INCY,N * .. * .. Array Arguments .. * COMPLEX*16 ZX(*),ZY(*) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ZAXPY constant times a vector plus a vector. *> \endverbatim * * Arguments: * ========== * *> \param[in] N *> \verbatim *> N is INTEGER *> number of elements in input vector(s) *> \endverbatim *> *> \param[in] ZA *> \verbatim *> ZA is COMPLEX*16 *> On entry, ZA specifies the scalar alpha. *> \endverbatim *> *> \param[in] ZX *> \verbatim *> ZX is COMPLEX*16 array, dimension ( 1 + ( N - 1 )*abs( INCX ) ) *> \endverbatim *> *> \param[in] INCX *> \verbatim *> INCX is INTEGER *> storage spacing between elements of ZX *> \endverbatim *> *> \param[in,out] ZY *> \verbatim *> ZY is COMPLEX*16 array, dimension ( 1 + ( N - 1 )*abs( INCY ) ) *> \endverbatim *> *> \param[in] INCY *> \verbatim *> INCY is INTEGER *> storage spacing between elements of ZY *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup axpy * *> \par Further Details: * ===================== *> *> \verbatim *> *> jack dongarra, 3/11/78. *> modified 12/3/93, array(1) declarations changed to array(*) *> \endverbatim *> * ===================================================================== SUBROUTINE ZAXPY(N,ZA,ZX,INCX,ZY,INCY) * * -- Reference BLAS level1 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. COMPLEX*16 ZA INTEGER INCX,INCY,N * .. * .. Array Arguments .. COMPLEX*16 ZX(*),ZY(*) * .. * * ===================================================================== * * .. Local Scalars .. INTEGER I,IX,IY * .. * .. External Functions .. DOUBLE PRECISION DCABS1 EXTERNAL DCABS1 * .. IF (N.LE.0) RETURN IF (DCABS1(ZA).EQ.0.0d0) RETURN IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN * * code for both increments equal to 1 * DO I = 1,N ZY(I) = ZY(I) + ZA*ZX(I) END DO ELSE * * code for unequal increments or equal increments * not equal to 1 * IX = 1 IY = 1 IF (INCX.LT.0) IX = (-N+1)*INCX + 1 IF (INCY.LT.0) IY = (-N+1)*INCY + 1 DO I = 1,N ZY(IY) = ZY(IY) + ZA*ZX(IX) IX = IX + INCX IY = IY + INCY END DO END IF * RETURN * * End of ZAXPY * END *> \brief ZCGESV computes the solution to system of linear equations A * X = B for GE matrices (mixed precision with iterative refinement) * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download ZCGESV + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * SUBROUTINE ZCGESV( N, NRHS, A, LDA, IPIV, B, LDB, X, LDX, WORK, * SWORK, RWORK, ITER, INFO ) * * .. Scalar Arguments .. * INTEGER INFO, ITER, LDA, LDB, LDX, N, NRHS * .. * .. Array Arguments .. * INTEGER IPIV( * ) * DOUBLE PRECISION RWORK( * ) * COMPLEX SWORK( * ) * COMPLEX*16 A( LDA, * ), B( LDB, * ), WORK( N, * ), * $ X( LDX, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ZCGESV computes the solution to a complex system of linear equations *> A * X = B, *> where A is an N-by-N matrix and X and B are N-by-NRHS matrices. *> *> ZCGESV first attempts to factorize the matrix in COMPLEX and use this *> factorization within an iterative refinement procedure to produce a *> solution with COMPLEX*16 normwise backward error quality (see below). *> If the approach fails the method switches to a COMPLEX*16 *> factorization and solve. *> *> The iterative refinement is not going to be a winning strategy if *> the ratio COMPLEX performance over COMPLEX*16 performance is too *> small. A reasonable strategy should take the number of right-hand *> sides and the size of the matrix into account. This might be done *> with a call to ILAENV in the future. Up to now, we always try *> iterative refinement. *> *> The iterative refinement process is stopped if *> ITER > ITERMAX *> or for all the RHS we have: *> RNRM < SQRT(N)*XNRM*ANRM*EPS*BWDMAX *> where *> o ITER is the number of the current iteration in the iterative *> refinement process *> o RNRM is the infinity-norm of the residual *> o XNRM is the infinity-norm of the solution *> o ANRM is the infinity-operator-norm of the matrix A *> o EPS is the machine epsilon returned by DLAMCH('Epsilon') *> The value ITERMAX and BWDMAX are fixed to 30 and 1.0D+00 *> respectively. *> \endverbatim * * Arguments: * ========== * *> \param[in] N *> \verbatim *> N is INTEGER *> The number of linear equations, i.e., the order of the *> matrix A. N >= 0. *> \endverbatim *> *> \param[in] NRHS *> \verbatim *> NRHS is INTEGER *> The number of right hand sides, i.e., the number of columns *> of the matrix B. NRHS >= 0. *> \endverbatim *> *> \param[in,out] A *> \verbatim *> A is COMPLEX*16 array, *> dimension (LDA,N) *> On entry, the N-by-N coefficient matrix A. *> On exit, if iterative refinement has been successfully used *> (INFO = 0 and ITER >= 0, see description below), then A is *> unchanged, if double precision factorization has been used *> (INFO = 0 and ITER < 0, see description below), then the *> array A contains the factors L and U from the factorization *> A = P*L*U; the unit diagonal elements of L are not stored. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. LDA >= max(1,N). *> \endverbatim *> *> \param[out] IPIV *> \verbatim *> IPIV is INTEGER array, dimension (N) *> The pivot indices that define the permutation matrix P; *> row i of the matrix was interchanged with row IPIV(i). *> Corresponds either to the single precision factorization *> (if INFO = 0 and ITER >= 0) or the double precision *> factorization (if INFO = 0 and ITER < 0). *> \endverbatim *> *> \param[in] B *> \verbatim *> B is COMPLEX*16 array, dimension (LDB,NRHS) *> The N-by-NRHS right hand side matrix B. *> \endverbatim *> *> \param[in] LDB *> \verbatim *> LDB is INTEGER *> The leading dimension of the array B. LDB >= max(1,N). *> \endverbatim *> *> \param[out] X *> \verbatim *> X is COMPLEX*16 array, dimension (LDX,NRHS) *> If INFO = 0, the N-by-NRHS solution matrix X. *> \endverbatim *> *> \param[in] LDX *> \verbatim *> LDX is INTEGER *> The leading dimension of the array X. LDX >= max(1,N). *> \endverbatim *> *> \param[out] WORK *> \verbatim *> WORK is COMPLEX*16 array, dimension (N,NRHS) *> This array is used to hold the residual vectors. *> \endverbatim *> *> \param[out] SWORK *> \verbatim *> SWORK is COMPLEX array, dimension (N*(N+NRHS)) *> This array is used to use the single precision matrix and the *> right-hand sides or solutions in single precision. *> \endverbatim *> *> \param[out] RWORK *> \verbatim *> RWORK is DOUBLE PRECISION array, dimension (N) *> \endverbatim *> *> \param[out] ITER *> \verbatim *> ITER is INTEGER *> < 0: iterative refinement has failed, COMPLEX*16 *> factorization has been performed *> -1 : the routine fell back to full precision for *> implementation- or machine-specific reasons *> -2 : narrowing the precision induced an overflow, *> the routine fell back to full precision *> -3 : failure of CGETRF *> -31: stop the iterative refinement after the 30th *> iterations *> > 0: iterative refinement has been successfully used. *> Returns the number of iterations *> \endverbatim *> *> \param[out] INFO *> \verbatim *> INFO is INTEGER *> = 0: successful exit *> < 0: if INFO = -i, the i-th argument had an illegal value *> > 0: if INFO = i, U(i,i) computed in COMPLEX*16 is exactly *> zero. The factorization has been completed, but the *> factor U is exactly singular, so the solution *> could not be computed. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \date June 2016 * *> \ingroup complex16GEsolve * * ===================================================================== SUBROUTINE ZCGESV( N, NRHS, A, LDA, IPIV, B, LDB, X, LDX, WORK, $ SWORK, RWORK, ITER, INFO ) * * -- LAPACK driver routine (version 3.8.0) -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * June 2016 * * .. Scalar Arguments .. INTEGER INFO, ITER, LDA, LDB, LDX, N, NRHS * .. * .. Array Arguments .. INTEGER IPIV( * ) DOUBLE PRECISION RWORK( * ) COMPLEX SWORK( * ) COMPLEX*16 A( LDA, * ), B( LDB, * ), WORK( N, * ), $ X( LDX, * ) * .. * * ===================================================================== * * .. Parameters .. LOGICAL DOITREF PARAMETER ( DOITREF = .TRUE. ) * INTEGER ITERMAX PARAMETER ( ITERMAX = 30 ) * DOUBLE PRECISION BWDMAX PARAMETER ( BWDMAX = 1.0E+00 ) * COMPLEX*16 NEGONE, ONE PARAMETER ( NEGONE = ( -1.0D+00, 0.0D+00 ), $ ONE = ( 1.0D+00, 0.0D+00 ) ) * * .. Local Scalars .. INTEGER I, IITER, PTSA, PTSX DOUBLE PRECISION ANRM, CTE, EPS, RNRM, XNRM COMPLEX*16 ZDUM * * .. External Subroutines .. EXTERNAL CGETRS, CGETRF, CLAG2Z, XERBLA, ZAXPY, ZGEMM, $ ZLACPY, ZLAG2C, ZGETRF, ZGETRS * .. * .. External Functions .. INTEGER IZAMAX DOUBLE PRECISION DLAMCH, ZLANGE EXTERNAL IZAMAX, DLAMCH, ZLANGE * .. * .. Intrinsic Functions .. INTRINSIC ABS, DBLE, MAX, SQRT * .. * .. Statement Functions .. DOUBLE PRECISION CABS1 * .. * .. Statement Function definitions .. CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) ) * .. * .. Executable Statements .. * INFO = 0 ITER = 0 * * Test the input parameters. * IF( N.LT.0 ) THEN INFO = -1 ELSE IF( NRHS.LT.0 ) THEN INFO = -2 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN INFO = -4 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN INFO = -7 ELSE IF( LDX.LT.MAX( 1, N ) ) THEN INFO = -9 END IF IF( INFO.NE.0 ) THEN CALL XERBLA( 'ZCGESV', -INFO ) RETURN END IF * * Quick return if (N.EQ.0). * IF( N.EQ.0 ) $ RETURN * * Skip single precision iterative refinement if a priori slower * than double precision factorization. * IF( .NOT.DOITREF ) THEN ITER = -1 GO TO 40 END IF * * Compute some constants. * ANRM = ZLANGE( 'I', N, N, A, LDA, RWORK ) EPS = DLAMCH( 'Epsilon' ) CTE = ANRM*EPS*SQRT( DBLE( N ) )*BWDMAX * * Set the indices PTSA, PTSX for referencing SA and SX in SWORK. * PTSA = 1 PTSX = PTSA + N*N * * Convert B from double precision to single precision and store the * result in SX. * CALL ZLAG2C( N, NRHS, B, LDB, SWORK( PTSX ), N, INFO ) * IF( INFO.NE.0 ) THEN ITER = -2 GO TO 40 END IF * * Convert A from double precision to single precision and store the * result in SA. * CALL ZLAG2C( N, N, A, LDA, SWORK( PTSA ), N, INFO ) * IF( INFO.NE.0 ) THEN ITER = -2 GO TO 40 END IF * * Compute the LU factorization of SA. * CALL CGETRF( N, N, SWORK( PTSA ), N, IPIV, INFO ) * IF( INFO.NE.0 ) THEN ITER = -3 GO TO 40 END IF * * Solve the system SA*SX = SB. * CALL CGETRS( 'No transpose', N, NRHS, SWORK( PTSA ), N, IPIV, $ SWORK( PTSX ), N, INFO ) * * Convert SX back to double precision * CALL CLAG2Z( N, NRHS, SWORK( PTSX ), N, X, LDX, INFO ) * * Compute R = B - AX (R is WORK). * CALL ZLACPY( 'All', N, NRHS, B, LDB, WORK, N ) * CALL ZGEMM( 'No Transpose', 'No Transpose', N, NRHS, N, NEGONE, A, $ LDA, X, LDX, ONE, WORK, N ) * * Check whether the NRHS normwise backward errors satisfy the * stopping criterion. If yes, set ITER=0 and return. * DO I = 1, NRHS XNRM = CABS1( X( IZAMAX( N, X( 1, I ), 1 ), I ) ) RNRM = CABS1( WORK( IZAMAX( N, WORK( 1, I ), 1 ), I ) ) IF( RNRM.GT.XNRM*CTE ) $ GO TO 10 END DO * * If we are here, the NRHS normwise backward errors satisfy the * stopping criterion. We are good to exit. * ITER = 0 RETURN * 10 CONTINUE * DO 30 IITER = 1, ITERMAX * * Convert R (in WORK) from double precision to single precision * and store the result in SX. * CALL ZLAG2C( N, NRHS, WORK, N, SWORK( PTSX ), N, INFO ) * IF( INFO.NE.0 ) THEN ITER = -2 GO TO 40 END IF * * Solve the system SA*SX = SR. * CALL CGETRS( 'No transpose', N, NRHS, SWORK( PTSA ), N, IPIV, $ SWORK( PTSX ), N, INFO ) * * Convert SX back to double precision and update the current * iterate. * CALL CLAG2Z( N, NRHS, SWORK( PTSX ), N, WORK, N, INFO ) * DO I = 1, NRHS CALL ZAXPY( N, ONE, WORK( 1, I ), 1, X( 1, I ), 1 ) END DO * * Compute R = B - AX (R is WORK). * CALL ZLACPY( 'All', N, NRHS, B, LDB, WORK, N ) * CALL ZGEMM( 'No Transpose', 'No Transpose', N, NRHS, N, NEGONE, $ A, LDA, X, LDX, ONE, WORK, N ) * * Check whether the NRHS normwise backward errors satisfy the * stopping criterion. If yes, set ITER=IITER>0 and return. * DO I = 1, NRHS XNRM = CABS1( X( IZAMAX( N, X( 1, I ), 1 ), I ) ) RNRM = CABS1( WORK( IZAMAX( N, WORK( 1, I ), 1 ), I ) ) IF( RNRM.GT.XNRM*CTE ) $ GO TO 20 END DO * * If we are here, the NRHS normwise backward errors satisfy the * stopping criterion, we are good to exit. * ITER = IITER * RETURN * 20 CONTINUE * 30 CONTINUE * * If we are at this place of the code, this is because we have * performed ITER=ITERMAX iterations and never satisfied the stopping * criterion, set up the ITER flag accordingly and follow up on double * precision routine. * ITER = -ITERMAX - 1 * 40 CONTINUE * * Single-precision iterative refinement failed to converge to a * satisfactory solution, so we resort to double precision. * CALL ZGETRF( N, N, A, LDA, IPIV, INFO ) * IF( INFO.NE.0 ) $ RETURN * CALL ZLACPY( 'All', N, NRHS, B, LDB, X, LDX ) CALL ZGETRS( 'No transpose', N, NRHS, A, LDA, IPIV, X, LDX, $ INFO ) * RETURN * * End of ZCGESV. * END *> \brief \b ZGEMM * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * SUBROUTINE ZGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC) * * .. Scalar Arguments .. * COMPLEX*16 ALPHA,BETA * INTEGER K,LDA,LDB,LDC,M,N * CHARACTER TRANSA,TRANSB * .. * .. Array Arguments .. * COMPLEX*16 A(LDA,*),B(LDB,*),C(LDC,*) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ZGEMM performs one of the matrix-matrix operations *> *> C := alpha*op( A )*op( B ) + beta*C, *> *> where op( X ) is one of *> *> op( X ) = X or op( X ) = X**T or op( X ) = X**H, *> *> alpha and beta are scalars, and A, B and C are matrices, with op( A ) *> an m by k matrix, op( B ) a k by n matrix and C an m by n matrix. *> \endverbatim * * Arguments: * ========== * *> \param[in] TRANSA *> \verbatim *> TRANSA is CHARACTER*1 *> On entry, TRANSA specifies the form of op( A ) to be used in *> the matrix multiplication as follows: *> *> TRANSA = 'N' or 'n', op( A ) = A. *> *> TRANSA = 'T' or 't', op( A ) = A**T. *> *> TRANSA = 'C' or 'c', op( A ) = A**H. *> \endverbatim *> *> \param[in] TRANSB *> \verbatim *> TRANSB is CHARACTER*1 *> On entry, TRANSB specifies the form of op( B ) to be used in *> the matrix multiplication as follows: *> *> TRANSB = 'N' or 'n', op( B ) = B. *> *> TRANSB = 'T' or 't', op( B ) = B**T. *> *> TRANSB = 'C' or 'c', op( B ) = B**H. *> \endverbatim *> *> \param[in] M *> \verbatim *> M is INTEGER *> On entry, M specifies the number of rows of the matrix *> op( A ) and of the matrix C. M must be at least zero. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> On entry, N specifies the number of columns of the matrix *> op( B ) and the number of columns of the matrix C. N must be *> at least zero. *> \endverbatim *> *> \param[in] K *> \verbatim *> K is INTEGER *> On entry, K specifies the number of columns of the matrix *> op( A ) and the number of rows of the matrix op( B ). K must *> be at least zero. *> \endverbatim *> *> \param[in] ALPHA *> \verbatim *> ALPHA is COMPLEX*16 *> On entry, ALPHA specifies the scalar alpha. *> \endverbatim *> *> \param[in] A *> \verbatim *> A is COMPLEX*16 array, dimension ( LDA, ka ), where ka is *> k when TRANSA = 'N' or 'n', and is m otherwise. *> Before entry with TRANSA = 'N' or 'n', the leading m by k *> part of the array A must contain the matrix A, otherwise *> the leading k by m part of the array A must contain the *> matrix A. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> On entry, LDA specifies the first dimension of A as declared *> in the calling (sub) program. When TRANSA = 'N' or 'n' then *> LDA must be at least max( 1, m ), otherwise LDA must be at *> least max( 1, k ). *> \endverbatim *> *> \param[in] B *> \verbatim *> B is COMPLEX*16 array, dimension ( LDB, kb ), where kb is *> n when TRANSB = 'N' or 'n', and is k otherwise. *> Before entry with TRANSB = 'N' or 'n', the leading k by n *> part of the array B must contain the matrix B, otherwise *> the leading n by k part of the array B must contain the *> matrix B. *> \endverbatim *> *> \param[in] LDB *> \verbatim *> LDB is INTEGER *> On entry, LDB specifies the first dimension of B as declared *> in the calling (sub) program. When TRANSB = 'N' or 'n' then *> LDB must be at least max( 1, k ), otherwise LDB must be at *> least max( 1, n ). *> \endverbatim *> *> \param[in] BETA *> \verbatim *> BETA is COMPLEX*16 *> On entry, BETA specifies the scalar beta. When BETA is *> supplied as zero then C need not be set on input. *> \endverbatim *> *> \param[in,out] C *> \verbatim *> C is COMPLEX*16 array, dimension ( LDC, N ) *> Before entry, the leading m by n part of the array C must *> contain the matrix C, except when beta is zero, in which *> case C need not be set on entry. *> On exit, the array C is overwritten by the m by n matrix *> ( alpha*op( A )*op( B ) + beta*C ). *> \endverbatim *> *> \param[in] LDC *> \verbatim *> LDC is INTEGER *> On entry, LDC specifies the first dimension of C as declared *> in the calling (sub) program. LDC must be at least *> max( 1, m ). *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup gemm * *> \par Further Details: * ===================== *> *> \verbatim *> *> Level 3 Blas routine. *> *> -- Written on 8-February-1989. *> Jack Dongarra, Argonne National Laboratory. *> Iain Duff, AERE Harwell. *> Jeremy Du Croz, Numerical Algorithms Group Ltd. *> Sven Hammarling, Numerical Algorithms Group Ltd. *> \endverbatim *> * ===================================================================== SUBROUTINE ZGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB, + BETA,C,LDC) * * -- Reference BLAS level3 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. COMPLEX*16 ALPHA,BETA INTEGER K,LDA,LDB,LDC,M,N CHARACTER TRANSA,TRANSB * .. * .. Array Arguments .. COMPLEX*16 A(LDA,*),B(LDB,*),C(LDC,*) * .. * * ===================================================================== * * .. External Functions .. LOGICAL LSAME EXTERNAL LSAME * .. * .. External Subroutines .. EXTERNAL XERBLA * .. * .. Intrinsic Functions .. INTRINSIC DCONJG,MAX * .. * .. Local Scalars .. COMPLEX*16 TEMP INTEGER I,INFO,J,L,NROWA,NROWB LOGICAL CONJA,CONJB,NOTA,NOTB * .. * .. Parameters .. COMPLEX*16 ONE PARAMETER (ONE= (1.0D+0,0.0D+0)) COMPLEX*16 ZERO PARAMETER (ZERO= (0.0D+0,0.0D+0)) * .. * * Set NOTA and NOTB as true if A and B respectively are not * conjugated or transposed, set CONJA and CONJB as true if A and * B respectively are to be transposed but not conjugated and set * NROWA and NROWB as the number of rows of A and B respectively. * NOTA = LSAME(TRANSA,'N') NOTB = LSAME(TRANSB,'N') CONJA = LSAME(TRANSA,'C') CONJB = LSAME(TRANSB,'C') IF (NOTA) THEN NROWA = M ELSE NROWA = K END IF IF (NOTB) THEN NROWB = K ELSE NROWB = N END IF * * Test the input parameters. * INFO = 0 IF ((.NOT.NOTA) .AND. (.NOT.CONJA) .AND. + (.NOT.LSAME(TRANSA,'T'))) THEN INFO = 1 ELSE IF ((.NOT.NOTB) .AND. (.NOT.CONJB) .AND. + (.NOT.LSAME(TRANSB,'T'))) THEN INFO = 2 ELSE IF (M.LT.0) THEN INFO = 3 ELSE IF (N.LT.0) THEN INFO = 4 ELSE IF (K.LT.0) THEN INFO = 5 ELSE IF (LDA.LT.MAX(1,NROWA)) THEN INFO = 8 ELSE IF (LDB.LT.MAX(1,NROWB)) THEN INFO = 10 ELSE IF (LDC.LT.MAX(1,M)) THEN INFO = 13 END IF IF (INFO.NE.0) THEN CALL XERBLA('ZGEMM ',INFO) RETURN END IF * * Quick return if possible. * IF ((M.EQ.0) .OR. (N.EQ.0) .OR. + (((ALPHA.EQ.ZERO).OR. (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN * * And when alpha.eq.zero. * IF (ALPHA.EQ.ZERO) THEN IF (BETA.EQ.ZERO) THEN DO 20 J = 1,N DO 10 I = 1,M C(I,J) = ZERO 10 CONTINUE 20 CONTINUE ELSE DO 40 J = 1,N DO 30 I = 1,M C(I,J) = BETA*C(I,J) 30 CONTINUE 40 CONTINUE END IF RETURN END IF * * Start the operations. * IF (NOTB) THEN IF (NOTA) THEN * * Form C := alpha*A*B + beta*C. * DO 90 J = 1,N IF (BETA.EQ.ZERO) THEN DO 50 I = 1,M C(I,J) = ZERO 50 CONTINUE ELSE IF (BETA.NE.ONE) THEN DO 60 I = 1,M C(I,J) = BETA*C(I,J) 60 CONTINUE END IF DO 80 L = 1,K TEMP = ALPHA*B(L,J) DO 70 I = 1,M C(I,J) = C(I,J) + TEMP*A(I,L) 70 CONTINUE 80 CONTINUE 90 CONTINUE ELSE IF (CONJA) THEN * * Form C := alpha*A**H*B + beta*C. * DO 120 J = 1,N DO 110 I = 1,M TEMP = ZERO DO 100 L = 1,K TEMP = TEMP + DCONJG(A(L,I))*B(L,J) 100 CONTINUE IF (BETA.EQ.ZERO) THEN C(I,J) = ALPHA*TEMP ELSE C(I,J) = ALPHA*TEMP + BETA*C(I,J) END IF 110 CONTINUE 120 CONTINUE ELSE * * Form C := alpha*A**T*B + beta*C * DO 150 J = 1,N DO 140 I = 1,M TEMP = ZERO DO 130 L = 1,K TEMP = TEMP + A(L,I)*B(L,J) 130 CONTINUE IF (BETA.EQ.ZERO) THEN C(I,J) = ALPHA*TEMP ELSE C(I,J) = ALPHA*TEMP + BETA*C(I,J) END IF 140 CONTINUE 150 CONTINUE END IF ELSE IF (NOTA) THEN IF (CONJB) THEN * * Form C := alpha*A*B**H + beta*C. * DO 200 J = 1,N IF (BETA.EQ.ZERO) THEN DO 160 I = 1,M C(I,J) = ZERO 160 CONTINUE ELSE IF (BETA.NE.ONE) THEN DO 170 I = 1,M C(I,J) = BETA*C(I,J) 170 CONTINUE END IF DO 190 L = 1,K TEMP = ALPHA*DCONJG(B(J,L)) DO 180 I = 1,M C(I,J) = C(I,J) + TEMP*A(I,L) 180 CONTINUE 190 CONTINUE 200 CONTINUE ELSE * * Form C := alpha*A*B**T + beta*C * DO 250 J = 1,N IF (BETA.EQ.ZERO) THEN DO 210 I = 1,M C(I,J) = ZERO 210 CONTINUE ELSE IF (BETA.NE.ONE) THEN DO 220 I = 1,M C(I,J) = BETA*C(I,J) 220 CONTINUE END IF DO 240 L = 1,K TEMP = ALPHA*B(J,L) DO 230 I = 1,M C(I,J) = C(I,J) + TEMP*A(I,L) 230 CONTINUE 240 CONTINUE 250 CONTINUE END IF ELSE IF (CONJA) THEN IF (CONJB) THEN * * Form C := alpha*A**H*B**H + beta*C. * DO 280 J = 1,N DO 270 I = 1,M TEMP = ZERO DO 260 L = 1,K TEMP = TEMP + DCONJG(A(L,I))*DCONJG(B(J,L)) 260 CONTINUE IF (BETA.EQ.ZERO) THEN C(I,J) = ALPHA*TEMP ELSE C(I,J) = ALPHA*TEMP + BETA*C(I,J) END IF 270 CONTINUE 280 CONTINUE ELSE * * Form C := alpha*A**H*B**T + beta*C * DO 310 J = 1,N DO 300 I = 1,M TEMP = ZERO DO 290 L = 1,K TEMP = TEMP + DCONJG(A(L,I))*B(J,L) 290 CONTINUE IF (BETA.EQ.ZERO) THEN C(I,J) = ALPHA*TEMP ELSE C(I,J) = ALPHA*TEMP + BETA*C(I,J) END IF 300 CONTINUE 310 CONTINUE END IF ELSE IF (CONJB) THEN * * Form C := alpha*A**T*B**H + beta*C * DO 340 J = 1,N DO 330 I = 1,M TEMP = ZERO DO 320 L = 1,K TEMP = TEMP + A(L,I)*DCONJG(B(J,L)) 320 CONTINUE IF (BETA.EQ.ZERO) THEN C(I,J) = ALPHA*TEMP ELSE C(I,J) = ALPHA*TEMP + BETA*C(I,J) END IF 330 CONTINUE 340 CONTINUE ELSE * * Form C := alpha*A**T*B**T + beta*C * DO 370 J = 1,N DO 360 I = 1,M TEMP = ZERO DO 350 L = 1,K TEMP = TEMP + A(L,I)*B(J,L) 350 CONTINUE IF (BETA.EQ.ZERO) THEN C(I,J) = ALPHA*TEMP ELSE C(I,J) = ALPHA*TEMP + BETA*C(I,J) END IF 360 CONTINUE 370 CONTINUE END IF END IF * RETURN * * End of ZGEMM * END *> \brief \b ZGETRF * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download ZGETRF + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * SUBROUTINE ZGETRF( M, N, A, LDA, IPIV, INFO ) * * .. Scalar Arguments .. * INTEGER INFO, LDA, M, N * .. * .. Array Arguments .. * INTEGER IPIV( * ) * COMPLEX*16 A( LDA, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ZGETRF computes an LU factorization of a general M-by-N matrix A *> using partial pivoting with row interchanges. *> *> The factorization has the form *> A = P * L * U *> where P is a permutation matrix, L is lower triangular with unit *> diagonal elements (lower trapezoidal if m > n), and U is upper *> triangular (upper trapezoidal if m < n). *> *> This is the right-looking Level 3 BLAS version of the algorithm. *> \endverbatim * * Arguments: * ========== * *> \param[in] M *> \verbatim *> M is INTEGER *> The number of rows of the matrix A. M >= 0. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> The number of columns of the matrix A. N >= 0. *> \endverbatim *> *> \param[in,out] A *> \verbatim *> A is COMPLEX*16 array, dimension (LDA,N) *> On entry, the M-by-N matrix to be factored. *> On exit, the factors L and U from the factorization *> A = P*L*U; the unit diagonal elements of L are not stored. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. LDA >= max(1,M). *> \endverbatim *> *> \param[out] IPIV *> \verbatim *> IPIV is INTEGER array, dimension (min(M,N)) *> The pivot indices; for 1 <= i <= min(M,N), row i of the *> matrix was interchanged with row IPIV(i). *> \endverbatim *> *> \param[out] INFO *> \verbatim *> INFO is INTEGER *> = 0: successful exit *> < 0: if INFO = -i, the i-th argument had an illegal value *> > 0: if INFO = i, U(i,i) is exactly zero. The factorization *> has been completed, but the factor U is exactly *> singular, and division by zero will occur if it is used *> to solve a system of equations. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \date December 2016 * *> \ingroup complex16GEcomputational * * ===================================================================== SUBROUTINE ZGETRF( M, N, A, LDA, IPIV, INFO ) * * -- LAPACK computational routine (version 3.7.0) -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * December 2016 * * .. Scalar Arguments .. INTEGER INFO, LDA, M, N * .. * .. Array Arguments .. INTEGER IPIV( * ) COMPLEX*16 A( LDA, * ) * .. * * ===================================================================== * * .. Parameters .. COMPLEX*16 ONE PARAMETER ( ONE = ( 1.0D+0, 0.0D+0 ) ) * .. * .. Local Scalars .. INTEGER I, IINFO, J, JB, NB * .. * .. External Subroutines .. EXTERNAL XERBLA, ZGEMM, ZGETRF2, ZLASWP, ZTRSM * .. * .. External Functions .. INTEGER ILAENV EXTERNAL ILAENV * .. * .. Intrinsic Functions .. INTRINSIC MAX, MIN * .. * .. Executable Statements .. * * Test the input parameters. * INFO = 0 IF( M.LT.0 ) THEN INFO = -1 ELSE IF( N.LT.0 ) THEN INFO = -2 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN INFO = -4 END IF IF( INFO.NE.0 ) THEN CALL XERBLA( 'ZGETRF', -INFO ) RETURN END IF * * Quick return if possible * IF( M.EQ.0 .OR. N.EQ.0 ) $ RETURN * * Determine the block size for this environment. * NB = ILAENV( 1, 'ZGETRF', ' ', M, N, -1, -1 ) IF( NB.LE.1 .OR. NB.GE.MIN( M, N ) ) THEN * * Use unblocked code. * CALL ZGETRF2( M, N, A, LDA, IPIV, INFO ) ELSE * * Use blocked code. * DO 20 J = 1, MIN( M, N ), NB JB = MIN( MIN( M, N )-J+1, NB ) * * Factor diagonal and subdiagonal blocks and test for exact * singularity. * CALL ZGETRF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO ) * * Adjust INFO and the pivot indices. * IF( INFO.EQ.0 .AND. IINFO.GT.0 ) $ INFO = IINFO + J - 1 DO 10 I = J, MIN( M, J+JB-1 ) IPIV( I ) = J - 1 + IPIV( I ) 10 CONTINUE * * Apply interchanges to columns 1:J-1. * CALL ZLASWP( J-1, A, LDA, J, J+JB-1, IPIV, 1 ) * IF( J+JB.LE.N ) THEN * * Apply interchanges to columns J+JB:N. * CALL ZLASWP( N-J-JB+1, A( 1, J+JB ), LDA, J, J+JB-1, $ IPIV, 1 ) * * Compute block row of U. * CALL ZTRSM( 'Left', 'Lower', 'No transpose', 'Unit', JB, $ N-J-JB+1, ONE, A( J, J ), LDA, A( J, J+JB ), $ LDA ) IF( J+JB.LE.M ) THEN * * Update trailing submatrix. * CALL ZGEMM( 'No transpose', 'No transpose', M-J-JB+1, $ N-J-JB+1, JB, -ONE, A( J+JB, J ), LDA, $ A( J, J+JB ), LDA, ONE, A( J+JB, J+JB ), $ LDA ) END IF END IF 20 CONTINUE END IF RETURN * * End of ZGETRF * END *> \brief \b ZGETRF2 * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * RECURSIVE SUBROUTINE ZGETRF2( M, N, A, LDA, IPIV, INFO ) * * .. Scalar Arguments .. * INTEGER INFO, LDA, M, N * .. * .. Array Arguments .. * INTEGER IPIV( * ) * COMPLEX*16 A( LDA, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ZGETRF2 computes an LU factorization of a general M-by-N matrix A *> using partial pivoting with row interchanges. *> *> The factorization has the form *> A = P * L * U *> where P is a permutation matrix, L is lower triangular with unit *> diagonal elements (lower trapezoidal if m > n), and U is upper *> triangular (upper trapezoidal if m < n). *> *> This is the recursive version of the algorithm. It divides *> the matrix into four submatrices: *> *> [ A11 | A12 ] where A11 is n1 by n1 and A22 is n2 by n2 *> A = [ -----|----- ] with n1 = min(m,n)/2 *> [ A21 | A22 ] n2 = n-n1 *> *> [ A11 ] *> The subroutine calls itself to factor [ --- ], *> [ A12 ] *> [ A12 ] *> do the swaps on [ --- ], solve A12, update A22, *> [ A22 ] *> *> then calls itself to factor A22 and do the swaps on A21. *> *> \endverbatim * * Arguments: * ========== * *> \param[in] M *> \verbatim *> M is INTEGER *> The number of rows of the matrix A. M >= 0. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> The number of columns of the matrix A. N >= 0. *> \endverbatim *> *> \param[in,out] A *> \verbatim *> A is COMPLEX*16 array, dimension (LDA,N) *> On entry, the M-by-N matrix to be factored. *> On exit, the factors L and U from the factorization *> A = P*L*U; the unit diagonal elements of L are not stored. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. LDA >= max(1,M). *> \endverbatim *> *> \param[out] IPIV *> \verbatim *> IPIV is INTEGER array, dimension (min(M,N)) *> The pivot indices; for 1 <= i <= min(M,N), row i of the *> matrix was interchanged with row IPIV(i). *> \endverbatim *> *> \param[out] INFO *> \verbatim *> INFO is INTEGER *> = 0: successful exit *> < 0: if INFO = -i, the i-th argument had an illegal value *> > 0: if INFO = i, U(i,i) is exactly zero. The factorization *> has been completed, but the factor U is exactly *> singular, and division by zero will occur if it is used *> to solve a system of equations. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \date June 2016 * *> \ingroup complex16GEcomputational * * ===================================================================== RECURSIVE SUBROUTINE ZGETRF2( M, N, A, LDA, IPIV, INFO ) * * -- LAPACK computational routine (version 3.7.0) -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * June 2016 * * .. Scalar Arguments .. INTEGER INFO, LDA, M, N * .. * .. Array Arguments .. INTEGER IPIV( * ) COMPLEX*16 A( LDA, * ) * .. * * ===================================================================== * * .. Parameters .. COMPLEX*16 ONE, ZERO PARAMETER ( ONE = ( 1.0D+0, 0.0D+0 ), $ ZERO = ( 0.0D+0, 0.0D+0 ) ) * .. * .. Local Scalars .. DOUBLE PRECISION SFMIN COMPLEX*16 TEMP INTEGER I, IINFO, N1, N2 * .. * .. External Functions .. DOUBLE PRECISION DLAMCH INTEGER IZAMAX EXTERNAL DLAMCH, IZAMAX * .. * .. External Subroutines .. EXTERNAL ZGEMM, ZSCAL, ZLASWP, ZTRSM, XERBLA * .. * .. Intrinsic Functions .. INTRINSIC MAX, MIN * .. * .. Executable Statements .. * * Test the input parameters * INFO = 0 IF( M.LT.0 ) THEN INFO = -1 ELSE IF( N.LT.0 ) THEN INFO = -2 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN INFO = -4 END IF IF( INFO.NE.0 ) THEN CALL XERBLA( 'ZGETRF2', -INFO ) RETURN END IF * * Quick return if possible * IF( M.EQ.0 .OR. N.EQ.0 ) $ RETURN IF ( M.EQ.1 ) THEN * * Use unblocked code for one row case * Just need to handle IPIV and INFO * IPIV( 1 ) = 1 IF ( A(1,1).EQ.ZERO ) $ INFO = 1 * ELSE IF( N.EQ.1 ) THEN * * Use unblocked code for one column case * * * Compute machine safe minimum * SFMIN = DLAMCH('S') * * Find pivot and test for singularity * I = IZAMAX( M, A( 1, 1 ), 1 ) IPIV( 1 ) = I IF( A( I, 1 ).NE.ZERO ) THEN * * Apply the interchange * IF( I.NE.1 ) THEN TEMP = A( 1, 1 ) A( 1, 1 ) = A( I, 1 ) A( I, 1 ) = TEMP END IF * * Compute elements 2:M of the column * IF( ABS(A( 1, 1 )) .GE. SFMIN ) THEN CALL ZSCAL( M-1, ONE / A( 1, 1 ), A( 2, 1 ), 1 ) ELSE DO 10 I = 1, M-1 A( 1+I, 1 ) = A( 1+I, 1 ) / A( 1, 1 ) 10 CONTINUE END IF * ELSE INFO = 1 END IF ELSE * * Use recursive code * N1 = MIN( M, N ) / 2 N2 = N-N1 * * [ A11 ] * Factor [ --- ] * [ A21 ] * CALL ZGETRF2( M, N1, A, LDA, IPIV, IINFO ) IF ( INFO.EQ.0 .AND. IINFO.GT.0 ) $ INFO = IINFO * * [ A12 ] * Apply interchanges to [ --- ] * [ A22 ] * CALL ZLASWP( N2, A( 1, N1+1 ), LDA, 1, N1, IPIV, 1 ) * * Solve A12 * CALL ZTRSM( 'L', 'L', 'N', 'U', N1, N2, ONE, A, LDA, $ A( 1, N1+1 ), LDA ) * * Update A22 * CALL ZGEMM( 'N', 'N', M-N1, N2, N1, -ONE, A( N1+1, 1 ), LDA, $ A( 1, N1+1 ), LDA, ONE, A( N1+1, N1+1 ), LDA ) * * Factor A22 * CALL ZGETRF2( M-N1, N2, A( N1+1, N1+1 ), LDA, IPIV( N1+1 ), $ IINFO ) * * Adjust INFO and the pivot indices * IF ( INFO.EQ.0 .AND. IINFO.GT.0 ) $ INFO = IINFO + N1 DO 20 I = N1+1, MIN( M, N ) IPIV( I ) = IPIV( I ) + N1 20 CONTINUE * * Apply interchanges to A21 * CALL ZLASWP( N1, A( 1, 1 ), LDA, N1+1, MIN( M, N), IPIV, 1 ) * END IF RETURN * * End of ZGETRF2 * END *> \brief \b ZGETRS * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download ZGETRS + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * SUBROUTINE ZGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO ) * * .. Scalar Arguments .. * CHARACTER TRANS * INTEGER INFO, LDA, LDB, N, NRHS * .. * .. Array Arguments .. * INTEGER IPIV( * ) * COMPLEX*16 A( LDA, * ), B( LDB, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ZGETRS solves a system of linear equations *> A * X = B, A**T * X = B, or A**H * X = B *> with a general N-by-N matrix A using the LU factorization computed *> by ZGETRF. *> \endverbatim * * Arguments: * ========== * *> \param[in] TRANS *> \verbatim *> TRANS is CHARACTER*1 *> Specifies the form of the system of equations: *> = 'N': A * X = B (No transpose) *> = 'T': A**T * X = B (Transpose) *> = 'C': A**H * X = B (Conjugate transpose) *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> The order of the matrix A. N >= 0. *> \endverbatim *> *> \param[in] NRHS *> \verbatim *> NRHS is INTEGER *> The number of right hand sides, i.e., the number of columns *> of the matrix B. NRHS >= 0. *> \endverbatim *> *> \param[in] A *> \verbatim *> A is COMPLEX*16 array, dimension (LDA,N) *> The factors L and U from the factorization A = P*L*U *> as computed by ZGETRF. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. LDA >= max(1,N). *> \endverbatim *> *> \param[in] IPIV *> \verbatim *> IPIV is INTEGER array, dimension (N) *> The pivot indices from ZGETRF; for 1<=i<=N, row i of the *> matrix was interchanged with row IPIV(i). *> \endverbatim *> *> \param[in,out] B *> \verbatim *> B is COMPLEX*16 array, dimension (LDB,NRHS) *> On entry, the right hand side matrix B. *> On exit, the solution matrix X. *> \endverbatim *> *> \param[in] LDB *> \verbatim *> LDB is INTEGER *> The leading dimension of the array B. LDB >= max(1,N). *> \endverbatim *> *> \param[out] INFO *> \verbatim *> INFO is INTEGER *> = 0: successful exit *> < 0: if INFO = -i, the i-th argument had an illegal value *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \date December 2016 * *> \ingroup complex16GEcomputational * * ===================================================================== SUBROUTINE ZGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO ) * * -- LAPACK computational routine (version 3.7.0) -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * December 2016 * * .. Scalar Arguments .. CHARACTER TRANS INTEGER INFO, LDA, LDB, N, NRHS * .. * .. Array Arguments .. INTEGER IPIV( * ) COMPLEX*16 A( LDA, * ), B( LDB, * ) * .. * * ===================================================================== * * .. Parameters .. COMPLEX*16 ONE PARAMETER ( ONE = ( 1.0D+0, 0.0D+0 ) ) * .. * .. Local Scalars .. LOGICAL NOTRAN * .. * .. External Functions .. LOGICAL LSAME EXTERNAL LSAME * .. * .. External Subroutines .. EXTERNAL XERBLA, ZLASWP, ZTRSM * .. * .. Intrinsic Functions .. INTRINSIC MAX * .. * .. Executable Statements .. * * Test the input parameters. * INFO = 0 NOTRAN = LSAME( TRANS, 'N' ) IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT. $ LSAME( TRANS, 'C' ) ) THEN INFO = -1 ELSE IF( N.LT.0 ) THEN INFO = -2 ELSE IF( NRHS.LT.0 ) THEN INFO = -3 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN INFO = -5 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN INFO = -8 END IF IF( INFO.NE.0 ) THEN CALL XERBLA( 'ZGETRS', -INFO ) RETURN END IF * * Quick return if possible * IF( N.EQ.0 .OR. NRHS.EQ.0 ) $ RETURN * IF( NOTRAN ) THEN * * Solve A * X = B. * * Apply row interchanges to the right hand sides. * CALL ZLASWP( NRHS, B, LDB, 1, N, IPIV, 1 ) * * Solve L*X = B, overwriting B with X. * CALL ZTRSM( 'Left', 'Lower', 'No transpose', 'Unit', N, NRHS, $ ONE, A, LDA, B, LDB ) * * Solve U*X = B, overwriting B with X. * CALL ZTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N, $ NRHS, ONE, A, LDA, B, LDB ) ELSE * * Solve A**T * X = B or A**H * X = B. * * Solve U**T *X = B or U**H *X = B, overwriting B with X. * CALL ZTRSM( 'Left', 'Upper', TRANS, 'Non-unit', N, NRHS, ONE, $ A, LDA, B, LDB ) * * Solve L**T *X = B, or L**H *X = B overwriting B with X. * CALL ZTRSM( 'Left', 'Lower', TRANS, 'Unit', N, NRHS, ONE, A, $ LDA, B, LDB ) * * Apply row interchanges to the solution vectors. * CALL ZLASWP( NRHS, B, LDB, 1, N, IPIV, -1 ) END IF * RETURN * * End of ZGETRS * END *> \brief \b ZLACPY copies all or part of one two-dimensional array to another. * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download ZLACPY + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * SUBROUTINE ZLACPY( UPLO, M, N, A, LDA, B, LDB ) * * .. Scalar Arguments .. * CHARACTER UPLO * INTEGER LDA, LDB, M, N * .. * .. Array Arguments .. * COMPLEX*16 A( LDA, * ), B( LDB, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ZLACPY copies all or part of a two-dimensional matrix A to another *> matrix B. *> \endverbatim * * Arguments: * ========== * *> \param[in] UPLO *> \verbatim *> UPLO is CHARACTER*1 *> Specifies the part of the matrix A to be copied to B. *> = 'U': Upper triangular part *> = 'L': Lower triangular part *> Otherwise: All of the matrix A *> \endverbatim *> *> \param[in] M *> \verbatim *> M is INTEGER *> The number of rows of the matrix A. M >= 0. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> The number of columns of the matrix A. N >= 0. *> \endverbatim *> *> \param[in] A *> \verbatim *> A is COMPLEX*16 array, dimension (LDA,N) *> The m by n matrix A. If UPLO = 'U', only the upper trapezium *> is accessed; if UPLO = 'L', only the lower trapezium is *> accessed. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. LDA >= max(1,M). *> \endverbatim *> *> \param[out] B *> \verbatim *> B is COMPLEX*16 array, dimension (LDB,N) *> On exit, B = A in the locations specified by UPLO. *> \endverbatim *> *> \param[in] LDB *> \verbatim *> LDB is INTEGER *> The leading dimension of the array B. LDB >= max(1,M). *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \date December 2016 * *> \ingroup complex16OTHERauxiliary * * ===================================================================== SUBROUTINE ZLACPY( UPLO, M, N, A, LDA, B, LDB ) * * -- LAPACK auxiliary routine (version 3.7.0) -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * December 2016 * * .. Scalar Arguments .. CHARACTER UPLO INTEGER LDA, LDB, M, N * .. * .. Array Arguments .. COMPLEX*16 A( LDA, * ), B( LDB, * ) * .. * * ===================================================================== * * .. Local Scalars .. INTEGER I, J * .. * .. External Functions .. LOGICAL LSAME EXTERNAL LSAME * .. * .. Intrinsic Functions .. INTRINSIC MIN * .. * .. Executable Statements .. * IF( LSAME( UPLO, 'U' ) ) THEN DO 20 J = 1, N DO 10 I = 1, MIN( J, M ) B( I, J ) = A( I, J ) 10 CONTINUE 20 CONTINUE * ELSE IF( LSAME( UPLO, 'L' ) ) THEN DO 40 J = 1, N DO 30 I = J, M B( I, J ) = A( I, J ) 30 CONTINUE 40 CONTINUE * ELSE DO 60 J = 1, N DO 50 I = 1, M B( I, J ) = A( I, J ) 50 CONTINUE 60 CONTINUE END IF * RETURN * * End of ZLACPY * END *> \brief \b ZLAG2C converts a complex double precision matrix to a complex single precision matrix. * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download ZLAG2C + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * SUBROUTINE ZLAG2C( M, N, A, LDA, SA, LDSA, INFO ) * * .. Scalar Arguments .. * INTEGER INFO, LDA, LDSA, M, N * .. * .. Array Arguments .. * COMPLEX SA( LDSA, * ) * COMPLEX*16 A( LDA, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ZLAG2C converts a COMPLEX*16 matrix, SA, to a COMPLEX matrix, A. *> *> RMAX is the overflow for the SINGLE PRECISION arithmetic *> ZLAG2C checks that all the entries of A are between -RMAX and *> RMAX. If not the conversion is aborted and a flag is raised. *> *> This is an auxiliary routine so there is no argument checking. *> \endverbatim * * Arguments: * ========== * *> \param[in] M *> \verbatim *> M is INTEGER *> The number of lines of the matrix A. M >= 0. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> The number of columns of the matrix A. N >= 0. *> \endverbatim *> *> \param[in] A *> \verbatim *> A is COMPLEX*16 array, dimension (LDA,N) *> On entry, the M-by-N coefficient matrix A. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. LDA >= max(1,M). *> \endverbatim *> *> \param[out] SA *> \verbatim *> SA is COMPLEX array, dimension (LDSA,N) *> On exit, if INFO=0, the M-by-N coefficient matrix SA; if *> INFO>0, the content of SA is unspecified. *> \endverbatim *> *> \param[in] LDSA *> \verbatim *> LDSA is INTEGER *> The leading dimension of the array SA. LDSA >= max(1,M). *> \endverbatim *> *> \param[out] INFO *> \verbatim *> INFO is INTEGER *> = 0: successful exit. *> = 1: an entry of the matrix A is greater than the SINGLE *> PRECISION overflow threshold, in this case, the content *> of SA in exit is unspecified. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \date December 2016 * *> \ingroup complex16OTHERauxiliary * * ===================================================================== SUBROUTINE ZLAG2C( M, N, A, LDA, SA, LDSA, INFO ) * * -- LAPACK auxiliary routine (version 3.7.0) -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * December 2016 * * .. Scalar Arguments .. INTEGER INFO, LDA, LDSA, M, N * .. * .. Array Arguments .. COMPLEX SA( LDSA, * ) COMPLEX*16 A( LDA, * ) * .. * * ===================================================================== * * .. Local Scalars .. INTEGER I, J DOUBLE PRECISION RMAX * .. * .. Intrinsic Functions .. INTRINSIC DBLE, DIMAG * .. * .. External Functions .. REAL SLAMCH EXTERNAL SLAMCH * .. * .. Executable Statements .. * RMAX = SLAMCH( 'O' ) DO 20 J = 1, N DO 10 I = 1, M IF( ( DBLE( A( I, J ) ).LT.-RMAX ) .OR. $ ( DBLE( A( I, J ) ).GT.RMAX ) .OR. $ ( DIMAG( A( I, J ) ).LT.-RMAX ) .OR. $ ( DIMAG( A( I, J ) ).GT.RMAX ) ) THEN INFO = 1 GO TO 30 END IF SA( I, J ) = A( I, J ) 10 CONTINUE 20 CONTINUE INFO = 0 30 CONTINUE RETURN * * End of ZLAG2C * END *> \brief \b ZLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value of any element of a general rectangular matrix. * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download ZLANGE + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * DOUBLE PRECISION FUNCTION ZLANGE( NORM, M, N, A, LDA, WORK ) * * .. Scalar Arguments .. * CHARACTER NORM * INTEGER LDA, M, N * .. * .. Array Arguments .. * DOUBLE PRECISION WORK( * ) * COMPLEX*16 A( LDA, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ZLANGE returns the value of the one norm, or the Frobenius norm, or *> the infinity norm, or the element of largest absolute value of a *> complex matrix A. *> \endverbatim *> *> \return ZLANGE *> \verbatim *> *> ZLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm' *> ( *> ( norm1(A), NORM = '1', 'O' or 'o' *> ( *> ( normI(A), NORM = 'I' or 'i' *> ( *> ( normF(A), NORM = 'F', 'f', 'E' or 'e' *> *> where norm1 denotes the one norm of a matrix (maximum column sum), *> normI denotes the infinity norm of a matrix (maximum row sum) and *> normF denotes the Frobenius norm of a matrix (square root of sum of *> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm. *> \endverbatim * * Arguments: * ========== * *> \param[in] NORM *> \verbatim *> NORM is CHARACTER*1 *> Specifies the value to be returned in ZLANGE as described *> above. *> \endverbatim *> *> \param[in] M *> \verbatim *> M is INTEGER *> The number of rows of the matrix A. M >= 0. When M = 0, *> ZLANGE is set to zero. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> The number of columns of the matrix A. N >= 0. When N = 0, *> ZLANGE is set to zero. *> \endverbatim *> *> \param[in] A *> \verbatim *> A is COMPLEX*16 array, dimension (LDA,N) *> The m by n matrix A. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. LDA >= max(M,1). *> \endverbatim *> *> \param[out] WORK *> \verbatim *> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)), *> where LWORK >= M when NORM = 'I'; otherwise, WORK is not *> referenced. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \date December 2016 * *> \ingroup complex16GEauxiliary * * ===================================================================== DOUBLE PRECISION FUNCTION ZLANGE( NORM, M, N, A, LDA, WORK ) * * -- LAPACK auxiliary routine (version 3.7.0) -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * December 2016 * IMPLICIT NONE * .. Scalar Arguments .. CHARACTER NORM INTEGER LDA, M, N * .. * .. Array Arguments .. DOUBLE PRECISION WORK( * ) COMPLEX*16 A( LDA, * ) * .. * * ===================================================================== * * .. Parameters .. DOUBLE PRECISION ONE, ZERO PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) * .. * .. Local Scalars .. INTEGER I, J DOUBLE PRECISION SUM, VALUE, TEMP * .. * .. Local Arrays .. DOUBLE PRECISION SSQ( 2 ), COLSSQ( 2 ) * .. * .. External Functions .. LOGICAL LSAME, DISNAN EXTERNAL LSAME, DISNAN * .. * .. External Subroutines .. EXTERNAL ZLASSQ, DCOMBSSQ * .. * .. Intrinsic Functions .. INTRINSIC ABS, MIN, SQRT * .. * .. Executable Statements .. * IF( MIN( M, N ).EQ.0 ) THEN VALUE = ZERO ELSE IF( LSAME( NORM, 'M' ) ) THEN * * Find max(abs(A(i,j))). * VALUE = ZERO DO 20 J = 1, N DO 10 I = 1, M TEMP = ABS( A( I, J ) ) IF( VALUE.LT.TEMP .OR. DISNAN( TEMP ) ) VALUE = TEMP 10 CONTINUE 20 CONTINUE ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN * * Find norm1(A). * VALUE = ZERO DO 40 J = 1, N SUM = ZERO DO 30 I = 1, M SUM = SUM + ABS( A( I, J ) ) 30 CONTINUE IF( VALUE.LT.SUM .OR. DISNAN( SUM ) ) VALUE = SUM 40 CONTINUE ELSE IF( LSAME( NORM, 'I' ) ) THEN * * Find normI(A). * DO 50 I = 1, M WORK( I ) = ZERO 50 CONTINUE DO 70 J = 1, N DO 60 I = 1, M WORK( I ) = WORK( I ) + ABS( A( I, J ) ) 60 CONTINUE 70 CONTINUE VALUE = ZERO DO 80 I = 1, M TEMP = WORK( I ) IF( VALUE.LT.TEMP .OR. DISNAN( TEMP ) ) VALUE = TEMP 80 CONTINUE ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN * * Find normF(A). * SSQ(1) is scale * SSQ(2) is sum-of-squares * For better accuracy, sum each column separately. * SSQ( 1 ) = ZERO SSQ( 2 ) = ONE DO 90 J = 1, N COLSSQ( 1 ) = ZERO COLSSQ( 2 ) = ONE CALL ZLASSQ( M, A( 1, J ), 1, COLSSQ( 1 ), COLSSQ( 2 ) ) CALL DCOMBSSQ( SSQ, COLSSQ ) 90 CONTINUE VALUE = SSQ( 1 )*SQRT( SSQ( 2 ) ) END IF * ZLANGE = VALUE RETURN * * End of ZLANGE * END !> \brief \b ZLASSQ updates a sum of squares represented in scaled form. ! ! =========== DOCUMENTATION =========== ! ! Online html documentation available at ! http://www.netlib.org/lapack/explore-html/ ! !> \htmlonly !> Download ZLASSQ + dependencies !> !> [TGZ] !> !> [ZIP] !> !> [TXT] !> \endhtmlonly ! ! Definition: ! =========== ! ! SUBROUTINE ZLASSQ( N, X, INCX, SCALE, SUMSQ ) ! ! .. Scalar Arguments .. ! INTEGER INCX, N ! DOUBLE PRECISION SCALE, SUMSQ ! .. ! .. Array Arguments .. ! DOUBLE COMPLEX X( * ) ! .. ! ! !> \par Purpose: ! ============= !> !> \verbatim !> !> ZLASSQ returns the values scale_out and sumsq_out such that !> !> (scale_out**2)*sumsq_out = x( 1 )**2 +...+ x( n )**2 + (scale**2)*sumsq, !> !> where x( i ) = X( 1 + ( i - 1 )*INCX ). The value of sumsq is !> assumed to be non-negative. !> !> scale and sumsq must be supplied in SCALE and SUMSQ and !> scale_out and sumsq_out are overwritten on SCALE and SUMSQ respectively. !> !> \endverbatim ! ! Arguments: ! ========== ! !> \param[in] N !> \verbatim !> N is INTEGER !> The number of elements to be used from the vector x. !> \endverbatim !> !> \param[in] X !> \verbatim !> X is DOUBLE COMPLEX array, dimension (1+(N-1)*abs(INCX)) !> The vector for which a scaled sum of squares is computed. !> x( i ) = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n. !> \endverbatim !> !> \param[in] INCX !> \verbatim !> INCX is INTEGER !> The increment between successive values of the vector x. !> If INCX > 0, X(1+(i-1)*INCX) = x(i) for 1 <= i <= n !> If INCX < 0, X(1-(n-i)*INCX) = x(i) for 1 <= i <= n !> If INCX = 0, x isn't a vector so there is no need to call !> this subroutine. If you call it anyway, it will count x(1) !> in the vector norm N times. !> \endverbatim !> !> \param[in,out] SCALE !> \verbatim !> SCALE is DOUBLE PRECISION !> On entry, the value scale in the equation above. !> On exit, SCALE is overwritten by scale_out, the scaling factor !> for the sum of squares. !> \endverbatim !> !> \param[in,out] SUMSQ !> \verbatim !> SUMSQ is DOUBLE PRECISION !> On entry, the value sumsq in the equation above. !> On exit, SUMSQ is overwritten by sumsq_out, the basic sum of !> squares from which scale_out has been factored out. !> \endverbatim ! ! Authors: ! ======== ! !> \author Edward Anderson, Lockheed Martin ! !> \par Contributors: ! ================== !> !> Weslley Pereira, University of Colorado Denver, USA !> Nick Papior, Technical University of Denmark, DK ! !> \par Further Details: ! ===================== !> !> \verbatim !> !> Anderson E. (2017) !> Algorithm 978: Safe Scaling in the Level 1 BLAS !> ACM Trans Math Softw 44:1--28 !> https://doi.org/10.1145/3061665 !> !> Blue, James L. (1978) !> A Portable Fortran Program to Find the Euclidean Norm of a Vector !> ACM Trans Math Softw 4:15--23 !> https://doi.org/10.1145/355769.355771 !> !> \endverbatim ! !> \ingroup lassq ! ! ===================================================================== subroutine ZLASSQ( n, x, incx, scale, sumsq ) use LA_CONSTANTS, & only: wp=>dp, zero=>dzero, one=>done, & sbig=>dsbig, ssml=>dssml, tbig=>dtbig, tsml=>dtsml use LA_XISNAN ! ! -- LAPACK auxiliary routine -- ! -- LAPACK is a software package provided by Univ. of Tennessee, -- ! -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- ! ! .. Scalar Arguments .. integer :: incx, n real(wp) :: scale, sumsq ! .. ! .. Array Arguments .. complex(wp) :: x(*) ! .. ! .. Local Scalars .. integer :: i, ix logical :: notbig real(wp) :: abig, amed, asml, ax, ymax, ymin ! .. ! ! Quick return if possible ! if( LA_ISNAN(scale) .or. LA_ISNAN(sumsq) ) return if( sumsq == zero ) scale = one if( scale == zero ) then scale = one sumsq = zero end if if (n <= 0) then return end if ! ! Compute the sum of squares in 3 accumulators: ! abig -- sums of squares scaled down to avoid overflow ! asml -- sums of squares scaled up to avoid underflow ! amed -- sums of squares that do not require scaling ! The thresholds and multipliers are ! tbig -- values bigger than this are scaled down by sbig ! tsml -- values smaller than this are scaled up by ssml ! notbig = .true. asml = zero amed = zero abig = zero ix = 1 if( incx < 0 ) ix = 1 - (n-1)*incx do i = 1, n ax = abs(real(x(ix))) if (ax > tbig) then abig = abig + (ax*sbig)**2 notbig = .false. else if (ax < tsml) then if (notbig) asml = asml + (ax*ssml)**2 else amed = amed + ax**2 end if ax = abs(aimag(x(ix))) if (ax > tbig) then abig = abig + (ax*sbig)**2 notbig = .false. else if (ax < tsml) then if (notbig) asml = asml + (ax*ssml)**2 else amed = amed + ax**2 end if ix = ix + incx end do ! ! Put the existing sum of squares into one of the accumulators ! if( sumsq > zero ) then ax = scale*sqrt( sumsq ) if (ax > tbig) then if (scale > one) then scale = scale * sbig abig = abig + scale * (scale * sumsq) else ! sumsq > tbig^2 => (sbig * (sbig * sumsq)) is representable abig = abig + scale * (scale * (sbig * (sbig * sumsq))) end if else if (ax < tsml) then if (notbig) then if (scale < one) then scale = scale * ssml asml = asml + scale * (scale * sumsq) else ! sumsq < tsml^2 => (ssml * (ssml * sumsq)) is representable asml = asml + scale * (scale * (ssml * (ssml * sumsq))) end if end if else amed = amed + scale * (scale * sumsq) end if end if ! ! Combine abig and amed or amed and asml if more than one ! accumulator was used. ! if (abig > zero) then ! ! Combine abig and amed if abig > 0. ! if (amed > zero .or. LA_ISNAN(amed)) then abig = abig + (amed*sbig)*sbig end if scale = one / sbig sumsq = abig else if (asml > zero) then ! ! Combine amed and asml if asml > 0. ! if (amed > zero .or. LA_ISNAN(amed)) then amed = sqrt(amed) asml = sqrt(asml) / ssml if (asml > amed) then ymin = amed ymax = asml else ymin = asml ymax = amed end if scale = one sumsq = ymax**2*( one + (ymin/ymax)**2 ) else scale = one / ssml sumsq = asml end if else ! ! Otherwise all values are mid-range or zero ! scale = one sumsq = amed end if return end subroutine *> \brief \b ZLASWP performs a series of row interchanges on a general rectangular matrix. * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download ZLASWP + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * SUBROUTINE ZLASWP( N, A, LDA, K1, K2, IPIV, INCX ) * * .. Scalar Arguments .. * INTEGER INCX, K1, K2, LDA, N * .. * .. Array Arguments .. * INTEGER IPIV( * ) * COMPLEX*16 A( LDA, * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ZLASWP performs a series of row interchanges on the matrix A. *> One row interchange is initiated for each of rows K1 through K2 of A. *> \endverbatim * * Arguments: * ========== * *> \param[in] N *> \verbatim *> N is INTEGER *> The number of columns of the matrix A. *> \endverbatim *> *> \param[in,out] A *> \verbatim *> A is COMPLEX*16 array, dimension (LDA,N) *> On entry, the matrix of column dimension N to which the row *> interchanges will be applied. *> On exit, the permuted matrix. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> The leading dimension of the array A. *> \endverbatim *> *> \param[in] K1 *> \verbatim *> K1 is INTEGER *> The first element of IPIV for which a row interchange will *> be done. *> \endverbatim *> *> \param[in] K2 *> \verbatim *> K2 is INTEGER *> (K2-K1+1) is the number of elements of IPIV for which a row *> interchange will be done. *> \endverbatim *> *> \param[in] IPIV *> \verbatim *> IPIV is INTEGER array, dimension (K1+(K2-K1)*abs(INCX)) *> The vector of pivot indices. Only the elements in positions *> K1 through K1+(K2-K1)*abs(INCX) of IPIV are accessed. *> IPIV(K1+(K-K1)*abs(INCX)) = L implies rows K and L are to be *> interchanged. *> \endverbatim *> *> \param[in] INCX *> \verbatim *> INCX is INTEGER *> The increment between successive values of IPIV. If INCX *> is negative, the pivots are applied in reverse order. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \date June 2017 * *> \ingroup complex16OTHERauxiliary * *> \par Further Details: * ===================== *> *> \verbatim *> *> Modified by *> R. C. Whaley, Computer Science Dept., Univ. of Tenn., Knoxville, USA *> \endverbatim *> * ===================================================================== SUBROUTINE ZLASWP( N, A, LDA, K1, K2, IPIV, INCX ) * * -- LAPACK auxiliary routine (version 3.7.1) -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * June 2017 * * .. Scalar Arguments .. INTEGER INCX, K1, K2, LDA, N * .. * .. Array Arguments .. INTEGER IPIV( * ) COMPLEX*16 A( LDA, * ) * .. * * ===================================================================== * * .. Local Scalars .. INTEGER I, I1, I2, INC, IP, IX, IX0, J, K, N32 COMPLEX*16 TEMP * .. * .. Executable Statements .. * * Interchange row I with row IPIV(K1+(I-K1)*abs(INCX)) for each of rows * K1 through K2. * IF( INCX.GT.0 ) THEN IX0 = K1 I1 = K1 I2 = K2 INC = 1 ELSE IF( INCX.LT.0 ) THEN IX0 = K1 + ( K1-K2 )*INCX I1 = K2 I2 = K1 INC = -1 ELSE RETURN END IF * N32 = ( N / 32 )*32 IF( N32.NE.0 ) THEN DO 30 J = 1, N32, 32 IX = IX0 DO 20 I = I1, I2, INC IP = IPIV( IX ) IF( IP.NE.I ) THEN DO 10 K = J, J + 31 TEMP = A( I, K ) A( I, K ) = A( IP, K ) A( IP, K ) = TEMP 10 CONTINUE END IF IX = IX + INCX 20 CONTINUE 30 CONTINUE END IF IF( N32.NE.N ) THEN N32 = N32 + 1 IX = IX0 DO 50 I = I1, I2, INC IP = IPIV( IX ) IF( IP.NE.I ) THEN DO 40 K = N32, N TEMP = A( I, K ) A( I, K ) = A( IP, K ) A( IP, K ) = TEMP 40 CONTINUE END IF IX = IX + INCX 50 CONTINUE END IF * RETURN * * End of ZLASWP * END *> \brief \b ZSCAL * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * SUBROUTINE ZSCAL(N,ZA,ZX,INCX) * * .. Scalar Arguments .. * COMPLEX*16 ZA * INTEGER INCX,N * .. * .. Array Arguments .. * COMPLEX*16 ZX(*) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ZSCAL scales a vector by a constant. *> \endverbatim * * Arguments: * ========== * *> \param[in] N *> \verbatim *> N is INTEGER *> number of elements in input vector(s) *> \endverbatim *> *> \param[in] ZA *> \verbatim *> ZA is COMPLEX*16 *> On entry, ZA specifies the scalar alpha. *> \endverbatim *> *> \param[in,out] ZX *> \verbatim *> ZX is COMPLEX*16 array, dimension ( 1 + ( N - 1 )*abs( INCX ) ) *> \endverbatim *> *> \param[in] INCX *> \verbatim *> INCX is INTEGER *> storage spacing between elements of ZX *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup scal * *> \par Further Details: * ===================== *> *> \verbatim *> *> jack dongarra, 3/11/78. *> modified 3/93 to return if incx .le. 0. *> modified 12/3/93, array(1) declarations changed to array(*) *> \endverbatim *> * ===================================================================== SUBROUTINE ZSCAL(N,ZA,ZX,INCX) * * -- Reference BLAS level1 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. COMPLEX*16 ZA INTEGER INCX,N * .. * .. Array Arguments .. COMPLEX*16 ZX(*) * .. * * ===================================================================== * * .. Local Scalars .. INTEGER I,NINCX * .. * .. Parameters .. COMPLEX*16 ONE PARAMETER (ONE= (1.0D+0,0.0D+0)) * .. IF (N.LE.0 .OR. INCX.LE.0 .OR. ZA.EQ.ONE) RETURN IF (INCX.EQ.1) THEN * * code for increment equal to 1 * DO I = 1,N ZX(I) = ZA*ZX(I) END DO ELSE * * code for increment not equal to 1 * NINCX = N*INCX DO I = 1,NINCX,INCX ZX(I) = ZA*ZX(I) END DO END IF RETURN * * End of ZSCAL * END *> \brief \b ZTRSM * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * SUBROUTINE ZTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB) * * .. Scalar Arguments .. * COMPLEX*16 ALPHA * INTEGER LDA,LDB,M,N * CHARACTER DIAG,SIDE,TRANSA,UPLO * .. * .. Array Arguments .. * COMPLEX*16 A(LDA,*),B(LDB,*) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> ZTRSM solves one of the matrix equations *> *> op( A )*X = alpha*B, or X*op( A ) = alpha*B, *> *> where alpha is a scalar, X and B are m by n matrices, A is a unit, or *> non-unit, upper or lower triangular matrix and op( A ) is one of *> *> op( A ) = A or op( A ) = A**T or op( A ) = A**H. *> *> The matrix X is overwritten on B. *> \endverbatim * * Arguments: * ========== * *> \param[in] SIDE *> \verbatim *> SIDE is CHARACTER*1 *> On entry, SIDE specifies whether op( A ) appears on the left *> or right of X as follows: *> *> SIDE = 'L' or 'l' op( A )*X = alpha*B. *> *> SIDE = 'R' or 'r' X*op( A ) = alpha*B. *> \endverbatim *> *> \param[in] UPLO *> \verbatim *> UPLO is CHARACTER*1 *> On entry, UPLO specifies whether the matrix A is an upper or *> lower triangular matrix as follows: *> *> UPLO = 'U' or 'u' A is an upper triangular matrix. *> *> UPLO = 'L' or 'l' A is a lower triangular matrix. *> \endverbatim *> *> \param[in] TRANSA *> \verbatim *> TRANSA is CHARACTER*1 *> On entry, TRANSA specifies the form of op( A ) to be used in *> the matrix multiplication as follows: *> *> TRANSA = 'N' or 'n' op( A ) = A. *> *> TRANSA = 'T' or 't' op( A ) = A**T. *> *> TRANSA = 'C' or 'c' op( A ) = A**H. *> \endverbatim *> *> \param[in] DIAG *> \verbatim *> DIAG is CHARACTER*1 *> On entry, DIAG specifies whether or not A is unit triangular *> as follows: *> *> DIAG = 'U' or 'u' A is assumed to be unit triangular. *> *> DIAG = 'N' or 'n' A is not assumed to be unit *> triangular. *> \endverbatim *> *> \param[in] M *> \verbatim *> M is INTEGER *> On entry, M specifies the number of rows of B. M must be at *> least zero. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> On entry, N specifies the number of columns of B. N must be *> at least zero. *> \endverbatim *> *> \param[in] ALPHA *> \verbatim *> ALPHA is COMPLEX*16 *> On entry, ALPHA specifies the scalar alpha. When alpha is *> zero then A is not referenced and B need not be set before *> entry. *> \endverbatim *> *> \param[in] A *> \verbatim *> A is COMPLEX*16 array, dimension ( LDA, k ), *> where k is m when SIDE = 'L' or 'l' *> and k is n when SIDE = 'R' or 'r'. *> Before entry with UPLO = 'U' or 'u', the leading k by k *> upper triangular part of the array A must contain the upper *> triangular matrix and the strictly lower triangular part of *> A is not referenced. *> Before entry with UPLO = 'L' or 'l', the leading k by k *> lower triangular part of the array A must contain the lower *> triangular matrix and the strictly upper triangular part of *> A is not referenced. *> Note that when DIAG = 'U' or 'u', the diagonal elements of *> A are not referenced either, but are assumed to be unity. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is INTEGER *> On entry, LDA specifies the first dimension of A as declared *> in the calling (sub) program. When SIDE = 'L' or 'l' then *> LDA must be at least max( 1, m ), when SIDE = 'R' or 'r' *> then LDA must be at least max( 1, n ). *> \endverbatim *> *> \param[in,out] B *> \verbatim *> B is COMPLEX*16 array, dimension ( LDB, N ) *> Before entry, the leading m by n part of the array B must *> contain the right-hand side matrix B, and on exit is *> overwritten by the solution matrix X. *> \endverbatim *> *> \param[in] LDB *> \verbatim *> LDB is INTEGER *> On entry, LDB specifies the first dimension of B as declared *> in the calling (sub) program. LDB must be at least *> max( 1, m ). *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \ingroup trsm * *> \par Further Details: * ===================== *> *> \verbatim *> *> Level 3 Blas routine. *> *> -- Written on 8-February-1989. *> Jack Dongarra, Argonne National Laboratory. *> Iain Duff, AERE Harwell. *> Jeremy Du Croz, Numerical Algorithms Group Ltd. *> Sven Hammarling, Numerical Algorithms Group Ltd. *> \endverbatim *> * ===================================================================== SUBROUTINE ZTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB) * * -- Reference BLAS level3 routine -- * -- Reference BLAS is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * * .. Scalar Arguments .. COMPLEX*16 ALPHA INTEGER LDA,LDB,M,N CHARACTER DIAG,SIDE,TRANSA,UPLO * .. * .. Array Arguments .. COMPLEX*16 A(LDA,*),B(LDB,*) * .. * * ===================================================================== * * .. External Functions .. LOGICAL LSAME EXTERNAL LSAME * .. * .. External Subroutines .. EXTERNAL XERBLA * .. * .. Intrinsic Functions .. INTRINSIC DCONJG,MAX * .. * .. Local Scalars .. COMPLEX*16 TEMP INTEGER I,INFO,J,K,NROWA LOGICAL LSIDE,NOCONJ,NOUNIT,UPPER * .. * .. Parameters .. COMPLEX*16 ONE PARAMETER (ONE= (1.0D+0,0.0D+0)) COMPLEX*16 ZERO PARAMETER (ZERO= (0.0D+0,0.0D+0)) * .. * * Test the input parameters. * LSIDE = LSAME(SIDE,'L') IF (LSIDE) THEN NROWA = M ELSE NROWA = N END IF NOCONJ = LSAME(TRANSA,'T') NOUNIT = LSAME(DIAG,'N') UPPER = LSAME(UPLO,'U') * INFO = 0 IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN INFO = 1 ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN INFO = 2 ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND. + (.NOT.LSAME(TRANSA,'T')) .AND. + (.NOT.LSAME(TRANSA,'C'))) THEN INFO = 3 ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. + (.NOT.LSAME(DIAG,'N'))) THEN INFO = 4 ELSE IF (M.LT.0) THEN INFO = 5 ELSE IF (N.LT.0) THEN INFO = 6 ELSE IF (LDA.LT.MAX(1,NROWA)) THEN INFO = 9 ELSE IF (LDB.LT.MAX(1,M)) THEN INFO = 11 END IF IF (INFO.NE.0) THEN CALL XERBLA('ZTRSM ',INFO) RETURN END IF * * Quick return if possible. * IF (M.EQ.0 .OR. N.EQ.0) RETURN * * And when alpha.eq.zero. * IF (ALPHA.EQ.ZERO) THEN DO 20 J = 1,N DO 10 I = 1,M B(I,J) = ZERO 10 CONTINUE 20 CONTINUE RETURN END IF * * Start the operations. * IF (LSIDE) THEN IF (LSAME(TRANSA,'N')) THEN * * Form B := alpha*inv( A )*B. * IF (UPPER) THEN DO 60 J = 1,N IF (ALPHA.NE.ONE) THEN DO 30 I = 1,M B(I,J) = ALPHA*B(I,J) 30 CONTINUE END IF DO 50 K = M,1,-1 IF (B(K,J).NE.ZERO) THEN IF (NOUNIT) B(K,J) = B(K,J)/A(K,K) DO 40 I = 1,K - 1 B(I,J) = B(I,J) - B(K,J)*A(I,K) 40 CONTINUE END IF 50 CONTINUE 60 CONTINUE ELSE DO 100 J = 1,N IF (ALPHA.NE.ONE) THEN DO 70 I = 1,M B(I,J) = ALPHA*B(I,J) 70 CONTINUE END IF DO 90 K = 1,M IF (B(K,J).NE.ZERO) THEN IF (NOUNIT) B(K,J) = B(K,J)/A(K,K) DO 80 I = K + 1,M B(I,J) = B(I,J) - B(K,J)*A(I,K) 80 CONTINUE END IF 90 CONTINUE 100 CONTINUE END IF ELSE * * Form B := alpha*inv( A**T )*B * or B := alpha*inv( A**H )*B. * IF (UPPER) THEN DO 140 J = 1,N DO 130 I = 1,M TEMP = ALPHA*B(I,J) IF (NOCONJ) THEN DO 110 K = 1,I - 1 TEMP = TEMP - A(K,I)*B(K,J) 110 CONTINUE IF (NOUNIT) TEMP = TEMP/A(I,I) ELSE DO 120 K = 1,I - 1 TEMP = TEMP - DCONJG(A(K,I))*B(K,J) 120 CONTINUE IF (NOUNIT) TEMP = TEMP/DCONJG(A(I,I)) END IF B(I,J) = TEMP 130 CONTINUE 140 CONTINUE ELSE DO 180 J = 1,N DO 170 I = M,1,-1 TEMP = ALPHA*B(I,J) IF (NOCONJ) THEN DO 150 K = I + 1,M TEMP = TEMP - A(K,I)*B(K,J) 150 CONTINUE IF (NOUNIT) TEMP = TEMP/A(I,I) ELSE DO 160 K = I + 1,M TEMP = TEMP - DCONJG(A(K,I))*B(K,J) 160 CONTINUE IF (NOUNIT) TEMP = TEMP/DCONJG(A(I,I)) END IF B(I,J) = TEMP 170 CONTINUE 180 CONTINUE END IF END IF ELSE IF (LSAME(TRANSA,'N')) THEN * * Form B := alpha*B*inv( A ). * IF (UPPER) THEN DO 230 J = 1,N IF (ALPHA.NE.ONE) THEN DO 190 I = 1,M B(I,J) = ALPHA*B(I,J) 190 CONTINUE END IF DO 210 K = 1,J - 1 IF (A(K,J).NE.ZERO) THEN DO 200 I = 1,M B(I,J) = B(I,J) - A(K,J)*B(I,K) 200 CONTINUE END IF 210 CONTINUE IF (NOUNIT) THEN TEMP = ONE/A(J,J) DO 220 I = 1,M B(I,J) = TEMP*B(I,J) 220 CONTINUE END IF 230 CONTINUE ELSE DO 280 J = N,1,-1 IF (ALPHA.NE.ONE) THEN DO 240 I = 1,M B(I,J) = ALPHA*B(I,J) 240 CONTINUE END IF DO 260 K = J + 1,N IF (A(K,J).NE.ZERO) THEN DO 250 I = 1,M B(I,J) = B(I,J) - A(K,J)*B(I,K) 250 CONTINUE END IF 260 CONTINUE IF (NOUNIT) THEN TEMP = ONE/A(J,J) DO 270 I = 1,M B(I,J) = TEMP*B(I,J) 270 CONTINUE END IF 280 CONTINUE END IF ELSE * * Form B := alpha*B*inv( A**T ) * or B := alpha*B*inv( A**H ). * IF (UPPER) THEN DO 330 K = N,1,-1 IF (NOUNIT) THEN IF (NOCONJ) THEN TEMP = ONE/A(K,K) ELSE TEMP = ONE/DCONJG(A(K,K)) END IF DO 290 I = 1,M B(I,K) = TEMP*B(I,K) 290 CONTINUE END IF DO 310 J = 1,K - 1 IF (A(J,K).NE.ZERO) THEN IF (NOCONJ) THEN TEMP = A(J,K) ELSE TEMP = DCONJG(A(J,K)) END IF DO 300 I = 1,M B(I,J) = B(I,J) - TEMP*B(I,K) 300 CONTINUE END IF 310 CONTINUE IF (ALPHA.NE.ONE) THEN DO 320 I = 1,M B(I,K) = ALPHA*B(I,K) 320 CONTINUE END IF 330 CONTINUE ELSE DO 380 K = 1,N IF (NOUNIT) THEN IF (NOCONJ) THEN TEMP = ONE/A(K,K) ELSE TEMP = ONE/DCONJG(A(K,K)) END IF DO 340 I = 1,M B(I,K) = TEMP*B(I,K) 340 CONTINUE END IF DO 360 J = K + 1,N IF (A(J,K).NE.ZERO) THEN IF (NOCONJ) THEN TEMP = A(J,K) ELSE TEMP = DCONJG(A(J,K)) END IF DO 350 I = 1,M B(I,J) = B(I,J) - TEMP*B(I,K) 350 CONTINUE END IF 360 CONTINUE IF (ALPHA.NE.ONE) THEN DO 370 I = 1,M B(I,K) = ALPHA*B(I,K) 370 CONTINUE END IF 380 CONTINUE END IF END IF END IF * RETURN * * End of ZTRSM * END *> \brief \b DLAMCH * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * DOUBLE PRECISION FUNCTION DLAMCH( CMACH ) * * .. Scalar Arguments .. * CHARACTER CMACH * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> DLAMCH determines double precision machine parameters. *> \endverbatim * * Arguments: * ========== * *> \param[in] CMACH *> \verbatim *> CMACH is CHARACTER*1 *> Specifies the value to be returned by DLAMCH: *> = 'E' or 'e', DLAMCH := eps *> = 'S' or 's , DLAMCH := sfmin *> = 'B' or 'b', DLAMCH := base *> = 'P' or 'p', DLAMCH := eps*base *> = 'N' or 'n', DLAMCH := t *> = 'R' or 'r', DLAMCH := rnd *> = 'M' or 'm', DLAMCH := emin *> = 'U' or 'u', DLAMCH := rmin *> = 'L' or 'l', DLAMCH := emax *> = 'O' or 'o', DLAMCH := rmax *> where *> eps = relative machine precision *> sfmin = safe minimum, such that 1/sfmin does not overflow *> base = base of the machine *> prec = eps*base *> t = number of (base) digits in the mantissa *> rnd = 1.0 when rounding occurs in addition, 0.0 otherwise *> emin = minimum exponent before (gradual) underflow *> rmin = underflow threshold - base**(emin-1) *> emax = largest exponent before overflow *> rmax = overflow threshold - (base**emax)*(1-eps) *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \date December 2016 * *> \ingroup auxOTHERauxiliary * * ===================================================================== DOUBLE PRECISION FUNCTION DLAMCH( CMACH ) * * -- LAPACK auxiliary routine (version 3.7.0) -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * December 2016 * * .. Scalar Arguments .. CHARACTER CMACH * .. * * ===================================================================== * * .. Parameters .. DOUBLE PRECISION ONE, ZERO PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) * .. * .. Local Scalars .. DOUBLE PRECISION RND, EPS, SFMIN, SMALL, RMACH * .. * .. External Functions .. LOGICAL LSAME EXTERNAL LSAME * .. * .. Intrinsic Functions .. INTRINSIC DIGITS, EPSILON, HUGE, MAXEXPONENT, $ MINEXPONENT, RADIX, TINY * .. * .. Executable Statements .. * * * Assume rounding, not chopping. Always. * RND = ONE * IF( ONE.EQ.RND ) THEN EPS = EPSILON(ZERO) * 0.5 ELSE EPS = EPSILON(ZERO) END IF * IF( LSAME( CMACH, 'E' ) ) THEN RMACH = EPS ELSE IF( LSAME( CMACH, 'S' ) ) THEN SFMIN = TINY(ZERO) SMALL = ONE / HUGE(ZERO) IF( SMALL.GE.SFMIN ) THEN * * Use SMALL plus a bit, to avoid the possibility of rounding * causing overflow when computing 1/sfmin. * SFMIN = SMALL*( ONE+EPS ) END IF RMACH = SFMIN ELSE IF( LSAME( CMACH, 'B' ) ) THEN RMACH = RADIX(ZERO) ELSE IF( LSAME( CMACH, 'P' ) ) THEN RMACH = EPS * RADIX(ZERO) ELSE IF( LSAME( CMACH, 'N' ) ) THEN RMACH = DIGITS(ZERO) ELSE IF( LSAME( CMACH, 'R' ) ) THEN RMACH = RND ELSE IF( LSAME( CMACH, 'M' ) ) THEN RMACH = MINEXPONENT(ZERO) ELSE IF( LSAME( CMACH, 'U' ) ) THEN RMACH = tiny(zero) ELSE IF( LSAME( CMACH, 'L' ) ) THEN RMACH = MAXEXPONENT(ZERO) ELSE IF( LSAME( CMACH, 'O' ) ) THEN RMACH = HUGE(ZERO) ELSE RMACH = ZERO END IF * DLAMCH = RMACH RETURN * * End of DLAMCH * END ************************************************************************ *> \brief \b DLAMC3 *> \details *> \b Purpose: *> \verbatim *> DLAMC3 is intended to force A and B to be stored prior to doing *> the addition of A and B , for use in situations where optimizers *> might hold one of these in a register. *> \endverbatim *> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd.. *> \date December 2016 *> \ingroup auxOTHERauxiliary *> *> \param[in] A *> \verbatim *> A is a DOUBLE PRECISION *> \endverbatim *> *> \param[in] B *> \verbatim *> B is a DOUBLE PRECISION *> The values A and B. *> \endverbatim *> DOUBLE PRECISION FUNCTION DLAMC3( A, B ) * * -- LAPACK auxiliary routine (version 3.7.0) -- * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. * November 2010 * * .. Scalar Arguments .. DOUBLE PRECISION A, B * .. * ===================================================================== * * .. Executable Statements .. * DLAMC3 = A + B * RETURN * * End of DLAMC3 * END * ************************************************************************ *> \brief \b SLAMCH * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * REAL FUNCTION SLAMCH( CMACH ) * * .. Scalar Arguments .. * CHARACTER CMACH * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> SLAMCH determines single precision machine parameters. *> \endverbatim * * Arguments: * ========== * *> \param[in] CMACH *> \verbatim *> CMACH is CHARACTER*1 *> Specifies the value to be returned by SLAMCH: *> = 'E' or 'e', SLAMCH := eps *> = 'S' or 's , SLAMCH := sfmin *> = 'B' or 'b', SLAMCH := base *> = 'P' or 'p', SLAMCH := eps*base *> = 'N' or 'n', SLAMCH := t *> = 'R' or 'r', SLAMCH := rnd *> = 'M' or 'm', SLAMCH := emin *> = 'U' or 'u', SLAMCH := rmin *> = 'L' or 'l', SLAMCH := emax *> = 'O' or 'o', SLAMCH := rmax *> where *> eps = relative machine precision *> sfmin = safe minimum, such that 1/sfmin does not overflow *> base = base of the machine *> prec = eps*base *> t = number of (base) digits in the mantissa *> rnd = 1.0 when rounding occurs in addition, 0.0 otherwise *> emin = minimum exponent before (gradual) underflow *> rmin = underflow threshold - base**(emin-1) *> emax = largest exponent before overflow *> rmax = overflow threshold - (base**emax)*(1-eps) *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \date December 2016 * *> \ingroup auxOTHERauxiliary * * ===================================================================== REAL FUNCTION SLAMCH( CMACH ) * * -- LAPACK auxiliary routine (version 3.7.0) -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * December 2016 * * .. Scalar Arguments .. CHARACTER CMACH * .. * * ===================================================================== * * .. Parameters .. REAL ONE, ZERO PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 ) * .. * .. Local Scalars .. REAL RND, EPS, SFMIN, SMALL, RMACH * .. * .. External Functions .. LOGICAL LSAME EXTERNAL LSAME * .. * .. Intrinsic Functions .. INTRINSIC DIGITS, EPSILON, HUGE, MAXEXPONENT, $ MINEXPONENT, RADIX, TINY * .. * .. Executable Statements .. * * * Assume rounding, not chopping. Always. * RND = ONE * IF( ONE.EQ.RND ) THEN EPS = EPSILON(ZERO) * 0.5 ELSE EPS = EPSILON(ZERO) END IF * IF( LSAME( CMACH, 'E' ) ) THEN RMACH = EPS ELSE IF( LSAME( CMACH, 'S' ) ) THEN SFMIN = TINY(ZERO) SMALL = ONE / HUGE(ZERO) IF( SMALL.GE.SFMIN ) THEN * * Use SMALL plus a bit, to avoid the possibility of rounding * causing overflow when computing 1/sfmin. * SFMIN = SMALL*( ONE+EPS ) END IF RMACH = SFMIN ELSE IF( LSAME( CMACH, 'B' ) ) THEN RMACH = RADIX(ZERO) ELSE IF( LSAME( CMACH, 'P' ) ) THEN RMACH = EPS * RADIX(ZERO) ELSE IF( LSAME( CMACH, 'N' ) ) THEN RMACH = DIGITS(ZERO) ELSE IF( LSAME( CMACH, 'R' ) ) THEN RMACH = RND ELSE IF( LSAME( CMACH, 'M' ) ) THEN RMACH = MINEXPONENT(ZERO) ELSE IF( LSAME( CMACH, 'U' ) ) THEN RMACH = tiny(zero) ELSE IF( LSAME( CMACH, 'L' ) ) THEN RMACH = MAXEXPONENT(ZERO) ELSE IF( LSAME( CMACH, 'O' ) ) THEN RMACH = HUGE(ZERO) ELSE RMACH = ZERO END IF * SLAMCH = RMACH RETURN * * End of SLAMCH * END ************************************************************************ *> \brief \b SLAMC3 *> \details *> \b Purpose: *> \verbatim *> SLAMC3 is intended to force A and B to be stored prior to doing *> the addition of A and B , for use in situations where optimizers *> might hold one of these in a register. *> \endverbatim *> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd.. *> \date December 2016 *> \ingroup auxOTHERauxiliary *> *> \param[in] A *> \verbatim *> \endverbatim *> *> \param[in] B *> \verbatim *> The values A and B. *> \endverbatim *> * REAL FUNCTION SLAMC3( A, B ) * * -- LAPACK auxiliary routine (version 3.7.0) -- * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. * November 2010 * * .. Scalar Arguments .. REAL A, B * .. * ===================================================================== * * .. Executable Statements .. * SLAMC3 = A + B * RETURN * * End of SLAMC3 * END * ************************************************************************