5 * SUBROUTINE CGEMQR( SIDE, TRANS, M, N, K, A, LDA, WORK1,
6 * $ LWORK1, C, LDC, WORK2, LWORK2, INFO )
9 * .. Scalar Arguments ..
10 * CHARACTER SIDE, TRANS
11 * INTEGER INFO, LDA, M, N, K, LDT, LWORK1, LWORK2, LDC
13 * .. Array Arguments ..
14 * COMPLEX A( LDA, * ), WORK1( * ), C(LDC, * ),
21 *> CGEMQR overwrites the general real M-by-N matrix C with
24 *> SIDE = 'L' SIDE = 'R'
25 *> TRANS = 'N': Q * C C * Q
26 *> TRANS = 'T': Q**T * C C * Q**T
27 *> where Q is a complex orthogonal matrix defined as the product
28 *> of blocked elementary reflectors computed by tall skinny
29 *> QR factorization (CGEQR)
36 *> SIDE is CHARACTER*1
37 *> = 'L': apply Q or Q**T from the Left;
38 *> = 'R': apply Q or Q**T from the Right.
41 *> TRANS is CHARACTER*1
42 *> = 'N': No transpose, apply Q;
43 *> = 'T': Transpose, apply Q**T.
47 *> The number of rows of the matrix A. M >=0.
53 *> The number of columns of the matrix C. M >= N >= 0.
59 *> The number of elementary reflectors whose product defines
67 *> A is COMPLEX array, dimension (LDA,K)
68 *> The i-th column must contain the vector which defines the
69 *> blockedelementary reflector H(i), for i = 1,2,...,k, as
70 *> returned by DGETSQR in the first k columns of
71 *> its array argument A.
77 *> The leading dimension of the array A.
78 *> If SIDE = 'L', LDA >= max(1,M);
79 *> if SIDE = 'R', LDA >= max(1,N).
84 *> WORK1 is COMPLEX array, dimension (MAX(1,LWORK1)) as
85 *> it is returned by GEQR.
91 *> The dimension of the array WORK1.
95 *> C is COMPLEX array, dimension (LDC,N)
96 *> On entry, the M-by-N matrix C.
97 *> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.
101 *> The leading dimension of the array C. LDC >= max(1,M).
105 *> (workspace) COMPLEX array, dimension (MAX(1,LWORK2))
111 *> The dimension of the array WORK2.
112 *> If LWORK2 = -1, then a workspace query is assumed; the routine
113 *> only calculates the optimal size of the WORK2 array, returns
114 *> this value as the third entry of the WORK2 array (WORK2(1)),
115 *> and no error message related to LWORK2 is issued by XERBLA.
121 *> = 0: successful exit
122 *> < 0: if INFO = -i, the i-th argument had an illegal value
128 *> \author Univ. of Tennessee
129 *> \author Univ. of California Berkeley
130 *> \author Univ. of Colorado Denver
133 *> \par Further Details:
134 * =====================
137 *> Depending on the matrix dimensions M and N, and row and column
138 *> block sizes MB and NB returned by ILAENV, GEQR will use either
139 *> LATSQR (if the matrix is tall-and-skinny) or GEQRT to compute
140 *> the QR decomposition.
141 *> The output of LATSQR or GEQRT representing Q is stored in A and in
142 *> array WORK1(6:LWORK1) for later use.
143 *> WORK1(2:5) contains the matrix dimensions M,N and block sizes MB,NB
144 *> which are needed to interpret A and WORK1(6:LWORK1) for later use.
145 *> WORK1(1)=1 indicates that the code needed to take WORK1(2:5) and
146 *> decide whether LATSQR or GEQRT was used is the same as used below in
147 *> GEQR. For a detailed description of A and WORK1(6:LWORK1), see
148 *> Further Details in LATSQR or GEQRT.
151 * =====================================================================
152 SUBROUTINE CGEMQR( SIDE, TRANS, M, N, K, A, LDA, WORK1, LWORK1,
153 $ C, LDC, WORK2, LWORK2, INFO )
155 * -- LAPACK computational routine (version 3.5.0) --
156 * -- LAPACK is a software package provided by Univ. of Tennessee, --
157 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
160 * .. Scalar Arguments ..
161 CHARACTER SIDE, TRANS
162 INTEGER INFO, LDA, M, N, K, LWORK1, LWORK2, LDC
164 * .. Array Arguments ..
165 COMPLEX A( LDA, * ), WORK1( * ), C(LDC, * ),
169 * =====================================================================
172 * .. Local Scalars ..
173 LOGICAL LEFT, RIGHT, TRAN, NOTRAN, LQUERY
174 INTEGER MB, NB, I, II, KK, LW, NBLCKS, MN
176 * .. External Functions ..
179 * .. External Subroutines ..
180 EXTERNAL CGEMQRT, CLAMTSQR, XERBLA
181 * .. Intrinsic Functions ..
182 INTRINSIC INT, MAX, MIN, MOD
184 * .. Executable Statements ..
186 * Test the input arguments
189 NOTRAN = LSAME( TRANS, 'N' )
190 TRAN = LSAME( TRANS, 'C' )
191 LEFT = LSAME( SIDE, 'L' )
192 RIGHT = LSAME( SIDE, 'R' )
204 IF ((MB.GT.K).AND.(MN.GT.K)) THEN
205 IF(MOD(MN-K, MB-K).EQ.0) THEN
206 NBLCKS = (MN-K)/(MB-K)
208 NBLCKS = (MN-K)/(MB-K) + 1
215 IF( .NOT.LEFT .AND. .NOT.RIGHT ) THEN
217 ELSE IF( .NOT.TRAN .AND. .NOT.NOTRAN ) THEN
219 ELSE IF( M.LT.0 ) THEN
221 ELSE IF( N.LT.0 ) THEN
223 ELSE IF( K.LT.0 ) THEN
225 ELSE IF( LDA.LT.MAX( 1, K ) ) THEN
227 ELSE IF( LWORK1.LT.MAX( 1, NB*K*NBLCKS+5 )) THEN
229 ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
231 ELSE IF(( LWORK2.LT.MAX(1,LW)).AND.(.NOT.LQUERY)) THEN
235 * Determine the block size if it is tall skinny or short and wide
242 CALL XERBLA( 'CGEMQR', -INFO )
244 ELSE IF (LQUERY) THEN
248 * Quick return if possible
250 IF( MIN(M,N,K).EQ.0 ) THEN
254 IF((LEFT.AND.M.LE.K).OR.(RIGHT.AND.N.LE.K).OR.(MB.LE.K).OR.
255 $ (MB.GE.MAX(M,N,K))) THEN
256 CALL CGEMQRT( SIDE, TRANS, M, N, K, NB, A, LDA,
257 $ WORK1(6), NB, C, LDC, WORK2, INFO)
259 CALL CLAMTSQR( SIDE, TRANS, M, N, K, MB, NB, A, LDA, WORK1(6),
260 $ NB, C, LDC, WORK2, LWORK2, INFO )