Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/lapack/cgerqf.f
5195 views
1
SUBROUTINE CGERQF( M, N, A, LDA, TAU, WORK, LWORK, INFO )
2
*
3
* -- LAPACK routine (version 3.0) --
4
* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
5
* Courant Institute, Argonne National Lab, and Rice University
6
* June 30, 1999
7
*
8
* .. Scalar Arguments ..
9
INTEGER INFO, LDA, LWORK, M, N
10
* ..
11
* .. Array Arguments ..
12
COMPLEX A( LDA, * ), TAU( * ), WORK( * )
13
* ..
14
*
15
* Purpose
16
* =======
17
*
18
* CGERQF computes an RQ factorization of a complex M-by-N matrix A:
19
* A = R * Q.
20
*
21
* Arguments
22
* =========
23
*
24
* M (input) INTEGER
25
* The number of rows of the matrix A. M >= 0.
26
*
27
* N (input) INTEGER
28
* The number of columns of the matrix A. N >= 0.
29
*
30
* A (input/output) COMPLEX array, dimension (LDA,N)
31
* On entry, the M-by-N matrix A.
32
* On exit,
33
* if m <= n, the upper triangle of the subarray
34
* A(1:m,n-m+1:n) contains the M-by-M upper triangular matrix R;
35
* if m >= n, the elements on and above the (m-n)-th subdiagonal
36
* contain the M-by-N upper trapezoidal matrix R;
37
* the remaining elements, with the array TAU, represent the
38
* unitary matrix Q as a product of min(m,n) elementary
39
* reflectors (see Further Details).
40
*
41
* LDA (input) INTEGER
42
* The leading dimension of the array A. LDA >= max(1,M).
43
*
44
* TAU (output) COMPLEX array, dimension (min(M,N))
45
* The scalar factors of the elementary reflectors (see Further
46
* Details).
47
*
48
* WORK (workspace/output) COMPLEX array, dimension (LWORK)
49
* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
50
*
51
* LWORK (input) INTEGER
52
* The dimension of the array WORK. LWORK >= max(1,M).
53
* For optimum performance LWORK >= M*NB, where NB is
54
* the optimal blocksize.
55
*
56
* If LWORK = -1, then a workspace query is assumed; the routine
57
* only calculates the optimal size of the WORK array, returns
58
* this value as the first entry of the WORK array, and no error
59
* message related to LWORK is issued by XERBLA.
60
*
61
* INFO (output) INTEGER
62
* = 0: successful exit
63
* < 0: if INFO = -i, the i-th argument had an illegal value
64
*
65
* Further Details
66
* ===============
67
*
68
* The matrix Q is represented as a product of elementary reflectors
69
*
70
* Q = H(1)' H(2)' . . . H(k)', where k = min(m,n).
71
*
72
* Each H(i) has the form
73
*
74
* H(i) = I - tau * v * v'
75
*
76
* where tau is a complex scalar, and v is a complex vector with
77
* v(n-k+i+1:n) = 0 and v(n-k+i) = 1; conjg(v(1:n-k+i-1)) is stored on
78
* exit in A(m-k+i,1:n-k+i-1), and tau in TAU(i).
79
*
80
* =====================================================================
81
*
82
* .. Local Scalars ..
83
LOGICAL LQUERY
84
INTEGER I, IB, IINFO, IWS, K, KI, KK, LDWORK, LWKOPT,
85
$ MU, NB, NBMIN, NU, NX
86
* ..
87
* .. External Subroutines ..
88
EXTERNAL CGERQ2, CLARFB, CLARFT, XERBLA
89
* ..
90
* .. Intrinsic Functions ..
91
INTRINSIC MAX, MIN
92
* ..
93
* .. External Functions ..
94
INTEGER ILAENV
95
EXTERNAL ILAENV
96
* ..
97
* .. Executable Statements ..
98
*
99
* Test the input arguments
100
*
101
INFO = 0
102
NB = ILAENV( 1, 'CGERQF', ' ', M, N, -1, -1 )
103
LWKOPT = M*NB
104
WORK( 1 ) = LWKOPT
105
LQUERY = ( LWORK.EQ.-1 )
106
IF( M.LT.0 ) THEN
107
INFO = -1
108
ELSE IF( N.LT.0 ) THEN
109
INFO = -2
110
ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
111
INFO = -4
112
ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THEN
113
INFO = -7
114
END IF
115
IF( INFO.NE.0 ) THEN
116
CALL XERBLA( 'CGERQF', -INFO )
117
RETURN
118
ELSE IF( LQUERY ) THEN
119
RETURN
120
END IF
121
*
122
* Quick return if possible
123
*
124
K = MIN( M, N )
125
IF( K.EQ.0 ) THEN
126
WORK( 1 ) = 1
127
RETURN
128
END IF
129
*
130
NBMIN = 2
131
NX = 1
132
IWS = M
133
IF( NB.GT.1 .AND. NB.LT.K ) THEN
134
*
135
* Determine when to cross over from blocked to unblocked code.
136
*
137
NX = MAX( 0, ILAENV( 3, 'CGERQF', ' ', M, N, -1, -1 ) )
138
IF( NX.LT.K ) THEN
139
*
140
* Determine if workspace is large enough for blocked code.
141
*
142
LDWORK = M
143
IWS = LDWORK*NB
144
IF( LWORK.LT.IWS ) THEN
145
*
146
* Not enough workspace to use optimal NB: reduce NB and
147
* determine the minimum value of NB.
148
*
149
NB = LWORK / LDWORK
150
NBMIN = MAX( 2, ILAENV( 2, 'CGERQF', ' ', M, N, -1,
151
$ -1 ) )
152
END IF
153
END IF
154
END IF
155
*
156
IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN
157
*
158
* Use blocked code initially.
159
* The last kk rows are handled by the block method.
160
*
161
KI = ( ( K-NX-1 ) / NB )*NB
162
KK = MIN( K, KI+NB )
163
*
164
DO 10 I = K - KK + KI + 1, K - KK + 1, -NB
165
IB = MIN( K-I+1, NB )
166
*
167
* Compute the RQ factorization of the current block
168
* A(m-k+i:m-k+i+ib-1,1:n-k+i+ib-1)
169
*
170
CALL CGERQ2( IB, N-K+I+IB-1, A( M-K+I, 1 ), LDA, TAU( I ),
171
$ WORK, IINFO )
172
IF( M-K+I.GT.1 ) THEN
173
*
174
* Form the triangular factor of the block reflector
175
* H = H(i+ib-1) . . . H(i+1) H(i)
176
*
177
CALL CLARFT( 'Backward', 'Rowwise', N-K+I+IB-1, IB,
178
$ A( M-K+I, 1 ), LDA, TAU( I ), WORK, LDWORK )
179
*
180
* Apply H to A(1:m-k+i-1,1:n-k+i+ib-1) from the right
181
*
182
CALL CLARFB( 'Right', 'No transpose', 'Backward',
183
$ 'Rowwise', M-K+I-1, N-K+I+IB-1, IB,
184
$ A( M-K+I, 1 ), LDA, WORK, LDWORK, A, LDA,
185
$ WORK( IB+1 ), LDWORK )
186
END IF
187
10 CONTINUE
188
MU = M - K + I + NB - 1
189
NU = N - K + I + NB - 1
190
ELSE
191
MU = M
192
NU = N
193
END IF
194
*
195
* Use unblocked code to factor the last or only block
196
*
197
IF( MU.GT.0 .AND. NU.GT.0 )
198
$ CALL CGERQ2( MU, NU, A, LDA, TAU, WORK, IINFO )
199
*
200
WORK( 1 ) = IWS
201
RETURN
202
*
203
* End of CGERQF
204
*
205
END
206
207