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