1*> \brief \b ZGERQF 2* 3* =========== DOCUMENTATION =========== 4* 5* Online html documentation available at 6* http://www.netlib.org/lapack/explore-html/ 7* 8*> \htmlonly 9*> Download ZGERQF + dependencies 10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zgerqf.f"> 11*> [TGZ]</a> 12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zgerqf.f"> 13*> [ZIP]</a> 14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zgerqf.f"> 15*> [TXT]</a> 16*> \endhtmlonly 17* 18* Definition: 19* =========== 20* 21* SUBROUTINE ZGERQF( M, N, A, LDA, TAU, WORK, LWORK, INFO ) 22* 23* .. Scalar Arguments .. 24* INTEGER INFO, LDA, LWORK, M, N 25* .. 26* .. Array Arguments .. 27* COMPLEX*16 A( LDA, * ), TAU( * ), WORK( * ) 28* .. 29* 30* 31*> \par Purpose: 32* ============= 33*> 34*> \verbatim 35*> 36*> ZGERQF computes an RQ factorization of a complex M-by-N matrix A: 37*> A = R * Q. 38*> \endverbatim 39* 40* Arguments: 41* ========== 42* 43*> \param[in] M 44*> \verbatim 45*> M is INTEGER 46*> The number of rows of the matrix A. M >= 0. 47*> \endverbatim 48*> 49*> \param[in] N 50*> \verbatim 51*> N is INTEGER 52*> The number of columns of the matrix A. N >= 0. 53*> \endverbatim 54*> 55*> \param[in,out] A 56*> \verbatim 57*> A is COMPLEX*16 array, dimension (LDA,N) 58*> On entry, the M-by-N matrix A. 59*> On exit, 60*> if m <= n, the upper triangle of the subarray 61*> A(1:m,n-m+1:n) contains the M-by-M upper triangular matrix R; 62*> if m >= n, the elements on and above the (m-n)-th subdiagonal 63*> contain the M-by-N upper trapezoidal matrix R; 64*> the remaining elements, with the array TAU, represent the 65*> unitary matrix Q as a product of min(m,n) elementary 66*> reflectors (see Further Details). 67*> \endverbatim 68*> 69*> \param[in] LDA 70*> \verbatim 71*> LDA is INTEGER 72*> The leading dimension of the array A. LDA >= max(1,M). 73*> \endverbatim 74*> 75*> \param[out] TAU 76*> \verbatim 77*> TAU is COMPLEX*16 array, dimension (min(M,N)) 78*> The scalar factors of the elementary reflectors (see Further 79*> Details). 80*> \endverbatim 81*> 82*> \param[out] WORK 83*> \verbatim 84*> WORK is COMPLEX*16 array, dimension (MAX(1,LWORK)) 85*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 86*> \endverbatim 87*> 88*> \param[in] LWORK 89*> \verbatim 90*> LWORK is INTEGER 91*> The dimension of the array WORK. LWORK >= max(1,M). 92*> For optimum performance LWORK >= M*NB, where NB is 93*> the optimal blocksize. 94*> 95*> If LWORK = -1, then a workspace query is assumed; the routine 96*> only calculates the optimal size of the WORK array, returns 97*> this value as the first entry of the WORK array, and no error 98*> message related to LWORK is issued by XERBLA. 99*> \endverbatim 100*> 101*> \param[out] INFO 102*> \verbatim 103*> INFO is INTEGER 104*> = 0: successful exit 105*> < 0: if INFO = -i, the i-th argument had an illegal value 106*> \endverbatim 107* 108* Authors: 109* ======== 110* 111*> \author Univ. of Tennessee 112*> \author Univ. of California Berkeley 113*> \author Univ. of Colorado Denver 114*> \author NAG Ltd. 115* 116*> \ingroup complex16GEcomputational 117* 118*> \par Further Details: 119* ===================== 120*> 121*> \verbatim 122*> 123*> The matrix Q is represented as a product of elementary reflectors 124*> 125*> Q = H(1)**H H(2)**H . . . H(k)**H, where k = min(m,n). 126*> 127*> Each H(i) has the form 128*> 129*> H(i) = I - tau * v * v**H 130*> 131*> where tau is a complex scalar, and v is a complex vector with 132*> v(n-k+i+1:n) = 0 and v(n-k+i) = 1; conjg(v(1:n-k+i-1)) is stored on 133*> exit in A(m-k+i,1:n-k+i-1), and tau in TAU(i). 134*> \endverbatim 135*> 136* ===================================================================== 137 SUBROUTINE ZGERQF( M, N, A, LDA, TAU, WORK, LWORK, INFO ) 138* 139* -- LAPACK computational routine -- 140* -- LAPACK is a software package provided by Univ. of Tennessee, -- 141* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 142* 143* .. Scalar Arguments .. 144 INTEGER INFO, LDA, LWORK, M, N 145* .. 146* .. Array Arguments .. 147 COMPLEX*16 A( LDA, * ), TAU( * ), WORK( * ) 148* .. 149* 150* ===================================================================== 151* 152* .. Local Scalars .. 153 LOGICAL LQUERY 154 INTEGER I, IB, IINFO, IWS, K, KI, KK, LDWORK, LWKOPT, 155 $ MU, NB, NBMIN, NU, NX 156* .. 157* .. External Subroutines .. 158 EXTERNAL XERBLA, ZGERQ2, ZLARFB, ZLARFT 159* .. 160* .. Intrinsic Functions .. 161 INTRINSIC MAX, MIN 162* .. 163* .. External Functions .. 164 INTEGER ILAENV 165 EXTERNAL ILAENV 166* .. 167* .. Executable Statements .. 168* 169* Test the input arguments 170* 171 INFO = 0 172 LQUERY = ( LWORK.EQ.-1 ) 173 IF( M.LT.0 ) THEN 174 INFO = -1 175 ELSE IF( N.LT.0 ) THEN 176 INFO = -2 177 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN 178 INFO = -4 179 END IF 180* 181 IF( INFO.EQ.0 ) THEN 182 K = MIN( M, N ) 183 IF( K.EQ.0 ) THEN 184 LWKOPT = 1 185 ELSE 186 NB = ILAENV( 1, 'ZGERQF', ' ', M, N, -1, -1 ) 187 LWKOPT = M*NB 188 END IF 189 WORK( 1 ) = LWKOPT 190* 191 IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN 192 INFO = -7 193 END IF 194 END IF 195* 196 IF( INFO.NE.0 ) THEN 197 CALL XERBLA( 'ZGERQF', -INFO ) 198 RETURN 199 ELSE IF( LQUERY ) THEN 200 RETURN 201 END IF 202* 203* Quick return if possible 204* 205 IF( K.EQ.0 ) THEN 206 RETURN 207 END IF 208* 209 NBMIN = 2 210 NX = 1 211 IWS = M 212 IF( NB.GT.1 .AND. NB.LT.K ) THEN 213* 214* Determine when to cross over from blocked to unblocked code. 215* 216 NX = MAX( 0, ILAENV( 3, 'ZGERQF', ' ', M, N, -1, -1 ) ) 217 IF( NX.LT.K ) THEN 218* 219* Determine if workspace is large enough for blocked code. 220* 221 LDWORK = M 222 IWS = LDWORK*NB 223 IF( LWORK.LT.IWS ) THEN 224* 225* Not enough workspace to use optimal NB: reduce NB and 226* determine the minimum value of NB. 227* 228 NB = LWORK / LDWORK 229 NBMIN = MAX( 2, ILAENV( 2, 'ZGERQF', ' ', M, N, -1, 230 $ -1 ) ) 231 END IF 232 END IF 233 END IF 234* 235 IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN 236* 237* Use blocked code initially. 238* The last kk rows are handled by the block method. 239* 240 KI = ( ( K-NX-1 ) / NB )*NB 241 KK = MIN( K, KI+NB ) 242* 243 DO 10 I = K - KK + KI + 1, K - KK + 1, -NB 244 IB = MIN( K-I+1, NB ) 245* 246* Compute the RQ factorization of the current block 247* A(m-k+i:m-k+i+ib-1,1:n-k+i+ib-1) 248* 249 CALL ZGERQ2( IB, N-K+I+IB-1, A( M-K+I, 1 ), LDA, TAU( I ), 250 $ WORK, IINFO ) 251 IF( M-K+I.GT.1 ) THEN 252* 253* Form the triangular factor of the block reflector 254* H = H(i+ib-1) . . . H(i+1) H(i) 255* 256 CALL ZLARFT( 'Backward', 'Rowwise', N-K+I+IB-1, IB, 257 $ A( M-K+I, 1 ), LDA, TAU( I ), WORK, LDWORK ) 258* 259* Apply H to A(1:m-k+i-1,1:n-k+i+ib-1) from the right 260* 261 CALL ZLARFB( 'Right', 'No transpose', 'Backward', 262 $ 'Rowwise', M-K+I-1, N-K+I+IB-1, IB, 263 $ A( M-K+I, 1 ), LDA, WORK, LDWORK, A, LDA, 264 $ WORK( IB+1 ), LDWORK ) 265 END IF 266 10 CONTINUE 267 MU = M - K + I + NB - 1 268 NU = N - K + I + NB - 1 269 ELSE 270 MU = M 271 NU = N 272 END IF 273* 274* Use unblocked code to factor the last or only block 275* 276 IF( MU.GT.0 .AND. NU.GT.0 ) 277 $ CALL ZGERQ2( MU, NU, A, LDA, TAU, WORK, IINFO ) 278* 279 WORK( 1 ) = IWS 280 RETURN 281* 282* End of ZGERQF 283* 284 END 285