1*> \brief \b CUNMQL 2* 3* =========== DOCUMENTATION =========== 4* 5* Online html documentation available at 6* http://www.netlib.org/lapack/explore-html/ 7* 8*> \htmlonly 9*> Download CUNMQL + dependencies 10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cunmql.f"> 11*> [TGZ]</a> 12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cunmql.f"> 13*> [ZIP]</a> 14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cunmql.f"> 15*> [TXT]</a> 16*> \endhtmlonly 17* 18* Definition: 19* =========== 20* 21* SUBROUTINE CUNMQL( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, 22* WORK, LWORK, INFO ) 23* 24* .. Scalar Arguments .. 25* CHARACTER SIDE, TRANS 26* INTEGER INFO, K, LDA, LDC, LWORK, M, N 27* .. 28* .. Array Arguments .. 29* COMPLEX A( LDA, * ), C( LDC, * ), TAU( * ), 30* $ WORK( * ) 31* .. 32* 33* 34*> \par Purpose: 35* ============= 36*> 37*> \verbatim 38*> 39*> CUNMQL overwrites the general complex M-by-N matrix C with 40*> 41*> SIDE = 'L' SIDE = 'R' 42*> TRANS = 'N': Q * C C * Q 43*> TRANS = 'C': Q**H * C C * Q**H 44*> 45*> where Q is a complex unitary matrix defined as the product of k 46*> elementary reflectors 47*> 48*> Q = H(k) . . . H(2) H(1) 49*> 50*> as returned by CGEQLF. Q is of order M if SIDE = 'L' and of order N 51*> if SIDE = 'R'. 52*> \endverbatim 53* 54* Arguments: 55* ========== 56* 57*> \param[in] SIDE 58*> \verbatim 59*> SIDE is CHARACTER*1 60*> = 'L': apply Q or Q**H from the Left; 61*> = 'R': apply Q or Q**H from the Right. 62*> \endverbatim 63*> 64*> \param[in] TRANS 65*> \verbatim 66*> TRANS is CHARACTER*1 67*> = 'N': No transpose, apply Q; 68*> = 'C': Conjugate transpose, apply Q**H. 69*> \endverbatim 70*> 71*> \param[in] M 72*> \verbatim 73*> M is INTEGER 74*> The number of rows of the matrix C. M >= 0. 75*> \endverbatim 76*> 77*> \param[in] N 78*> \verbatim 79*> N is INTEGER 80*> The number of columns of the matrix C. N >= 0. 81*> \endverbatim 82*> 83*> \param[in] K 84*> \verbatim 85*> K is INTEGER 86*> The number of elementary reflectors whose product defines 87*> the matrix Q. 88*> If SIDE = 'L', M >= K >= 0; 89*> if SIDE = 'R', N >= K >= 0. 90*> \endverbatim 91*> 92*> \param[in] A 93*> \verbatim 94*> A is COMPLEX array, dimension (LDA,K) 95*> The i-th column must contain the vector which defines the 96*> elementary reflector H(i), for i = 1,2,...,k, as returned by 97*> CGEQLF in the last k columns of its array argument A. 98*> \endverbatim 99*> 100*> \param[in] LDA 101*> \verbatim 102*> LDA is INTEGER 103*> The leading dimension of the array A. 104*> If SIDE = 'L', LDA >= max(1,M); 105*> if SIDE = 'R', LDA >= max(1,N). 106*> \endverbatim 107*> 108*> \param[in] TAU 109*> \verbatim 110*> TAU is COMPLEX array, dimension (K) 111*> TAU(i) must contain the scalar factor of the elementary 112*> reflector H(i), as returned by CGEQLF. 113*> \endverbatim 114*> 115*> \param[in,out] C 116*> \verbatim 117*> C is COMPLEX array, dimension (LDC,N) 118*> On entry, the M-by-N matrix C. 119*> On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q. 120*> \endverbatim 121*> 122*> \param[in] LDC 123*> \verbatim 124*> LDC is INTEGER 125*> The leading dimension of the array C. LDC >= max(1,M). 126*> \endverbatim 127*> 128*> \param[out] WORK 129*> \verbatim 130*> WORK is COMPLEX array, dimension (MAX(1,LWORK)) 131*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 132*> \endverbatim 133*> 134*> \param[in] LWORK 135*> \verbatim 136*> LWORK is INTEGER 137*> The dimension of the array WORK. 138*> If SIDE = 'L', LWORK >= max(1,N); 139*> if SIDE = 'R', LWORK >= max(1,M). 140*> For good performance, LWORK should generally be larger. 141*> 142*> If LWORK = -1, then a workspace query is assumed; the routine 143*> only calculates the optimal size of the WORK array, returns 144*> this value as the first entry of the WORK array, and no error 145*> message related to LWORK is issued by XERBLA. 146*> \endverbatim 147*> 148*> \param[out] INFO 149*> \verbatim 150*> INFO is INTEGER 151*> = 0: successful exit 152*> < 0: if INFO = -i, the i-th argument had an illegal value 153*> \endverbatim 154* 155* Authors: 156* ======== 157* 158*> \author Univ. of Tennessee 159*> \author Univ. of California Berkeley 160*> \author Univ. of Colorado Denver 161*> \author NAG Ltd. 162* 163*> \ingroup complexOTHERcomputational 164* 165* ===================================================================== 166 SUBROUTINE CUNMQL( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, 167 $ WORK, LWORK, INFO ) 168* 169* -- LAPACK computational routine -- 170* -- LAPACK is a software package provided by Univ. of Tennessee, -- 171* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 172* 173* .. Scalar Arguments .. 174 CHARACTER SIDE, TRANS 175 INTEGER INFO, K, LDA, LDC, LWORK, M, N 176* .. 177* .. Array Arguments .. 178 COMPLEX A( LDA, * ), C( LDC, * ), TAU( * ), 179 $ WORK( * ) 180* .. 181* 182* ===================================================================== 183* 184* .. Parameters .. 185 INTEGER NBMAX, LDT, TSIZE 186 PARAMETER ( NBMAX = 64, LDT = NBMAX+1, 187 $ TSIZE = LDT*NBMAX ) 188* .. 189* .. Local Scalars .. 190 LOGICAL LEFT, LQUERY, NOTRAN 191 INTEGER I, I1, I2, I3, IB, IINFO, IWT, LDWORK, LWKOPT, 192 $ MI, NB, NBMIN, NI, NQ, NW 193* .. 194* .. External Functions .. 195 LOGICAL LSAME 196 INTEGER ILAENV 197 EXTERNAL LSAME, ILAENV 198* .. 199* .. External Subroutines .. 200 EXTERNAL CLARFB, CLARFT, CUNM2L, XERBLA 201* .. 202* .. Intrinsic Functions .. 203 INTRINSIC MAX, MIN 204* .. 205* .. Executable Statements .. 206* 207* Test the input arguments 208* 209 INFO = 0 210 LEFT = LSAME( SIDE, 'L' ) 211 NOTRAN = LSAME( TRANS, 'N' ) 212 LQUERY = ( LWORK.EQ.-1 ) 213* 214* NQ is the order of Q and NW is the minimum dimension of WORK 215* 216 IF( LEFT ) THEN 217 NQ = M 218 NW = MAX( 1, N ) 219 ELSE 220 NQ = N 221 NW = MAX( 1, M ) 222 END IF 223 IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN 224 INFO = -1 225 ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN 226 INFO = -2 227 ELSE IF( M.LT.0 ) THEN 228 INFO = -3 229 ELSE IF( N.LT.0 ) THEN 230 INFO = -4 231 ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN 232 INFO = -5 233 ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN 234 INFO = -7 235 ELSE IF( LDC.LT.MAX( 1, M ) ) THEN 236 INFO = -10 237 ELSE IF( LWORK.LT.NW .AND. .NOT.LQUERY ) THEN 238 INFO = -12 239 END IF 240* 241 IF( INFO.EQ.0 ) THEN 242* 243* Compute the workspace requirements 244* 245 IF( M.EQ.0 .OR. N.EQ.0 ) THEN 246 LWKOPT = 1 247 ELSE 248 NB = MIN( NBMAX, ILAENV( 1, 'CUNMQL', SIDE // TRANS, M, N, 249 $ K, -1 ) ) 250 LWKOPT = NW*NB + TSIZE 251 END IF 252 WORK( 1 ) = LWKOPT 253 END IF 254* 255 IF( INFO.NE.0 ) THEN 256 CALL XERBLA( 'CUNMQL', -INFO ) 257 RETURN 258 ELSE IF( LQUERY ) THEN 259 RETURN 260 END IF 261* 262* Quick return if possible 263* 264 IF( M.EQ.0 .OR. N.EQ.0 ) THEN 265 RETURN 266 END IF 267* 268* Determine the block size 269* 270 NBMIN = 2 271 LDWORK = NW 272 IF( NB.GT.1 .AND. NB.LT.K ) THEN 273 IF( LWORK.LT.LWKOPT ) THEN 274 NB = (LWORK-TSIZE) / LDWORK 275 NBMIN = MAX( 2, ILAENV( 2, 'CUNMQL', SIDE // TRANS, M, N, K, 276 $ -1 ) ) 277 END IF 278 END IF 279* 280 IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN 281* 282* Use unblocked code 283* 284 CALL CUNM2L( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, 285 $ IINFO ) 286 ELSE 287* 288* Use blocked code 289* 290 IWT = 1 + NW*NB 291 IF( ( LEFT .AND. NOTRAN ) .OR. 292 $ ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) THEN 293 I1 = 1 294 I2 = K 295 I3 = NB 296 ELSE 297 I1 = ( ( K-1 ) / NB )*NB + 1 298 I2 = 1 299 I3 = -NB 300 END IF 301* 302 IF( LEFT ) THEN 303 NI = N 304 ELSE 305 MI = M 306 END IF 307* 308 DO 10 I = I1, I2, I3 309 IB = MIN( NB, K-I+1 ) 310* 311* Form the triangular factor of the block reflector 312* H = H(i+ib-1) . . . H(i+1) H(i) 313* 314 CALL CLARFT( 'Backward', 'Columnwise', NQ-K+I+IB-1, IB, 315 $ A( 1, I ), LDA, TAU( I ), WORK( IWT ), LDT ) 316 IF( LEFT ) THEN 317* 318* H or H**H is applied to C(1:m-k+i+ib-1,1:n) 319* 320 MI = M - K + I + IB - 1 321 ELSE 322* 323* H or H**H is applied to C(1:m,1:n-k+i+ib-1) 324* 325 NI = N - K + I + IB - 1 326 END IF 327* 328* Apply H or H**H 329* 330 CALL CLARFB( SIDE, TRANS, 'Backward', 'Columnwise', MI, NI, 331 $ IB, A( 1, I ), LDA, WORK( IWT ), LDT, C, LDC, 332 $ WORK, LDWORK ) 333 10 CONTINUE 334 END IF 335 WORK( 1 ) = LWKOPT 336 RETURN 337* 338* End of CUNMQL 339* 340 END 341