ztrsm(3f) - [BLAS:COMPLEX_16_BLAS_LEVEL3]
subroutine ztrsm(side,uplo,transa,diag,m,n,alpha,a,lda,b,ldb)
.. Scalar Arguments ..
complex(kind=real64),intent(in) :: alpha
integer,intent(in) :: lda,ldb,m,n
character,intent(in) :: diag,side,transa,uplo
..
.. Array Arguments ..
complex(kind=real64),intent(in) :: a(lda,*)
complex(kind=real64),intent(inout) :: b(ldb,*)
..
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.
SIDE
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.
UPLO
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.
TRANSA
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.
DIAG
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.
M
M is INTEGER
On entry, M specifies the number of rows of B. M must be at
least zero.
N
N is INTEGER
On entry, N specifies the number of columns of B. N must be
at least zero.
ALPHA
ALPHA is complex(kind=real64)
On entry, ALPHA specifies the scalar alpha. When alpha is
zero then A is not referenced and B need not be set before
entry.
A
A is complex(kind=real64) 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.
LDA
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 ).
B
B is complex(kind=real64) 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.
LDB
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 ).
date:December 2016
FURTHER DETAILS
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.
Online html documentation available at
http://www.netlib.org/lapack/explore-html/
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
character(len=1), | intent(in) | :: | side | |||
character(len=1), | intent(in) | :: | uplo | |||
character(len=1), | intent(in) | :: | transa | |||
character(len=1), | intent(in) | :: | diag | |||
integer, | intent(in) | :: | m | |||
integer, | intent(in) | :: | n | |||
complex(kind=real64), | intent(in) | :: | alpha | |||
complex(kind=real64), | intent(in) | :: | a(lda,*) | |||
integer, | intent(in) | :: | lda | |||
complex(kind=real64), | intent(inout) | :: | b(ldb,*) | |||
integer, | intent(in) | :: | ldb |
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
integer, | public | :: | i | ||||
integer, | public | :: | info | ||||
integer, | public | :: | j | ||||
integer, | public | :: | k | ||||
logical, | public | :: | lside | ||||
logical, | public | :: | noconj | ||||
logical, | public | :: | nounit | ||||
integer, | public | :: | nrowa | ||||
complex(kind=real64), | public, | parameter | :: | one | = | (1.0d+0,0.0d+0) | |
complex(kind=real64), | public | :: | temp | ||||
logical, | public | :: | upper | ||||
complex(kind=real64), | public, | parameter | :: | zero | = | (0.0d+0,0.0d+0) |
subroutine ztrsm(side,uplo,transa,diag,m,n,alpha,a,lda,b,ldb)
implicit none
!
! -- Reference BLAS level3 routine (version 3.7.0) --
! -- Reference BLAS is a software package provided by Univ. of Tennessee, --
! -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! December 2016
!
! .. Scalar Arguments ..
complex(kind=real64),intent(in) :: alpha
integer,intent(in) :: lda,ldb,m,n
character,intent(in) :: diag,side,transa,uplo
! ..
! .. Array Arguments ..
complex(kind=real64),intent(in) :: a(lda,*)
complex(kind=real64),intent(inout) :: b(ldb,*)
! ..
!
! =====================================================================
!
! .. External Functions ..
! LOGICAL LSAME
! EXTERNAL LSAME
! ..
! .. External Subroutines ..
! EXTERNAL XERBLA
! ..
! .. Intrinsic Functions ..
intrinsic dconjg,max
! ..
! .. Local Scalars ..
complex(kind=real64) :: temp
integer i,info,j,k,nrowa
logical lside,noconj,nounit,upper
! ..
! .. Parameters ..
complex(kind=real64) :: one
parameter (one= (1.0d+0,0.0d+0))
complex(kind=real64) :: 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
endif
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
elseif ((.not.upper) .and. (.not.lsame(uplo,'L'))) then
info = 2
elseif ((.not.lsame(transa,'N')) .and. (.not.lsame(transa,'T')) .and. (.not.lsame(transa,'C'))) then
info = 3
elseif ((.not.lsame(diag,'U')) .and. (.not.lsame(diag,'N'))) then
info = 4
elseif (m.lt.0) then
info = 5
elseif (n.lt.0) then
info = 6
elseif (lda.lt.max(1,nrowa)) then
info = 9
elseif (ldb.lt.max(1,m)) then
info = 11
endif
if (info.ne.0) then
call xerbla('ZTRSM ',info)
return
endif
!
! Quick return if possible.
!
if (m.eq.0 .or. n.eq.0) return
!
! And when alpha.eq.zero.
!
if (alpha.eq.zero) then
do j = 1,n
do i = 1,m
b(i,j) = zero
enddo
enddo
return
endif
!
! Start the operations.
!
if (lside) then
if (lsame(transa,'N')) then
!
! Form B := alpha*inv( A )*B.
!
if (upper) then
do j = 1,n
if (alpha.ne.one) then
do i = 1,m
b(i,j) = alpha*b(i,j)
enddo
endif
do k = m,1,-1
if (b(k,j).ne.zero) then
if (nounit) b(k,j) = b(k,j)/a(k,k)
do i = 1,k - 1
b(i,j) = b(i,j) - b(k,j)*a(i,k)
enddo
endif
enddo
enddo
else
do j = 1,n
if (alpha.ne.one) then
do i = 1,m
b(i,j) = alpha*b(i,j)
enddo
endif
do k = 1,m
if (b(k,j).ne.zero) then
if (nounit) b(k,j) = b(k,j)/a(k,k)
do i = k + 1,m
b(i,j) = b(i,j) - b(k,j)*a(i,k)
enddo
endif
enddo
enddo
endif
else
!
! Form B := alpha*inv( A**T )*B
! or B := alpha*inv( A**H )*B.
!
if (upper) then
do j = 1,n
do i = 1,m
temp = alpha*b(i,j)
if (noconj) then
do k = 1,i - 1
temp = temp - a(k,i)*b(k,j)
enddo
if (nounit) temp = temp/a(i,i)
else
do k = 1,i - 1
temp = temp - dconjg(a(k,i))*b(k,j)
enddo
if (nounit) temp = temp/dconjg(a(i,i))
endif
b(i,j) = temp
enddo
enddo
else
do j = 1,n
do i = m,1,-1
temp = alpha*b(i,j)
if (noconj) then
do k = i + 1,m
temp = temp - a(k,i)*b(k,j)
enddo
if (nounit) temp = temp/a(i,i)
else
do k = i + 1,m
temp = temp - dconjg(a(k,i))*b(k,j)
enddo
if (nounit) temp = temp/dconjg(a(i,i))
endif
b(i,j) = temp
enddo
enddo
endif
endif
else
if (lsame(transa,'N')) then
!
! Form B := alpha*B*inv( A ).
!
if (upper) then
do j = 1,n
if (alpha.ne.one) then
do i = 1,m
b(i,j) = alpha*b(i,j)
enddo
endif
do k = 1,j - 1
if (a(k,j).ne.zero) then
do i = 1,m
b(i,j) = b(i,j) - a(k,j)*b(i,k)
enddo
endif
enddo
if (nounit) then
temp = one/a(j,j)
do i = 1,m
b(i,j) = temp*b(i,j)
enddo
endif
enddo
else
do j = n,1,-1
if (alpha.ne.one) then
do i = 1,m
b(i,j) = alpha*b(i,j)
enddo
endif
do k = j + 1,n
if (a(k,j).ne.zero) then
do i = 1,m
b(i,j) = b(i,j) - a(k,j)*b(i,k)
enddo
endif
enddo
if (nounit) then
temp = one/a(j,j)
do i = 1,m
b(i,j) = temp*b(i,j)
enddo
endif
enddo
endif
else
!
! Form B := alpha*B*inv( A**T )
! or B := alpha*B*inv( A**H ).
!
if (upper) then
do k = n,1,-1
if (nounit) then
if (noconj) then
temp = one/a(k,k)
else
temp = one/dconjg(a(k,k))
endif
do i = 1,m
b(i,k) = temp*b(i,k)
enddo
endif
do j = 1,k - 1
if (a(j,k).ne.zero) then
if (noconj) then
temp = a(j,k)
else
temp = dconjg(a(j,k))
endif
do i = 1,m
b(i,j) = b(i,j) - temp*b(i,k)
enddo
endif
enddo
if (alpha.ne.one) then
do i = 1,m
b(i,k) = alpha*b(i,k)
enddo
endif
enddo
else
do k = 1,n
if (nounit) then
if (noconj) then
temp = one/a(k,k)
else
temp = one/dconjg(a(k,k))
endif
do i = 1,m
b(i,k) = temp*b(i,k)
enddo
endif
do j = k + 1,n
if (a(j,k).ne.zero) then
if (noconj) then
temp = a(j,k)
else
temp = dconjg(a(j,k))
endif
do i = 1,m
b(i,j) = b(i,j) - temp*b(i,k)
enddo
endif
enddo
if (alpha.ne.one) then
do i = 1,m
b(i,k) = alpha*b(i,k)
enddo
endif
enddo
endif
endif
endif
end subroutine ztrsm