1*> \brief \b ZGEQLF
2*
3*  =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6*            http://www.netlib.org/lapack/explore-html/
7*
8*> \htmlonly
9*> Download ZGEQLF + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zgeqlf.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zgeqlf.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zgeqlf.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18*  Definition:
19*  ===========
20*
21*       SUBROUTINE ZGEQLF( 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*> ZGEQLF computes a QL factorization of a complex M-by-N matrix A:
37*> A = Q * L.
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 lower triangle of the subarray
61*>          A(m-n+1:m,1:n) contains the N-by-N lower triangular matrix L;
62*>          if m <= n, the elements on and below the (n-m)-th
63*>          superdiagonal contain the M-by-N lower trapezoidal matrix L;
64*>          the remaining elements, with the array TAU, represent the
65*>          unitary matrix Q as a product of elementary reflectors
66*>          (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,N).
92*>          For optimum performance LWORK >= N*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(k) . . . H(2) H(1), 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(m-k+i+1:m) = 0 and v(m-k+i) = 1; v(1:m-k+i-1) is stored on exit in
133*>  A(1:m-k+i-1,n-k+i), and tau in TAU(i).
134*> \endverbatim
135*>
136*  =====================================================================
137      SUBROUTINE ZGEQLF( 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, ZGEQL2, 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, 'ZGEQLF', ' ', M, N, -1, -1 )
187            LWKOPT = N*NB
188         END IF
189         WORK( 1 ) = LWKOPT
190*
191         IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
192            INFO = -7
193         END IF
194      END IF
195*
196      IF( INFO.NE.0 ) THEN
197         CALL XERBLA( 'ZGEQLF', -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 = N
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, 'ZGEQLF', ' ', M, N, -1, -1 ) )
217         IF( NX.LT.K ) THEN
218*
219*           Determine if workspace is large enough for blocked code.
220*
221            LDWORK = N
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, 'ZGEQLF', ' ', 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 columns 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 QL factorization of the current block
247*           A(1:m-k+i+ib-1,n-k+i:n-k+i+ib-1)
248*
249            CALL ZGEQL2( M-K+I+IB-1, IB, A( 1, N-K+I ), LDA, TAU( I ),
250     $                   WORK, IINFO )
251            IF( N-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', 'Columnwise', M-K+I+IB-1, IB,
257     $                      A( 1, N-K+I ), LDA, TAU( I ), WORK, LDWORK )
258*
259*              Apply H**H to A(1:m-k+i+ib-1,1:n-k+i-1) from the left
260*
261               CALL ZLARFB( 'Left', 'Conjugate transpose', 'Backward',
262     $                      'Columnwise', M-K+I+IB-1, N-K+I-1, IB,
263     $                      A( 1, N-K+I ), 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 ZGEQL2( MU, NU, A, LDA, TAU, WORK, IINFO )
278*
279      WORK( 1 ) = IWS
280      RETURN
281*
282*     End of ZGEQLF
283*
284      END
285