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