1
SUBROUTINE DTRMM ( SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA,
3
* .. Scalar Arguments ..
4
CHARACTER*1 SIDE, UPLO, TRANSA, DIAG
7
* .. Array Arguments ..
8
DOUBLE PRECISION A( LDA, * ), B( LDB, * )
14
* DTRMM performs one of the matrix-matrix operations
16
* B := alpha*op( A )*B, or B := alpha*B*op( A ),
18
* where alpha is a scalar, B is an m by n matrix, A is a unit, or
19
* non-unit, upper or lower triangular matrix and op( A ) is one of
21
* op( A ) = A or op( A ) = A'.
27
* On entry, SIDE specifies whether op( A ) multiplies B from
28
* the left or right as follows:
30
* SIDE = 'L' or 'l' B := alpha*op( A )*B.
32
* SIDE = 'R' or 'r' B := alpha*B*op( A ).
37
* On entry, UPLO specifies whether the matrix A is an upper or
38
* lower triangular matrix as follows:
40
* UPLO = 'U' or 'u' A is an upper triangular matrix.
42
* UPLO = 'L' or 'l' A is a lower triangular matrix.
46
* TRANSA - CHARACTER*1.
47
* On entry, TRANSA specifies the form of op( A ) to be used in
48
* the matrix multiplication as follows:
50
* TRANSA = 'N' or 'n' op( A ) = A.
52
* TRANSA = 'T' or 't' op( A ) = A'.
54
* TRANSA = 'C' or 'c' op( A ) = A'.
59
* On entry, DIAG specifies whether or not A is unit triangular
62
* DIAG = 'U' or 'u' A is assumed to be unit triangular.
64
* DIAG = 'N' or 'n' A is not assumed to be unit
70
* On entry, M specifies the number of rows of B. M must be at
75
* On entry, N specifies the number of columns of B. N must be
79
* ALPHA - DOUBLE PRECISION.
80
* On entry, ALPHA specifies the scalar alpha. When alpha is
81
* zero then A is not referenced and B need not be set before
85
* A - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m
86
* when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'.
87
* Before entry with UPLO = 'U' or 'u', the leading k by k
88
* upper triangular part of the array A must contain the upper
89
* triangular matrix and the strictly lower triangular part of
90
* A is not referenced.
91
* Before entry with UPLO = 'L' or 'l', the leading k by k
92
* lower triangular part of the array A must contain the lower
93
* triangular matrix and the strictly upper triangular part of
94
* A is not referenced.
95
* Note that when DIAG = 'U' or 'u', the diagonal elements of
96
* A are not referenced either, but are assumed to be unity.
100
* On entry, LDA specifies the first dimension of A as declared
101
* in the calling (sub) program. When SIDE = 'L' or 'l' then
102
* LDA must be at least max( 1, m ), when SIDE = 'R' or 'r'
103
* then LDA must be at least max( 1, n ).
106
* B - DOUBLE PRECISION array of DIMENSION ( LDB, n ).
107
* Before entry, the leading m by n part of the array B must
108
* contain the matrix B, and on exit is overwritten by the
109
* transformed matrix.
112
* On entry, LDB specifies the first dimension of B as declared
113
* in the calling (sub) program. LDB must be at least
118
* Level 3 Blas routine.
120
* -- Written on 8-February-1989.
121
* Jack Dongarra, Argonne National Laboratory.
122
* Iain Duff, AERE Harwell.
123
* Jeremy Du Croz, Numerical Algorithms Group Ltd.
124
* Sven Hammarling, Numerical Algorithms Group Ltd.
127
* .. External Functions ..
130
* .. External Subroutines ..
132
* .. Intrinsic Functions ..
134
* .. Local Scalars ..
135
LOGICAL LSIDE, NOUNIT, UPPER
136
INTEGER I, INFO, J, K, NROWA
137
DOUBLE PRECISION TEMP
139
DOUBLE PRECISION ONE , ZERO
140
PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )
142
* .. Executable Statements ..
144
* Test the input parameters.
146
LSIDE = LSAME( SIDE , 'L' )
152
NOUNIT = LSAME( DIAG , 'N' )
153
UPPER = LSAME( UPLO , 'U' )
156
IF( ( .NOT.LSIDE ).AND.
157
$ ( .NOT.LSAME( SIDE , 'R' ) ) )THEN
159
ELSE IF( ( .NOT.UPPER ).AND.
160
$ ( .NOT.LSAME( UPLO , 'L' ) ) )THEN
162
ELSE IF( ( .NOT.LSAME( TRANSA, 'N' ) ).AND.
163
$ ( .NOT.LSAME( TRANSA, 'T' ) ).AND.
164
$ ( .NOT.LSAME( TRANSA, 'C' ) ) )THEN
166
ELSE IF( ( .NOT.LSAME( DIAG , 'U' ) ).AND.
167
$ ( .NOT.LSAME( DIAG , 'N' ) ) )THEN
169
ELSE IF( M .LT.0 )THEN
171
ELSE IF( N .LT.0 )THEN
173
ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN
175
ELSE IF( LDB.LT.MAX( 1, M ) )THEN
179
CALL XERBLA( 'DTRMM ', INFO )
183
* Quick return if possible.
188
* And when alpha.eq.zero.
190
IF( ALPHA.EQ.ZERO )THEN
199
* Start the operations.
202
IF( LSAME( TRANSA, 'N' ) )THEN
204
* Form B := alpha*A*B.
209
IF( B( K, J ).NE.ZERO )THEN
210
TEMP = ALPHA*B( K, J )
212
B( I, J ) = B( I, J ) + TEMP*A( I, K )
215
$ TEMP = TEMP*A( K, K )
223
IF( B( K, J ).NE.ZERO )THEN
224
TEMP = ALPHA*B( K, J )
227
$ B( K, J ) = B( K, J )*A( K, K )
229
B( I, J ) = B( I, J ) + TEMP*A( I, K )
237
* Form B := alpha*B*A'.
244
$ TEMP = TEMP*A( I, I )
246
TEMP = TEMP + A( K, I )*B( K, J )
248
B( I, J ) = ALPHA*TEMP
256
$ TEMP = TEMP*A( I, I )
258
TEMP = TEMP + A( K, I )*B( K, J )
260
B( I, J ) = ALPHA*TEMP
266
IF( LSAME( TRANSA, 'N' ) )THEN
268
* Form B := alpha*B*A.
274
$ TEMP = TEMP*A( J, J )
276
B( I, J ) = TEMP*B( I, J )
279
IF( A( K, J ).NE.ZERO )THEN
280
TEMP = ALPHA*A( K, J )
282
B( I, J ) = B( I, J ) + TEMP*B( I, K )
291
$ TEMP = TEMP*A( J, J )
293
B( I, J ) = TEMP*B( I, J )
296
IF( A( K, J ).NE.ZERO )THEN
297
TEMP = ALPHA*A( K, J )
299
B( I, J ) = B( I, J ) + TEMP*B( I, K )
307
* Form B := alpha*B*A'.
312
IF( A( J, K ).NE.ZERO )THEN
313
TEMP = ALPHA*A( J, K )
315
B( I, J ) = B( I, J ) + TEMP*B( I, K )
321
$ TEMP = TEMP*A( K, K )
322
IF( TEMP.NE.ONE )THEN
324
B( I, K ) = TEMP*B( I, K )
331
IF( A( J, K ).NE.ZERO )THEN
332
TEMP = ALPHA*A( J, K )
334
B( I, J ) = B( I, J ) + TEMP*B( I, K )
340
$ TEMP = TEMP*A( K, K )
341
IF( TEMP.NE.ONE )THEN
343
B( I, K ) = TEMP*B( I, K )