1*> \brief \b ZGEMQR 2* 3* Definition: 4* =========== 5* 6* SUBROUTINE ZGEMQR( SIDE, TRANS, M, N, K, A, LDA, T, 7* $ TSIZE, C, LDC, WORK, LWORK, INFO ) 8* 9* 10* .. Scalar Arguments .. 11* CHARACTER SIDE, TRANS 12* INTEGER INFO, LDA, M, N, K, LDT, TSIZE, LWORK, LDC 13* .. 14* .. Array Arguments .. 15* COMPLEX*16 A( LDA, * ), T( * ), C( LDC, * ), WORK( * ) 16* .. 17* 18*> \par Purpose: 19* ============= 20*> 21*> \verbatim 22*> 23*> ZGEMQR overwrites the general real M-by-N matrix C with 24*> 25*> SIDE = 'L' SIDE = 'R' 26*> TRANS = 'N': Q * C C * Q 27*> TRANS = 'T': Q**H * C C * Q**H 28*> 29*> where Q is a complex unitary matrix defined as the product 30*> of blocked elementary reflectors computed by tall skinny 31*> QR factorization (ZGEQR) 32*> 33*> \endverbatim 34* 35* Arguments: 36* ========== 37* 38*> \param[in] SIDE 39*> \verbatim 40*> SIDE is CHARACTER*1 41*> = 'L': apply Q or Q**H from the Left; 42*> = 'R': apply Q or Q**H from the Right. 43*> \endverbatim 44*> 45*> \param[in] TRANS 46*> \verbatim 47*> TRANS is CHARACTER*1 48*> = 'N': No transpose, apply Q; 49*> = 'C': Conjugate transpose, apply Q**H. 50*> \endverbatim 51*> 52*> \param[in] M 53*> \verbatim 54*> M is INTEGER 55*> The number of rows of the matrix A. M >=0. 56*> \endverbatim 57*> 58*> \param[in] N 59*> \verbatim 60*> N is INTEGER 61*> The number of columns of the matrix C. N >= 0. 62*> \endverbatim 63*> 64*> \param[in] K 65*> \verbatim 66*> K is INTEGER 67*> The number of elementary reflectors whose product defines 68*> the matrix Q. 69*> If SIDE = 'L', M >= K >= 0; 70*> if SIDE = 'R', N >= K >= 0. 71*> \endverbatim 72*> 73*> \param[in] A 74*> \verbatim 75*> A is COMPLEX*16 array, dimension (LDA,K) 76*> Part of the data structure to represent Q as returned by ZGEQR. 77*> \endverbatim 78*> 79*> \param[in] LDA 80*> \verbatim 81*> LDA is INTEGER 82*> The leading dimension of the array A. 83*> If SIDE = 'L', LDA >= max(1,M); 84*> if SIDE = 'R', LDA >= max(1,N). 85*> \endverbatim 86*> 87*> \param[in] T 88*> \verbatim 89*> T is COMPLEX*16 array, dimension (MAX(5,TSIZE)). 90*> Part of the data structure to represent Q as returned by ZGEQR. 91*> \endverbatim 92*> 93*> \param[in] TSIZE 94*> \verbatim 95*> TSIZE is INTEGER 96*> The dimension of the array T. TSIZE >= 5. 97*> \endverbatim 98*> 99*> \param[in,out] C 100*> \verbatim 101*> C is COMPLEX*16 array, dimension (LDC,N) 102*> On entry, the M-by-N matrix C. 103*> On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q. 104*> \endverbatim 105*> 106*> \param[in] LDC 107*> \verbatim 108*> LDC is INTEGER 109*> The leading dimension of the array C. LDC >= max(1,M). 110*> \endverbatim 111*> 112*> \param[out] WORK 113*> \verbatim 114*> (workspace) COMPLEX*16 array, dimension (MAX(1,LWORK)) 115*> \endverbatim 116*> 117*> \param[in] LWORK 118*> \verbatim 119*> LWORK is INTEGER 120*> The dimension of the array WORK. 121*> If LWORK = -1, then a workspace query is assumed. The routine 122*> only calculates the size of the WORK array, returns this 123*> value as WORK(1), and no error message related to WORK 124*> is issued by XERBLA. 125*> \endverbatim 126*> 127*> \param[out] INFO 128*> \verbatim 129*> INFO is INTEGER 130*> = 0: successful exit 131*> < 0: if INFO = -i, the i-th argument had an illegal value 132*> \endverbatim 133* 134* Authors: 135* ======== 136* 137*> \author Univ. of Tennessee 138*> \author Univ. of California Berkeley 139*> \author Univ. of Colorado Denver 140*> \author NAG Ltd. 141* 142*> \par Further Details 143* ==================== 144*> 145*> \verbatim 146*> 147*> These details are particular for this LAPACK implementation. Users should not 148*> take them for granted. These details may change in the future, and are not likely 149*> true for another LAPACK implementation. These details are relevant if one wants 150*> to try to understand the code. They are not part of the interface. 151*> 152*> In this version, 153*> 154*> T(2): row block size (MB) 155*> T(3): column block size (NB) 156*> T(6:TSIZE): data structure needed for Q, computed by 157*> ZLATSQR or ZGEQRT 158*> 159*> Depending on the matrix dimensions M and N, and row and column 160*> block sizes MB and NB returned by ILAENV, ZGEQR will use either 161*> ZLATSQR (if the matrix is tall-and-skinny) or ZGEQRT to compute 162*> the QR factorization. 163*> This version of ZGEMQR will use either ZLAMTSQR or ZGEMQRT to 164*> multiply matrix Q by another matrix. 165*> Further Details in ZLAMTSQR or ZGEMQRT. 166*> 167*> \endverbatim 168*> 169* ===================================================================== 170 SUBROUTINE ZGEMQR( SIDE, TRANS, M, N, K, A, LDA, T, TSIZE, 171 $ C, LDC, WORK, LWORK, INFO ) 172* 173* -- LAPACK computational routine -- 174* -- LAPACK is a software package provided by Univ. of Tennessee, -- 175* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 176* 177* .. Scalar Arguments .. 178 CHARACTER SIDE, TRANS 179 INTEGER INFO, LDA, M, N, K, TSIZE, LWORK, LDC 180* .. 181* .. Array Arguments .. 182 COMPLEX*16 A( LDA, * ), T( * ), C( LDC, * ), WORK( * ) 183* .. 184* 185* ===================================================================== 186* 187* .. 188* .. Local Scalars .. 189 LOGICAL LEFT, RIGHT, TRAN, NOTRAN, LQUERY 190 INTEGER MB, NB, LW, NBLCKS, MN 191* .. 192* .. External Functions .. 193 LOGICAL LSAME 194 EXTERNAL LSAME 195* .. 196* .. External Subroutines .. 197 EXTERNAL ZGEMQRT, ZLAMTSQR, XERBLA 198* .. 199* .. Intrinsic Functions .. 200 INTRINSIC INT, MAX, MIN, MOD 201* .. 202* .. Executable Statements .. 203* 204* Test the input arguments 205* 206 LQUERY = LWORK.EQ.-1 207 NOTRAN = LSAME( TRANS, 'N' ) 208 TRAN = LSAME( TRANS, 'C' ) 209 LEFT = LSAME( SIDE, 'L' ) 210 RIGHT = LSAME( SIDE, 'R' ) 211* 212 MB = INT( T( 2 ) ) 213 NB = INT( T( 3 ) ) 214 IF( LEFT ) THEN 215 LW = N * NB 216 MN = M 217 ELSE 218 LW = MB * NB 219 MN = N 220 END IF 221* 222 IF( ( MB.GT.K ) .AND. ( MN.GT.K ) ) THEN 223 IF( MOD( MN - K, MB - K ).EQ.0 ) THEN 224 NBLCKS = ( MN - K ) / ( MB - K ) 225 ELSE 226 NBLCKS = ( MN - K ) / ( MB - K ) + 1 227 END IF 228 ELSE 229 NBLCKS = 1 230 END IF 231* 232 INFO = 0 233 IF( .NOT.LEFT .AND. .NOT.RIGHT ) THEN 234 INFO = -1 235 ELSE IF( .NOT.TRAN .AND. .NOT.NOTRAN ) THEN 236 INFO = -2 237 ELSE IF( M.LT.0 ) THEN 238 INFO = -3 239 ELSE IF( N.LT.0 ) THEN 240 INFO = -4 241 ELSE IF( K.LT.0 .OR. K.GT.MN ) THEN 242 INFO = -5 243 ELSE IF( LDA.LT.MAX( 1, MN ) ) THEN 244 INFO = -7 245 ELSE IF( TSIZE.LT.5 ) THEN 246 INFO = -9 247 ELSE IF( LDC.LT.MAX( 1, M ) ) THEN 248 INFO = -11 249 ELSE IF( ( LWORK.LT.MAX( 1, LW ) ) .AND. ( .NOT.LQUERY ) ) THEN 250 INFO = -13 251 END IF 252* 253 IF( INFO.EQ.0 ) THEN 254 WORK( 1 ) = LW 255 END IF 256* 257 IF( INFO.NE.0 ) THEN 258 CALL XERBLA( 'ZGEMQR', -INFO ) 259 RETURN 260 ELSE IF( LQUERY ) THEN 261 RETURN 262 END IF 263* 264* Quick return if possible 265* 266 IF( MIN( M, N, K ).EQ.0 ) THEN 267 RETURN 268 END IF 269* 270 IF( ( LEFT .AND. M.LE.K ) .OR. ( RIGHT .AND. N.LE.K ) 271 $ .OR. ( MB.LE.K ) .OR. ( MB.GE.MAX( M, N, K ) ) ) THEN 272 CALL ZGEMQRT( SIDE, TRANS, M, N, K, NB, A, LDA, T( 6 ), 273 $ NB, C, LDC, WORK, INFO ) 274 ELSE 275 CALL ZLAMTSQR( SIDE, TRANS, M, N, K, MB, NB, A, LDA, T( 6 ), 276 $ NB, C, LDC, WORK, LWORK, INFO ) 277 END IF 278* 279 WORK( 1 ) = LW 280* 281 RETURN 282* 283* End of ZGEMQR 284* 285 END 286