Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/lapack/cgeqp3.f
5218 views
1
SUBROUTINE CGEQP3( M, N, A, LDA, JPVT, TAU, WORK, LWORK, RWORK,
2
$ INFO )
3
*
4
* -- LAPACK routine (version 3.0) --
5
* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
6
* Courant Institute, Argonne National Lab, and Rice University
7
* June 30, 1999
8
*
9
* .. Scalar Arguments ..
10
INTEGER INFO, LDA, LWORK, M, N
11
* ..
12
* .. Array Arguments ..
13
INTEGER JPVT( * )
14
REAL RWORK( * )
15
COMPLEX A( LDA, * ), TAU( * ), WORK( * )
16
* ..
17
*
18
* Purpose
19
* =======
20
*
21
* CGEQP3 computes a QR factorization with column pivoting of a
22
* matrix A: A*P = Q*R using Level 3 BLAS.
23
*
24
* Arguments
25
* =========
26
*
27
* M (input) INTEGER
28
* The number of rows of the matrix A. M >= 0.
29
*
30
* N (input) INTEGER
31
* The number of columns of the matrix A. N >= 0.
32
*
33
* A (input/output) COMPLEX array, dimension (LDA,N)
34
* On entry, the M-by-N matrix A.
35
* On exit, the upper triangle of the array contains the
36
* min(M,N)-by-N upper trapezoidal matrix R; the elements below
37
* the diagonal, together with the array TAU, represent the
38
* unitary matrix Q as a product of min(M,N) elementary
39
* reflectors.
40
*
41
* LDA (input) INTEGER
42
* The leading dimension of the array A. LDA >= max(1,M).
43
*
44
* JPVT (input/output) INTEGER array, dimension (N)
45
* On entry, if JPVT(J).ne.0, the J-th column of A is permuted
46
* to the front of A*P (a leading column); if JPVT(J)=0,
47
* the J-th column of A is a free column.
48
* On exit, if JPVT(J)=K, then the J-th column of A*P was the
49
* the K-th column of A.
50
*
51
* TAU (output) COMPLEX array, dimension (min(M,N))
52
* The scalar factors of the elementary reflectors.
53
*
54
* WORK (workspace/output) COMPLEX array, dimension (LWORK)
55
* On exit, if INFO=0, WORK(1) returns the optimal LWORK.
56
*
57
* LWORK (input) INTEGER
58
* The dimension of the array WORK. LWORK >= N+1.
59
* For optimal performance LWORK >= ( N+1 )*NB, where NB
60
* is the optimal blocksize.
61
*
62
* If LWORK = -1, then a workspace query is assumed; the routine
63
* only calculates the optimal size of the WORK array, returns
64
* this value as the first entry of the WORK array, and no error
65
* message related to LWORK is issued by XERBLA.
66
*
67
* RWORK (workspace) REAL array, dimension (2*N)
68
*
69
* INFO (output) INTEGER
70
* = 0: successful exit.
71
* < 0: if INFO = -i, the i-th argument had an illegal value.
72
*
73
* Further Details
74
* ===============
75
*
76
* The matrix Q is represented as a product of elementary reflectors
77
*
78
* Q = H(1) H(2) . . . H(k), where k = min(m,n).
79
*
80
* Each H(i) has the form
81
*
82
* H(i) = I - tau * v * v'
83
*
84
* where tau is a real/complex scalar, and v is a real/complex vector
85
* with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in
86
* A(i+1:m,i), and tau in TAU(i).
87
*
88
* Based on contributions by
89
* G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
90
* X. Sun, Computer Science Dept., Duke University, USA
91
*
92
* =====================================================================
93
*
94
* .. Parameters ..
95
INTEGER INB, INBMIN, IXOVER
96
PARAMETER ( INB = 1, INBMIN = 2, IXOVER = 3 )
97
* ..
98
* .. Local Scalars ..
99
LOGICAL LQUERY
100
INTEGER FJB, IWS, J, JB, LWKOPT, MINMN, MINWS, NA, NB,
101
$ NBMIN, NFXD, NX, SM, SMINMN, SN, TOPBMN
102
* ..
103
* .. External Subroutines ..
104
EXTERNAL CGEQRF, CLAQP2, CLAQPS, CSWAP, CUNMQR, XERBLA
105
* ..
106
* .. External Functions ..
107
INTEGER ILAENV
108
REAL SCNRM2
109
EXTERNAL ILAENV, SCNRM2
110
* ..
111
* .. Intrinsic Functions ..
112
INTRINSIC INT, MAX, MIN
113
* ..
114
* .. Executable Statements ..
115
*
116
IWS = N + 1
117
MINMN = MIN( M, N )
118
*
119
* Test input arguments
120
* ====================
121
*
122
INFO = 0
123
NB = ILAENV( INB, 'CGEQRF', ' ', M, N, -1, -1 )
124
LWKOPT = ( N+1 )*NB
125
WORK( 1 ) = LWKOPT
126
LQUERY = ( LWORK.EQ.-1 )
127
IF( M.LT.0 ) THEN
128
INFO = -1
129
ELSE IF( N.LT.0 ) THEN
130
INFO = -2
131
ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
132
INFO = -4
133
ELSE IF( ( LWORK.LT.IWS ) .AND. .NOT.LQUERY ) THEN
134
INFO = -8
135
END IF
136
IF( INFO.NE.0 ) THEN
137
CALL XERBLA( 'CGEQP3', -INFO )
138
RETURN
139
ELSE IF( LQUERY ) THEN
140
RETURN
141
END IF
142
*
143
* Quick return if possible.
144
*
145
IF( MINMN.EQ.0 ) THEN
146
WORK( 1 ) = 1
147
RETURN
148
END IF
149
*
150
* Move initial columns up front.
151
*
152
NFXD = 1
153
DO 10 J = 1, N
154
IF( JPVT( J ).NE.0 ) THEN
155
IF( J.NE.NFXD ) THEN
156
CALL CSWAP( M, A( 1, J ), 1, A( 1, NFXD ), 1 )
157
JPVT( J ) = JPVT( NFXD )
158
JPVT( NFXD ) = J
159
ELSE
160
JPVT( J ) = J
161
END IF
162
NFXD = NFXD + 1
163
ELSE
164
JPVT( J ) = J
165
END IF
166
10 CONTINUE
167
NFXD = NFXD - 1
168
*
169
* Factorize fixed columns
170
* =======================
171
*
172
* Compute the QR factorization of fixed columns and update
173
* remaining columns.
174
*
175
IF( NFXD.GT.0 ) THEN
176
NA = MIN( M, NFXD )
177
*CC CALL CGEQR2( M, NA, A, LDA, TAU, WORK, INFO )
178
CALL CGEQRF( M, NA, A, LDA, TAU, WORK, LWORK, INFO )
179
IWS = MAX( IWS, INT( WORK( 1 ) ) )
180
IF( NA.LT.N ) THEN
181
*CC CALL CUNM2R( 'Left', 'Conjugate Transpose', M, N-NA,
182
*CC $ NA, A, LDA, TAU, A( 1, NA+1 ), LDA, WORK,
183
*CC $ INFO )
184
CALL CUNMQR( 'Left', 'Conjugate Transpose', M, N-NA, NA, A,
185
$ LDA, TAU, A( 1, NA+1 ), LDA, WORK, LWORK,
186
$ INFO )
187
IWS = MAX( IWS, INT( WORK( 1 ) ) )
188
END IF
189
END IF
190
*
191
* Factorize free columns
192
* ======================
193
*
194
IF( NFXD.LT.MINMN ) THEN
195
*
196
SM = M - NFXD
197
SN = N - NFXD
198
SMINMN = MINMN - NFXD
199
*
200
* Determine the block size.
201
*
202
NB = ILAENV( INB, 'CGEQRF', ' ', SM, SN, -1, -1 )
203
NBMIN = 2
204
NX = 0
205
*
206
IF( ( NB.GT.1 ) .AND. ( NB.LT.SMINMN ) ) THEN
207
*
208
* Determine when to cross over from blocked to unblocked code.
209
*
210
NX = MAX( 0, ILAENV( IXOVER, 'CGEQRF', ' ', SM, SN, -1,
211
$ -1 ) )
212
*
213
*
214
IF( NX.LT.SMINMN ) THEN
215
*
216
* Determine if workspace is large enough for blocked code.
217
*
218
MINWS = ( SN+1 )*NB
219
IWS = MAX( IWS, MINWS )
220
IF( LWORK.LT.MINWS ) THEN
221
*
222
* Not enough workspace to use optimal NB: Reduce NB and
223
* determine the minimum value of NB.
224
*
225
NB = LWORK / ( SN+1 )
226
NBMIN = MAX( 2, ILAENV( INBMIN, 'CGEQRF', ' ', SM, SN,
227
$ -1, -1 ) )
228
*
229
*
230
END IF
231
END IF
232
END IF
233
*
234
* Initialize partial column norms. The first N elements of work
235
* store the exact column norms.
236
*
237
DO 20 J = NFXD + 1, N
238
RWORK( J ) = SCNRM2( SM, A( NFXD+1, J ), 1 )
239
RWORK( N+J ) = RWORK( J )
240
20 CONTINUE
241
*
242
IF( ( NB.GE.NBMIN ) .AND. ( NB.LT.SMINMN ) .AND.
243
$ ( NX.LT.SMINMN ) ) THEN
244
*
245
* Use blocked code initially.
246
*
247
J = NFXD + 1
248
*
249
* Compute factorization: while loop.
250
*
251
*
252
TOPBMN = MINMN - NX
253
30 CONTINUE
254
IF( J.LE.TOPBMN ) THEN
255
JB = MIN( NB, TOPBMN-J+1 )
256
*
257
* Factorize JB columns among columns J:N.
258
*
259
CALL CLAQPS( M, N-J+1, J-1, JB, FJB, A( 1, J ), LDA,
260
$ JPVT( J ), TAU( J ), RWORK( J ),
261
$ RWORK( N+J ), WORK( 1 ), WORK( JB+1 ),
262
$ N-J+1 )
263
*
264
J = J + FJB
265
GO TO 30
266
END IF
267
ELSE
268
J = NFXD + 1
269
END IF
270
*
271
* Use unblocked code to factor the last or only block.
272
*
273
*
274
IF( J.LE.MINMN )
275
$ CALL CLAQP2( M, N-J+1, J-1, A( 1, J ), LDA, JPVT( J ),
276
$ TAU( J ), RWORK( J ), RWORK( N+J ), WORK( 1 ) )
277
*
278
END IF
279
*
280
WORK( 1 ) = IWS
281
RETURN
282
*
283
* End of CGEQP3
284
*
285
END
286
287