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