1
SUBROUTINE ZUNMLQ( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
4
* -- LAPACK routine (version 3.0) --
5
* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
6
* Courant Institute, Argonne National Lab, and Rice University
9
* .. Scalar Arguments ..
11
INTEGER INFO, K, LDA, LDC, LWORK, M, N
13
* .. Array Arguments ..
14
COMPLEX*16 A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
20
* ZUNMLQ overwrites the general complex M-by-N matrix C with
22
* SIDE = 'L' SIDE = 'R'
23
* TRANS = 'N': Q * C C * Q
24
* TRANS = 'C': Q**H * C C * Q**H
26
* where Q is a complex unitary matrix defined as the product of k
27
* elementary reflectors
29
* Q = H(k)' . . . H(2)' H(1)'
31
* as returned by ZGELQF. Q is of order M if SIDE = 'L' and of order N
37
* SIDE (input) CHARACTER*1
38
* = 'L': apply Q or Q**H from the Left;
39
* = 'R': apply Q or Q**H from the Right.
41
* TRANS (input) CHARACTER*1
42
* = 'N': No transpose, apply Q;
43
* = 'C': Conjugate transpose, apply Q**H.
46
* The number of rows of the matrix C. M >= 0.
49
* The number of columns of the matrix C. N >= 0.
52
* The number of elementary reflectors whose product defines
54
* If SIDE = 'L', M >= K >= 0;
55
* if SIDE = 'R', N >= K >= 0.
57
* A (input) COMPLEX*16 array, dimension
58
* (LDA,M) if SIDE = 'L',
59
* (LDA,N) if SIDE = 'R'
60
* The i-th row must contain the vector which defines the
61
* elementary reflector H(i), for i = 1,2,...,k, as returned by
62
* ZGELQF in the first k rows of its array argument A.
63
* A is modified by the routine but restored on exit.
66
* The leading dimension of the array A. LDA >= max(1,K).
68
* TAU (input) COMPLEX*16 array, dimension (K)
69
* TAU(i) must contain the scalar factor of the elementary
70
* reflector H(i), as returned by ZGELQF.
72
* C (input/output) COMPLEX*16 array, dimension (LDC,N)
73
* On entry, the M-by-N matrix C.
74
* On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q.
77
* The leading dimension of the array C. LDC >= max(1,M).
79
* WORK (workspace/output) COMPLEX*16 array, dimension (LWORK)
80
* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
82
* LWORK (input) INTEGER
83
* The dimension of the array WORK.
84
* If SIDE = 'L', LWORK >= max(1,N);
85
* if SIDE = 'R', LWORK >= max(1,M).
86
* For optimum performance LWORK >= N*NB if SIDE 'L', and
87
* LWORK >= M*NB if SIDE = 'R', where NB is the optimal
90
* If LWORK = -1, then a workspace query is assumed; the routine
91
* only calculates the optimal size of the WORK array, returns
92
* this value as the first entry of the WORK array, and no error
93
* message related to LWORK is issued by XERBLA.
95
* INFO (output) INTEGER
96
* = 0: successful exit
97
* < 0: if INFO = -i, the i-th argument had an illegal value
99
* =====================================================================
103
PARAMETER ( NBMAX = 64, LDT = NBMAX+1 )
105
* .. Local Scalars ..
106
LOGICAL LEFT, LQUERY, NOTRAN
108
INTEGER I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK,
109
$ LWKOPT, MI, NB, NBMIN, NI, NQ, NW
112
COMPLEX*16 T( LDT, NBMAX )
114
* .. External Functions ..
117
EXTERNAL LSAME, ILAENV
119
* .. External Subroutines ..
120
EXTERNAL XERBLA, ZLARFB, ZLARFT, ZUNML2
122
* .. Intrinsic Functions ..
125
* .. Executable Statements ..
127
* Test the input arguments
130
LEFT = LSAME( SIDE, 'L' )
131
NOTRAN = LSAME( TRANS, 'N' )
132
LQUERY = ( LWORK.EQ.-1 )
134
* NQ is the order of Q and NW is the minimum dimension of WORK
143
IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
145
ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
147
ELSE IF( M.LT.0 ) THEN
149
ELSE IF( N.LT.0 ) THEN
151
ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
153
ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
155
ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
157
ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THEN
163
* Determine the block size. NB may be at most NBMAX, where NBMAX
164
* is used to define the local array T.
166
NB = MIN( NBMAX, ILAENV( 1, 'ZUNMLQ', SIDE // TRANS, M, N, K,
168
LWKOPT = MAX( 1, NW )*NB
173
CALL XERBLA( 'ZUNMLQ', -INFO )
175
ELSE IF( LQUERY ) THEN
179
* Quick return if possible
181
IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THEN
188
IF( NB.GT.1 .AND. NB.LT.K ) THEN
190
IF( LWORK.LT.IWS ) THEN
192
NBMIN = MAX( 2, ILAENV( 2, 'ZUNMLQ', SIDE // TRANS, M, N, K,
199
IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
203
CALL ZUNML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,
209
IF( ( LEFT .AND. NOTRAN ) .OR.
210
$ ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) THEN
215
I1 = ( ( K-1 ) / NB )*NB + 1
235
IB = MIN( NB, K-I+1 )
237
* Form the triangular factor of the block reflector
238
* H = H(i) H(i+1) . . . H(i+ib-1)
240
CALL ZLARFT( 'Forward', 'Rowwise', NQ-I+1, IB, A( I, I ),
241
$ LDA, TAU( I ), T, LDT )
244
* H or H' is applied to C(i:m,1:n)
250
* H or H' is applied to C(1:m,i:n)
258
CALL ZLARFB( SIDE, TRANST, 'Forward', 'Rowwise', MI, NI, IB,
259
$ A( I, I ), LDA, T, LDT, C( IC, JC ), LDC, WORK,