3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
11 * SUBROUTINE CTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
13 * .. Scalar Arguments ..
16 * CHARACTER DIAG,SIDE,TRANSA,UPLO
18 * .. Array Arguments ..
19 * COMPLEX A(LDA,*),B(LDB,*)
28 *> CTRSM solves one of the matrix equations
30 *> op( A )*X = alpha*B, or X*op( A ) = alpha*B,
32 *> where alpha is a scalar, X and B are m by n matrices, A is a unit, or
33 *> non-unit, upper or lower triangular matrix and op( A ) is one of
35 *> op( A ) = A or op( A ) = A**T or op( A ) = A**H.
37 *> The matrix X is overwritten on B.
45 *> SIDE is CHARACTER*1
46 *> On entry, SIDE specifies whether op( A ) appears on the left
47 *> or right of X as follows:
49 *> SIDE = 'L' or 'l' op( A )*X = alpha*B.
51 *> SIDE = 'R' or 'r' X*op( A ) = alpha*B.
56 *> UPLO is CHARACTER*1
57 *> On entry, UPLO specifies whether the matrix A is an upper or
58 *> lower triangular matrix as follows:
60 *> UPLO = 'U' or 'u' A is an upper triangular matrix.
62 *> UPLO = 'L' or 'l' A is a lower triangular matrix.
67 *> TRANSA is CHARACTER*1
68 *> On entry, TRANSA specifies the form of op( A ) to be used in
69 *> the matrix multiplication as follows:
71 *> TRANSA = 'N' or 'n' op( A ) = A.
73 *> TRANSA = 'T' or 't' op( A ) = A**T.
75 *> TRANSA = 'C' or 'c' op( A ) = A**H.
80 *> DIAG is CHARACTER*1
81 *> On entry, DIAG specifies whether or not A is unit triangular
84 *> DIAG = 'U' or 'u' A is assumed to be unit triangular.
86 *> DIAG = 'N' or 'n' A is not assumed to be unit
93 *> On entry, M specifies the number of rows of B. M must be at
100 *> On entry, N specifies the number of columns of B. N must be
107 *> On entry, ALPHA specifies the scalar alpha. When alpha is
108 *> zero then A is not referenced and B need not be set before
114 *> A is COMPLEX array of DIMENSION ( LDA, k ),
115 *> where k is m when SIDE = 'L' or 'l'
116 *> and k is n when SIDE = 'R' or 'r'.
117 *> Before entry with UPLO = 'U' or 'u', the leading k by k
118 *> upper triangular part of the array A must contain the upper
119 *> triangular matrix and the strictly lower triangular part of
120 *> A is not referenced.
121 *> Before entry with UPLO = 'L' or 'l', the leading k by k
122 *> lower triangular part of the array A must contain the lower
123 *> triangular matrix and the strictly upper triangular part of
124 *> A is not referenced.
125 *> Note that when DIAG = 'U' or 'u', the diagonal elements of
126 *> A are not referenced either, but are assumed to be unity.
132 *> On entry, LDA specifies the first dimension of A as declared
133 *> in the calling (sub) program. When SIDE = 'L' or 'l' then
134 *> LDA must be at least max( 1, m ), when SIDE = 'R' or 'r'
135 *> then LDA must be at least max( 1, n ).
140 *> B is COMPLEX array of DIMENSION ( LDB, n ).
141 *> Before entry, the leading m by n part of the array B must
142 *> contain the right-hand side matrix B, and on exit is
143 *> overwritten by the solution matrix X.
149 *> On entry, LDB specifies the first dimension of B as declared
150 *> in the calling (sub) program. LDB must be at least
157 *> \author Univ. of Tennessee
158 *> \author Univ. of California Berkeley
159 *> \author Univ. of Colorado Denver
162 *> \date November 2011
164 *> \ingroup complex_blas_level3
166 *> \par Further Details:
167 * =====================
171 *> Level 3 Blas routine.
173 *> -- Written on 8-February-1989.
174 *> Jack Dongarra, Argonne National Laboratory.
175 *> Iain Duff, AERE Harwell.
176 *> Jeremy Du Croz, Numerical Algorithms Group Ltd.
177 *> Sven Hammarling, Numerical Algorithms Group Ltd.
180 * =====================================================================
181 SUBROUTINE CTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
183 * -- Reference BLAS level3 routine (version 3.4.0) --
184 * -- Reference BLAS is a software package provided by Univ. of Tennessee, --
185 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
188 * .. Scalar Arguments ..
191 CHARACTER DIAG,SIDE,TRANSA,UPLO
193 * .. Array Arguments ..
194 COMPLEX A(LDA,*),B(LDB,*)
197 * =====================================================================
199 * .. External Functions ..
203 * .. External Subroutines ..
206 * .. Intrinsic Functions ..
209 * .. Local Scalars ..
211 INTEGER I,INFO,J,K,NROWA
212 LOGICAL LSIDE,NOCONJ,NOUNIT,UPPER
216 PARAMETER (ONE= (1.0E+0,0.0E+0))
218 PARAMETER (ZERO= (0.0E+0,0.0E+0))
221 * Test the input parameters.
223 LSIDE = LSAME(SIDE,'L')
229 NOCONJ = LSAME(TRANSA,'T')
230 NOUNIT = LSAME(DIAG,'N')
231 UPPER = LSAME(UPLO,'U')
234 IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
236 ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
238 ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
239 + (.NOT.LSAME(TRANSA,'T')) .AND.
240 + (.NOT.LSAME(TRANSA,'C'))) THEN
242 ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
244 ELSE IF (M.LT.0) THEN
246 ELSE IF (N.LT.0) THEN
248 ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
250 ELSE IF (LDB.LT.MAX(1,M)) THEN
254 CALL XERBLA('CTRSM ',INFO)
258 * Quick return if possible.
260 IF (M.EQ.0 .OR. N.EQ.0) RETURN
262 * And when alpha.eq.zero.
264 IF (ALPHA.EQ.ZERO) THEN
273 * Start the operations.
276 IF (LSAME(TRANSA,'N')) THEN
278 * Form B := alpha*inv( A )*B.
282 IF (ALPHA.NE.ONE) THEN
284 B(I,J) = ALPHA*B(I,J)
288 IF (B(K,J).NE.ZERO) THEN
289 IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
291 B(I,J) = B(I,J) - B(K,J)*A(I,K)
298 IF (ALPHA.NE.ONE) THEN
300 B(I,J) = ALPHA*B(I,J)
304 IF (B(K,J).NE.ZERO) THEN
305 IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
307 B(I,J) = B(I,J) - B(K,J)*A(I,K)
315 * Form B := alpha*inv( A**T )*B
316 * or B := alpha*inv( A**H )*B.
324 TEMP = TEMP - A(K,I)*B(K,J)
326 IF (NOUNIT) TEMP = TEMP/A(I,I)
329 TEMP = TEMP - CONJG(A(K,I))*B(K,J)
331 IF (NOUNIT) TEMP = TEMP/CONJG(A(I,I))
342 TEMP = TEMP - A(K,I)*B(K,J)
344 IF (NOUNIT) TEMP = TEMP/A(I,I)
347 TEMP = TEMP - CONJG(A(K,I))*B(K,J)
349 IF (NOUNIT) TEMP = TEMP/CONJG(A(I,I))
357 IF (LSAME(TRANSA,'N')) THEN
359 * Form B := alpha*B*inv( A ).
363 IF (ALPHA.NE.ONE) THEN
365 B(I,J) = ALPHA*B(I,J)
369 IF (A(K,J).NE.ZERO) THEN
371 B(I,J) = B(I,J) - A(K,J)*B(I,K)
384 IF (ALPHA.NE.ONE) THEN
386 B(I,J) = ALPHA*B(I,J)
390 IF (A(K,J).NE.ZERO) THEN
392 B(I,J) = B(I,J) - A(K,J)*B(I,K)
406 * Form B := alpha*B*inv( A**T )
407 * or B := alpha*B*inv( A**H ).
415 TEMP = ONE/CONJG(A(K,K))
422 IF (A(J,K).NE.ZERO) THEN
429 B(I,J) = B(I,J) - TEMP*B(I,K)
433 IF (ALPHA.NE.ONE) THEN
435 B(I,K) = ALPHA*B(I,K)
445 TEMP = ONE/CONJG(A(K,K))
452 IF (A(J,K).NE.ZERO) THEN
459 B(I,J) = B(I,J) - TEMP*B(I,K)
463 IF (ALPHA.NE.ONE) THEN
465 B(I,K) = ALPHA*B(I,K)