Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/lapack/cgelsx.f
5224 views
1
SUBROUTINE CGELSX( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
2
$ WORK, RWORK, INFO )
3
*
4
* -- LAPACK driver routine (version 3.0) --
5
* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
6
* Courant Institute, Argonne National Lab, and Rice University
7
* September 30, 1994
8
*
9
* .. Scalar Arguments ..
10
INTEGER INFO, LDA, LDB, M, N, NRHS, RANK
11
REAL RCOND
12
* ..
13
* .. Array Arguments ..
14
INTEGER JPVT( * )
15
REAL RWORK( * )
16
COMPLEX A( LDA, * ), B( LDB, * ), WORK( * )
17
* ..
18
*
19
* Purpose
20
* =======
21
*
22
* This routine is deprecated and has been replaced by routine CGELSY.
23
*
24
* CGELSX computes the minimum-norm solution to a complex linear least
25
* squares problem:
26
* minimize || A * X - B ||
27
* using a complete orthogonal factorization of A. A is an M-by-N
28
* matrix which may be rank-deficient.
29
*
30
* Several right hand side vectors b and solution vectors x can be
31
* handled in a single call; they are stored as the columns of the
32
* M-by-NRHS right hand side matrix B and the N-by-NRHS solution
33
* matrix X.
34
*
35
* The routine first computes a QR factorization with column pivoting:
36
* A * P = Q * [ R11 R12 ]
37
* [ 0 R22 ]
38
* with R11 defined as the largest leading submatrix whose estimated
39
* condition number is less than 1/RCOND. The order of R11, RANK,
40
* is the effective rank of A.
41
*
42
* Then, R22 is considered to be negligible, and R12 is annihilated
43
* by unitary transformations from the right, arriving at the
44
* complete orthogonal factorization:
45
* A * P = Q * [ T11 0 ] * Z
46
* [ 0 0 ]
47
* The minimum-norm solution is then
48
* X = P * Z' [ inv(T11)*Q1'*B ]
49
* [ 0 ]
50
* where Q1 consists of the first RANK columns of Q.
51
*
52
* Arguments
53
* =========
54
*
55
* M (input) INTEGER
56
* The number of rows of the matrix A. M >= 0.
57
*
58
* N (input) INTEGER
59
* The number of columns of the matrix A. N >= 0.
60
*
61
* NRHS (input) INTEGER
62
* The number of right hand sides, i.e., the number of
63
* columns of matrices B and X. NRHS >= 0.
64
*
65
* A (input/output) COMPLEX array, dimension (LDA,N)
66
* On entry, the M-by-N matrix A.
67
* On exit, A has been overwritten by details of its
68
* complete orthogonal factorization.
69
*
70
* LDA (input) INTEGER
71
* The leading dimension of the array A. LDA >= max(1,M).
72
*
73
* B (input/output) COMPLEX array, dimension (LDB,NRHS)
74
* On entry, the M-by-NRHS right hand side matrix B.
75
* On exit, the N-by-NRHS solution matrix X.
76
* If m >= n and RANK = n, the residual sum-of-squares for
77
* the solution in the i-th column is given by the sum of
78
* squares of elements N+1:M in that column.
79
*
80
* LDB (input) INTEGER
81
* The leading dimension of the array B. LDB >= max(1,M,N).
82
*
83
* JPVT (input/output) INTEGER array, dimension (N)
84
* On entry, if JPVT(i) .ne. 0, the i-th column of A is an
85
* initial column, otherwise it is a free column. Before
86
* the QR factorization of A, all initial columns are
87
* permuted to the leading positions; only the remaining
88
* free columns are moved as a result of column pivoting
89
* during the factorization.
90
* On exit, if JPVT(i) = k, then the i-th column of A*P
91
* was the k-th column of A.
92
*
93
* RCOND (input) REAL
94
* RCOND is used to determine the effective rank of A, which
95
* is defined as the order of the largest leading triangular
96
* submatrix R11 in the QR factorization with pivoting of A,
97
* whose estimated condition number < 1/RCOND.
98
*
99
* RANK (output) INTEGER
100
* The effective rank of A, i.e., the order of the submatrix
101
* R11. This is the same as the order of the submatrix T11
102
* in the complete orthogonal factorization of A.
103
*
104
* WORK (workspace) COMPLEX array, dimension
105
* (min(M,N) + max( N, 2*min(M,N)+NRHS )),
106
*
107
* RWORK (workspace) REAL array, dimension (2*N)
108
*
109
* INFO (output) INTEGER
110
* = 0: successful exit
111
* < 0: if INFO = -i, the i-th argument had an illegal value
112
*
113
* =====================================================================
114
*
115
* .. Parameters ..
116
INTEGER IMAX, IMIN
117
PARAMETER ( IMAX = 1, IMIN = 2 )
118
REAL ZERO, ONE, DONE, NTDONE
119
PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0, DONE = ZERO,
120
$ NTDONE = ONE )
121
COMPLEX CZERO, CONE
122
PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ),
123
$ CONE = ( 1.0E+0, 0.0E+0 ) )
124
* ..
125
* .. Local Scalars ..
126
INTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, K, MN
127
REAL ANRM, BIGNUM, BNRM, SMAX, SMAXPR, SMIN, SMINPR,
128
$ SMLNUM
129
COMPLEX C1, C2, S1, S2, T1, T2
130
* ..
131
* .. External Subroutines ..
132
EXTERNAL CGEQPF, CLAIC1, CLASCL, CLASET, CLATZM, CTRSM,
133
$ CTZRQF, CUNM2R, SLABAD, XERBLA
134
* ..
135
* .. External Functions ..
136
REAL CLANGE, SLAMCH
137
EXTERNAL CLANGE, SLAMCH
138
* ..
139
* .. Intrinsic Functions ..
140
INTRINSIC ABS, CONJG, MAX, MIN
141
* ..
142
* .. Executable Statements ..
143
*
144
MN = MIN( M, N )
145
ISMIN = MN + 1
146
ISMAX = 2*MN + 1
147
*
148
* Test the input arguments.
149
*
150
INFO = 0
151
IF( M.LT.0 ) THEN
152
INFO = -1
153
ELSE IF( N.LT.0 ) THEN
154
INFO = -2
155
ELSE IF( NRHS.LT.0 ) THEN
156
INFO = -3
157
ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
158
INFO = -5
159
ELSE IF( LDB.LT.MAX( 1, M, N ) ) THEN
160
INFO = -7
161
END IF
162
*
163
IF( INFO.NE.0 ) THEN
164
CALL XERBLA( 'CGELSX', -INFO )
165
RETURN
166
END IF
167
*
168
* Quick return if possible
169
*
170
IF( MIN( M, N, NRHS ).EQ.0 ) THEN
171
RANK = 0
172
RETURN
173
END IF
174
*
175
* Get machine parameters
176
*
177
SMLNUM = SLAMCH( 'S' ) / SLAMCH( 'P' )
178
BIGNUM = ONE / SMLNUM
179
CALL SLABAD( SMLNUM, BIGNUM )
180
*
181
* Scale A, B if max elements outside range [SMLNUM,BIGNUM]
182
*
183
ANRM = CLANGE( 'M', M, N, A, LDA, RWORK )
184
IASCL = 0
185
IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
186
*
187
* Scale matrix norm up to SMLNUM
188
*
189
CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
190
IASCL = 1
191
ELSE IF( ANRM.GT.BIGNUM ) THEN
192
*
193
* Scale matrix norm down to BIGNUM
194
*
195
CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
196
IASCL = 2
197
ELSE IF( ANRM.EQ.ZERO ) THEN
198
*
199
* Matrix all zero. Return zero solution.
200
*
201
CALL CLASET( 'F', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
202
RANK = 0
203
GO TO 100
204
END IF
205
*
206
BNRM = CLANGE( 'M', M, NRHS, B, LDB, RWORK )
207
IBSCL = 0
208
IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
209
*
210
* Scale matrix norm up to SMLNUM
211
*
212
CALL CLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
213
IBSCL = 1
214
ELSE IF( BNRM.GT.BIGNUM ) THEN
215
*
216
* Scale matrix norm down to BIGNUM
217
*
218
CALL CLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
219
IBSCL = 2
220
END IF
221
*
222
* Compute QR factorization with column pivoting of A:
223
* A * P = Q * R
224
*
225
CALL CGEQPF( M, N, A, LDA, JPVT, WORK( 1 ), WORK( MN+1 ), RWORK,
226
$ INFO )
227
*
228
* complex workspace MN+N. Real workspace 2*N. Details of Householder
229
* rotations stored in WORK(1:MN).
230
*
231
* Determine RANK using incremental condition estimation
232
*
233
WORK( ISMIN ) = CONE
234
WORK( ISMAX ) = CONE
235
SMAX = ABS( A( 1, 1 ) )
236
SMIN = SMAX
237
IF( ABS( A( 1, 1 ) ).EQ.ZERO ) THEN
238
RANK = 0
239
CALL CLASET( 'F', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
240
GO TO 100
241
ELSE
242
RANK = 1
243
END IF
244
*
245
10 CONTINUE
246
IF( RANK.LT.MN ) THEN
247
I = RANK + 1
248
CALL CLAIC1( IMIN, RANK, WORK( ISMIN ), SMIN, A( 1, I ),
249
$ A( I, I ), SMINPR, S1, C1 )
250
CALL CLAIC1( IMAX, RANK, WORK( ISMAX ), SMAX, A( 1, I ),
251
$ A( I, I ), SMAXPR, S2, C2 )
252
*
253
IF( SMAXPR*RCOND.LE.SMINPR ) THEN
254
DO 20 I = 1, RANK
255
WORK( ISMIN+I-1 ) = S1*WORK( ISMIN+I-1 )
256
WORK( ISMAX+I-1 ) = S2*WORK( ISMAX+I-1 )
257
20 CONTINUE
258
WORK( ISMIN+RANK ) = C1
259
WORK( ISMAX+RANK ) = C2
260
SMIN = SMINPR
261
SMAX = SMAXPR
262
RANK = RANK + 1
263
GO TO 10
264
END IF
265
END IF
266
*
267
* Logically partition R = [ R11 R12 ]
268
* [ 0 R22 ]
269
* where R11 = R(1:RANK,1:RANK)
270
*
271
* [R11,R12] = [ T11, 0 ] * Y
272
*
273
IF( RANK.LT.N )
274
$ CALL CTZRQF( RANK, N, A, LDA, WORK( MN+1 ), INFO )
275
*
276
* Details of Householder rotations stored in WORK(MN+1:2*MN)
277
*
278
* B(1:M,1:NRHS) := Q' * B(1:M,1:NRHS)
279
*
280
CALL CUNM2R( 'Left', 'Conjugate transpose', M, NRHS, MN, A, LDA,
281
$ WORK( 1 ), B, LDB, WORK( 2*MN+1 ), INFO )
282
*
283
* workspace NRHS
284
*
285
* B(1:RANK,1:NRHS) := inv(T11) * B(1:RANK,1:NRHS)
286
*
287
CALL CTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', RANK,
288
$ NRHS, CONE, A, LDA, B, LDB )
289
*
290
DO 40 I = RANK + 1, N
291
DO 30 J = 1, NRHS
292
B( I, J ) = CZERO
293
30 CONTINUE
294
40 CONTINUE
295
*
296
* B(1:N,1:NRHS) := Y' * B(1:N,1:NRHS)
297
*
298
IF( RANK.LT.N ) THEN
299
DO 50 I = 1, RANK
300
CALL CLATZM( 'Left', N-RANK+1, NRHS, A( I, RANK+1 ), LDA,
301
$ CONJG( WORK( MN+I ) ), B( I, 1 ),
302
$ B( RANK+1, 1 ), LDB, WORK( 2*MN+1 ) )
303
50 CONTINUE
304
END IF
305
*
306
* workspace NRHS
307
*
308
* B(1:N,1:NRHS) := P * B(1:N,1:NRHS)
309
*
310
DO 90 J = 1, NRHS
311
DO 60 I = 1, N
312
WORK( 2*MN+I ) = NTDONE
313
60 CONTINUE
314
DO 80 I = 1, N
315
IF( WORK( 2*MN+I ).EQ.NTDONE ) THEN
316
IF( JPVT( I ).NE.I ) THEN
317
K = I
318
T1 = B( K, J )
319
T2 = B( JPVT( K ), J )
320
70 CONTINUE
321
B( JPVT( K ), J ) = T1
322
WORK( 2*MN+K ) = DONE
323
T1 = T2
324
K = JPVT( K )
325
T2 = B( JPVT( K ), J )
326
IF( JPVT( K ).NE.I )
327
$ GO TO 70
328
B( I, J ) = T1
329
WORK( 2*MN+K ) = DONE
330
END IF
331
END IF
332
80 CONTINUE
333
90 CONTINUE
334
*
335
* Undo scaling
336
*
337
IF( IASCL.EQ.1 ) THEN
338
CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
339
CALL CLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
340
$ INFO )
341
ELSE IF( IASCL.EQ.2 ) THEN
342
CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
343
CALL CLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
344
$ INFO )
345
END IF
346
IF( IBSCL.EQ.1 ) THEN
347
CALL CLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
348
ELSE IF( IBSCL.EQ.2 ) THEN
349
CALL CLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
350
END IF
351
*
352
100 CONTINUE
353
*
354
RETURN
355
*
356
* End of CGELSX
357
*
358
END
359
360