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