SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
pdgels.f
Go to the documentation of this file.
1 SUBROUTINE pdgels( TRANS, M, N, NRHS, A, IA, JA, DESCA, B, IB, JB,
2 $ DESCB, WORK, LWORK, INFO )
3*
4* -- ScaLAPACK routine (version 1.7) --
5* University of Tennessee, Knoxville, Oak Ridge National Laboratory,
6* and University of California, Berkeley.
7* May 1, 1997
8*
9* .. Scalar Arguments ..
10 CHARACTER TRANS
11 INTEGER IA, IB, INFO, JA, JB, LWORK, M, N, NRHS
12* ..
13* .. Array Arguments ..
14 INTEGER DESCA( * ), DESCB( * )
15 DOUBLE PRECISION A( * ), B( * ), WORK( * )
16* ..
17*
18* Purpose
19* =======
20*
21* PDGELS solves overdetermined or underdetermined real linear
22* systems involving an M-by-N matrix sub( A ) = A(IA:IA+M-1,JA:JA+N-1),
23* or its transpose, using a QR or LQ factorization of sub( A ). It is
24* assumed that sub( A ) has full rank.
25*
26* The following options are provided:
27*
28* 1. If TRANS = 'N' and m >= n: find the least squares solution of
29* an overdetermined system, i.e., solve the least squares problem
30* minimize || sub( B ) - sub( A )*X ||.
31*
32* 2. If TRANS = 'N' and m < n: find the minimum norm solution of
33* an underdetermined system sub( A ) * X = sub( B ).
34*
35* 3. If TRANS = 'T' and m >= n: find the minimum norm solution of
36* an undetermined system sub( A )**T * X = sub( B ).
37*
38* 4. If TRANS = 'T' and m < n: find the least squares solution of
39* an overdetermined system, i.e., solve the least squares problem
40* minimize || sub( B ) - sub( A )**T * X ||.
41*
42* where sub( B ) denotes B( IB:IB+M-1, JB:JB+NRHS-1 ) when TRANS = 'N'
43* and B( IB:IB+N-1, JB:JB+NRHS-1 ) otherwise. Several right hand side
44* vectors b and solution vectors x can be handled in a single call;
45* When TRANS = 'N', the solution vectors are stored as the columns of
46* the N-by-NRHS right hand side matrix sub( B ) and the M-by-NRHS
47* right hand side matrix sub( B ) otherwise.
48*
49* Notes
50* =====
51*
52* Each global data object is described by an associated description
53* vector. This vector stores the information required to establish
54* the mapping between an object element and its corresponding process
55* and memory location.
56*
57* Let A be a generic term for any 2D block cyclicly distributed array.
58* Such a global array has an associated description vector DESCA.
59* In the following comments, the character _ should be read as
60* "of the global array".
61*
62* NOTATION STORED IN EXPLANATION
63* --------------- -------------- --------------------------------------
64* DTYPE_A(global) DESCA( DTYPE_ )The descriptor type. In this case,
65* DTYPE_A = 1.
66* CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating
67* the BLACS process grid A is distribu-
68* ted over. The context itself is glo-
69* bal, but the handle (the integer
70* value) may vary.
71* M_A (global) DESCA( M_ ) The number of rows in the global
72* array A.
73* N_A (global) DESCA( N_ ) The number of columns in the global
74* array A.
75* MB_A (global) DESCA( MB_ ) The blocking factor used to distribute
76* the rows of the array.
77* NB_A (global) DESCA( NB_ ) The blocking factor used to distribute
78* the columns of the array.
79* RSRC_A (global) DESCA( RSRC_ ) The process row over which the first
80* row of the array A is distributed.
81* CSRC_A (global) DESCA( CSRC_ ) The process column over which the
82* first column of the array A is
83* distributed.
84* LLD_A (local) DESCA( LLD_ ) The leading dimension of the local
85* array. LLD_A >= MAX(1,LOCr(M_A)).
86*
87* Let K be the number of rows or columns of a distributed matrix,
88* and assume that its process grid has dimension p x q.
89* LOCr( K ) denotes the number of elements of K that a process
90* would receive if K were distributed over the p processes of its
91* process column.
92* Similarly, LOCc( K ) denotes the number of elements of K that a
93* process would receive if K were distributed over the q processes of
94* its process row.
95* The values of LOCr() and LOCc() may be determined via a call to the
96* ScaLAPACK tool function, NUMROC:
97* LOCr( M ) = NUMROC( M, MB_A, MYROW, RSRC_A, NPROW ),
98* LOCc( N ) = NUMROC( N, NB_A, MYCOL, CSRC_A, NPCOL ).
99* An upper bound for these quantities may be computed by:
100* LOCr( M ) <= ceil( ceil(M/MB_A)/NPROW )*MB_A
101* LOCc( N ) <= ceil( ceil(N/NB_A)/NPCOL )*NB_A
102*
103* Arguments
104* =========
105*
106* TRANS (global input) CHARACTER
107* = 'N': the linear system involves sub( A );
108* = 'T': the linear system involves sub( A )**T.
109*
110* M (global input) INTEGER
111* The number of rows to be operated on, i.e. the number of
112* rows of the distributed submatrix sub( A ). M >= 0.
113*
114* N (global input) INTEGER
115* The number of columns to be operated on, i.e. the number of
116* columns of the distributed submatrix sub( A ). N >= 0.
117*
118* NRHS (global input) INTEGER
119* The number of right hand sides, i.e. the number of columns
120* of the distributed submatrices sub( B ) and X. NRHS >= 0.
121*
122* A (local input/local output) DOUBLE PRECISION pointer into the
123* local memory to an array of local dimension
124* ( LLD_A, LOCc(JA+N-1) ). On entry, the M-by-N matrix A.
125* if M >= N, sub( A ) is overwritten by details of its QR
126* factorization as returned by PDGEQRF;
127* if M < N, sub( A ) is overwritten by details of its LQ
128* factorization as returned by PDGELQF.
129*
130* IA (global input) INTEGER
131* The row index in the global array A indicating the first
132* row of sub( A ).
133*
134* JA (global input) INTEGER
135* The column index in the global array A indicating the
136* first column of sub( A ).
137*
138* DESCA (global and local input) INTEGER array of dimension DLEN_.
139* The array descriptor for the distributed matrix A.
140*
141* B (local input/local output) DOUBLE PRECISION pointer into the
142* local memory to an array of local dimension
143* (LLD_B, LOCc(JB+NRHS-1)). On entry, this array contains the
144* local pieces of the distributed matrix B of right hand side
145* vectors, stored columnwise;
146* sub( B ) is M-by-NRHS if TRANS='N', and N-by-NRHS otherwise.
147* On exit, sub( B ) is overwritten by the solution vectors,
148* stored columnwise: if TRANS = 'N' and M >= N, rows 1 to N
149* of sub( B ) contain the least squares solution vectors; the
150* residual sum of squares for the solution in each column is
151* given by the sum of squares of elements N+1 to M in that
152* column; if TRANS = 'N' and M < N, rows 1 to N of sub( B )
153* contain the minimum norm solution vectors; if TRANS = 'T'
154* and M >= N, rows 1 to M of sub( B ) contain the minimum norm
155* solution vectors; if TRANS = 'T' and M < N, rows 1 to M of
156* sub( B ) contain the least squares solution vectors; the
157* residual sum of squares for the solution in each column is
158* given by the sum of squares of elements M+1 to N in that
159* column.
160*
161* IB (global input) INTEGER
162* The row index in the global array B indicating the first
163* row of sub( B ).
164*
165* JB (global input) INTEGER
166* The column index in the global array B indicating the
167* first column of sub( B ).
168*
169* DESCB (global and local input) INTEGER array of dimension DLEN_.
170* The array descriptor for the distributed matrix B.
171*
172* WORK (local workspace/local output) DOUBLE PRECISION array,
173* dimension (LWORK)
174* On exit, WORK(1) returns the minimal and optimal LWORK.
175*
176* LWORK (local or global input) INTEGER
177* The dimension of the array WORK.
178* LWORK is local input and must be at least
179* LWORK >= LTAU + MAX( LWF, LWS ) where
180* If M >= N, then
181* LTAU = NUMROC( JA+MIN(M,N)-1, NB_A, MYCOL, CSRC_A, NPCOL ),
182* LWF = NB_A * ( MpA0 + NqA0 + NB_A )
183* LWS = MAX( (NB_A*(NB_A-1))/2, (NRHSqB0 + MpB0)*NB_A ) +
184* NB_A * NB_A
185* Else
186* LTAU = NUMROC( IA+MIN(M,N)-1, MB_A, MYROW, RSRC_A, NPROW ),
187* LWF = MB_A * ( MpA0 + NqA0 + MB_A )
188* LWS = MAX( (MB_A*(MB_A-1))/2, ( NpB0 + MAX( NqA0 +
189* NUMROC( NUMROC( N+IROFFB, MB_A, 0, 0, NPROW ),
190* MB_A, 0, 0, LCMP ), NRHSqB0 ) )*MB_A ) +
191* MB_A * MB_A
192* End if
193*
194* where LCMP = LCM / NPROW with LCM = ILCM( NPROW, NPCOL ),
195*
196* IROFFA = MOD( IA-1, MB_A ), ICOFFA = MOD( JA-1, NB_A ),
197* IAROW = INDXG2P( IA, MB_A, MYROW, RSRC_A, NPROW ),
198* IACOL = INDXG2P( JA, NB_A, MYCOL, CSRC_A, NPCOL ),
199* MpA0 = NUMROC( M+IROFFA, MB_A, MYROW, IAROW, NPROW ),
200* NqA0 = NUMROC( N+ICOFFA, NB_A, MYCOL, IACOL, NPCOL ),
201*
202* IROFFB = MOD( IB-1, MB_B ), ICOFFB = MOD( JB-1, NB_B ),
203* IBROW = INDXG2P( IB, MB_B, MYROW, RSRC_B, NPROW ),
204* IBCOL = INDXG2P( JB, NB_B, MYCOL, CSRC_B, NPCOL ),
205* MpB0 = NUMROC( M+IROFFB, MB_B, MYROW, IBROW, NPROW ),
206* NpB0 = NUMROC( N+IROFFB, MB_B, MYROW, IBROW, NPROW ),
207* NRHSqB0 = NUMROC( NRHS+ICOFFB, NB_B, MYCOL, IBCOL, NPCOL ),
208*
209* ILCM, INDXG2P and NUMROC are ScaLAPACK tool functions;
210* MYROW, MYCOL, NPROW and NPCOL can be determined by calling
211* the subroutine BLACS_GRIDINFO.
212*
213* If LWORK = -1, then LWORK is global input and a workspace
214* query is assumed; the routine only calculates the minimum
215* and optimal size for all work arrays. Each of these
216* values is returned in the first entry of the corresponding
217* work array, and no error message is issued by PXERBLA.
218*
219* INFO (global output) INTEGER
220* = 0: successful exit
221* < 0: If the i-th argument is an array and the j-entry had
222* an illegal value, then INFO = -(i*100+j), if the i-th
223* argument is a scalar and had an illegal value, then
224* INFO = -i.
225*
226* =====================================================================
227*
228* .. Parameters ..
229 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
230 $ lld_, mb_, m_, nb_, n_, rsrc_
231 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
232 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
233 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
234 DOUBLE PRECISION ZERO, ONE
235 parameter( zero = 0.0d+0, one = 1.0d+0 )
236* ..
237* .. Local Scalars ..
238 LOGICAL LQUERY, TPSD
239 INTEGER BROW, IACOL, IAROW, IASCL, IBCOL, IBROW, IBSCL,
240 $ icoffa, icoffb, ictxt, ipw, iroffa, iroffb,
241 $ lcm, lcmp, ltau, lwf, lwmin, lws, mpa0, mpb0,
242 $ mycol, myrow, npb0, npcol, nprow, nqa0,
243 $ nrhsqb0, scllen
244 DOUBLE PRECISION ANRM, BIGNUM, BNRM, SMLNUM
245* ..
246* .. Local Arrays ..
247 INTEGER IDUM1( 2 ), IDUM2( 2 )
248 DOUBLE PRECISION RWORK( 1 )
249* ..
250* .. External Functions ..
251 LOGICAL LSAME
252 INTEGER ILCM
253 INTEGER INDXG2P, NUMROC
254 DOUBLE PRECISION PDLAMCH, PDLANGE
255 EXTERNAL ilcm, indxg2p, lsame, numroc, pdlamch,
256 $ pdlange
257* ..
258* .. External Subroutines ..
259 EXTERNAL blacs_gridinfo, chk1mat, pchk2mat, pdgelqf,
261 $ pdormlq, pdormqr, pdtrsm, pxerbla
262* ..
263* .. Intrinsic Functions ..
264 INTRINSIC dble, ichar, max, min, mod
265* ..
266* .. Executable Statements ..
267*
268* Get grid parameters
269*
270 ictxt = desca( ctxt_ )
271 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
272*
273* Test the input parameters
274*
275 info = 0
276 IF( nprow.EQ.-1 ) THEN
277 info = -( 800 + ctxt_ )
278 ELSE
279 CALL chk1mat( m, 2, n, 3, ia, ja, desca, 8, info )
280 IF ( m .GE. n ) THEN
281 CALL chk1mat( m, 2, nrhs, 4, ib, jb, descb, 12, info )
282 ELSE
283 CALL chk1mat( n, 3, nrhs, 4, ib, jb, descb, 12, info )
284 ENDIF
285 IF( info.EQ.0 ) THEN
286 iroffa = mod( ia-1, desca( mb_ ) )
287 icoffa = mod( ja-1, desca( nb_ ) )
288 iroffb = mod( ib-1, descb( mb_ ) )
289 icoffb = mod( jb-1, descb( nb_ ) )
290 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
291 $ nprow )
292 iacol = indxg2p( ia, desca( nb_ ), mycol, desca( csrc_ ),
293 $ npcol )
294 mpa0 = numroc( m+iroffa, desca( mb_ ), myrow, iarow, nprow )
295 nqa0 = numroc( n+icoffa, desca( nb_ ), mycol, iacol, npcol )
296*
297 ibrow = indxg2p( ib, descb( mb_ ), myrow, descb( rsrc_ ),
298 $ nprow )
299 ibcol = indxg2p( ib, descb( nb_ ), mycol, descb( csrc_ ),
300 $ npcol )
301 nrhsqb0 = numroc( nrhs+icoffb, descb( nb_ ), mycol, ibcol,
302 $ npcol )
303 IF( m.GE.n ) THEN
304 mpb0 = numroc( m+iroffb, descb( mb_ ), myrow, ibrow,
305 $ nprow )
306 ltau = numroc( ja+min(m,n)-1, desca( nb_ ), mycol,
307 $ desca( csrc_ ), npcol )
308 lwf = desca( nb_ ) * ( mpa0 + nqa0 + desca( nb_ ) )
309 lws = max( ( desca( nb_ )*( desca( nb_ ) - 1 ) ) / 2,
310 $ ( mpb0 + nrhsqb0 ) * desca( nb_ ) ) +
311 $ desca( nb_ )*desca( nb_ )
312 ELSE
313 lcm = ilcm( nprow, npcol )
314 lcmp = lcm / nprow
315 npb0 = numroc( n+iroffb, descb( mb_ ), myrow, ibrow,
316 $ nprow )
317 ltau = numroc( ia+min(m,n)-1, desca( mb_ ), myrow,
318 $ desca( rsrc_ ), nprow )
319 lwf = desca( mb_ ) * ( mpa0 + nqa0 + desca( mb_ ) )
320 lws = max( ( desca( mb_ )*( desca( mb_ ) - 1 ) ) / 2,
321 $ ( npb0 + max( nqa0 + numroc( numroc( n+iroffb,
322 $ desca( mb_ ), 0, 0, nprow ), desca( mb_ ), 0, 0,
323 $ lcmp ), nrhsqb0 ) )*desca( mb_ ) ) +
324 $ desca( mb_ ) * desca( mb_ )
325 END IF
326 lwmin = ltau + max( lwf, lws )
327 work( 1 ) = dble( lwmin )
328 lquery = ( lwork.EQ.-1 )
329*
330 tpsd = .true.
331 IF( lsame( trans, 'N' ) )
332 $ tpsd = .false.
333*
334 IF( .NOT.( lsame( trans, 'N' ) .OR.
335 $ lsame( trans, 'T' ) ) ) THEN
336 info = -1
337 ELSE IF( m.LT.0 ) THEN
338 info = -2
339 ELSE IF( n.LT.0 ) THEN
340 info = -3
341 ELSE IF( nrhs.LT.0 ) THEN
342 info = -4
343 ELSE IF( m.GE.n .AND. iroffa.NE.iroffb ) THEN
344 info = -10
345 ELSE IF( m.GE.n .AND. iarow.NE.ibrow ) THEN
346 info = -10
347 ELSE IF( m.LT.n .AND. icoffa.NE.iroffb ) THEN
348 info = -10
349 ELSE IF( m.GE.n .AND. desca( mb_ ).NE.descb( mb_ ) ) THEN
350 info = -( 1200 + mb_ )
351 ELSE IF( m.LT.n .AND. desca( nb_ ).NE.descb( mb_ ) ) THEN
352 info = -( 1200 + mb_ )
353 ELSE IF( ictxt.NE.descb( ctxt_ ) ) THEN
354 info = -( 1200 + ctxt_ )
355 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
356 info = -14
357 END IF
358 END IF
359*
360 IF( .NOT.tpsd ) THEN
361 idum1( 1 ) = ichar( 'N' )
362 ELSE
363 idum1( 1 ) = ichar( 'T' )
364 END IF
365 idum2( 1 ) = 1
366 IF( lwork.EQ.-1 ) THEN
367 idum1( 2 ) = -1
368 ELSE
369 idum1( 2 ) = 1
370 END IF
371 idum2( 2 ) = 14
372 CALL pchk2mat( m, 2, n, 3, ia, ja, desca, 8, n, 3, nrhs, 4,
373 $ ib, jb, descb, 12, 2, idum1, idum2, info )
374 END IF
375*
376 IF( info.NE.0 ) THEN
377 CALL pxerbla( ictxt, 'PDGELS', -info )
378 RETURN
379 ELSE IF( lquery ) THEN
380 RETURN
381 END IF
382*
383* Quick return if possible
384*
385 IF( min( m, n, nrhs ).EQ.0 ) THEN
386 CALL pdlaset( 'Full', max( m, n ), nrhs, zero, zero, b,
387 $ ib, jb, descb )
388 RETURN
389 END IF
390*
391* Get machine parameters
392*
393 smlnum = pdlamch( ictxt, 'S' )
394 smlnum = smlnum / pdlamch( ictxt, 'P' )
395 bignum = one / smlnum
396 CALL pdlabad( ictxt, smlnum, bignum )
397*
398* Scale A, B if max entry outside range [SMLNUM,BIGNUM]
399*
400 anrm = pdlange( 'M', m, n, a, ia, ja, desca, rwork )
401 iascl = 0
402 IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
403*
404* Scale matrix norm up to SMLNUM
405*
406 CALL pdlascl( 'G', anrm, smlnum, m, n, a, ia, ja, desca,
407 $ info )
408 iascl = 1
409 ELSE IF( anrm.GT.bignum ) THEN
410*
411* Scale matrix norm down to BIGNUM
412*
413 CALL pdlascl( 'G', anrm, bignum, m, n, a, ia, ja, desca,
414 $ info )
415 iascl = 2
416 ELSE IF( anrm.EQ.zero ) THEN
417*
418* Matrix all zero. Return zero solution.
419*
420 CALL pdlaset( 'F', max( m, n ), nrhs, zero, zero, b, ib, jb,
421 $ descb )
422 GO TO 10
423 END IF
424*
425 brow = m
426 IF( tpsd )
427 $ brow = n
428*
429 bnrm = pdlange( 'M', brow, nrhs, b, ib, jb, descb, rwork )
430*
431 ibscl = 0
432 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum ) THEN
433*
434* Scale matrix norm up to SMLNUM
435*
436 CALL pdlascl( 'G', bnrm, smlnum, brow, nrhs, b, ib, jb,
437 $ descb, info )
438 ibscl = 1
439 ELSE IF( bnrm.GT.bignum ) THEN
440*
441* Scale matrix norm down to BIGNUM
442*
443 CALL pdlascl( 'G', bnrm, bignum, brow, nrhs, b, ib, jb,
444 $ descb, info )
445 ibscl = 2
446 END IF
447*
448 ipw = ltau + 1
449*
450 IF( m.GE.n ) THEN
451*
452* compute QR factorization of A
453*
454 CALL pdgeqrf( m, n, a, ia, ja, desca, work, work( ipw ),
455 $ lwork-ltau, info )
456*
457* workspace at least N, optimally N*NB
458*
459 IF( .NOT.tpsd ) THEN
460*
461* Least-Squares Problem min || A * X - B ||
462*
463* B(IB:IB+M-1,JB:JB+NRHS-1) := Q' * B(IB:IB+M-1,JB:JB+NRHS-1)
464*
465 CALL pdormqr( 'Left', 'Transpose', m, nrhs, n, a, ia, ja,
466 $ desca, work, b, ib, jb, descb, work( ipw ),
467 $ lwork-ltau, info )
468*
469* workspace at least NRHS, optimally NRHS*NB
470*
471* B(IB:IB+N-1,JB:JB+NRHS-1) := inv(R) *
472* B(IB:IB+N-1,JB:JB+NRHS-1)
473*
474 CALL pdtrsm( 'Left', 'Upper', 'No transpose', 'Non-unit', n,
475 $ nrhs, one, a, ia, ja, desca, b, ib, jb, descb )
476*
477 scllen = n
478*
479 ELSE
480*
481* Overdetermined system of equations sub( A )' * X = sub( B )
482*
483* sub( B ) := inv(R') * sub( B )
484*
485 CALL pdtrsm( 'Left', 'Upper', 'Transpose', 'Non-unit', n,
486 $ nrhs, one, a, ia, ja, desca, b, ib, jb, descb )
487*
488* B(IB+N:IB+M-1,JB:JB+NRHS-1) = ZERO
489*
490 CALL pdlaset( 'All', m-n, nrhs, zero, zero, b, ib+n, jb,
491 $ descb )
492*
493* B(IB:IB+M-1,JB:JB+NRHS-1) := Q(1:N,:) *
494* B(IB:IB+N-1,JB:JB+NRHS-1)
495*
496 CALL pdormqr( 'Left', 'No transpose', m, nrhs, n, a, ia, ja,
497 $ desca, work, b, ib, jb, descb, work( ipw ),
498 $ lwork-ltau, info )
499*
500* workspace at least NRHS, optimally NRHS*NB
501*
502 scllen = m
503*
504 END IF
505*
506 ELSE
507*
508* Compute LQ factorization of sub( A )
509*
510 CALL pdgelqf( m, n, a, ia, ja, desca, work, work( ipw ),
511 $ lwork-ltau, info )
512*
513* workspace at least M, optimally M*NB.
514*
515 IF( .NOT.tpsd ) THEN
516*
517* underdetermined system of equations sub( A ) * X = sub( B )
518*
519* B(IB:IB+M-1,JB:JB+NRHS-1) := inv(L) *
520* B(IB:IB+M-1,JB:JB+NRHS-1)
521*
522 CALL pdtrsm( 'Left', 'Lower', 'No transpose', 'Non-unit', m,
523 $ nrhs, one, a, ia, ja, desca, b, ib, jb, descb )
524*
525* B(IB+M:IB+N-1,JB:JB+NRHS-1) = 0
526*
527 CALL pdlaset( 'All', n-m, nrhs, zero, zero, b, ib+m, jb,
528 $ descb )
529*
530* B(IB:IB+N-1,JB:JB+NRHS-1) := Q(1:N,:)' *
531* B(IB:IB+M-1,JB:JB+NRHS-1)
532*
533 CALL pdormlq( 'Left', 'Transpose', n, nrhs, m, a, ia, ja,
534 $ desca, work, b, ib, jb, descb, work( ipw ),
535 $ lwork-ltau, info )
536*
537* workspace at least NRHS, optimally NRHS*NB
538*
539 scllen = n
540*
541 ELSE
542*
543* overdetermined system min || A' * X - B ||
544*
545* B(IB:IB+N-1,JB:JB+NRHS-1) := Q * B(IB:IB+N-1,JB:JB+NRHS-1)
546*
547 CALL pdormlq( 'Left', 'No transpose', n, nrhs, m, a, ia, ja,
548 $ desca, work, b, ib, jb, descb, work( ipw ),
549 $ lwork-ltau, info )
550*
551* workspace at least NRHS, optimally NRHS*NB
552*
553* B(IB:IB+M-1,JB:JB+NRHS-1) := inv(L') *
554* B(IB:IB+M-1,JB:JB+NRHS-1)
555*
556 CALL pdtrsm( 'Left', 'Lower', 'Transpose', 'Non-unit', m,
557 $ nrhs, one, a, ia, ja, desca, b, ib, jb, descb )
558*
559 scllen = m
560*
561 END IF
562*
563 END IF
564*
565* Undo scaling
566*
567 IF( iascl.EQ.1 ) THEN
568 CALL pdlascl( 'G', anrm, smlnum, scllen, nrhs, b, ib, jb,
569 $ descb, info )
570 ELSE IF( iascl.EQ.2 ) THEN
571 CALL pdlascl( 'G', anrm, bignum, scllen, nrhs, b, ib, jb,
572 $ descb, info )
573 END IF
574 IF( ibscl.EQ.1 ) THEN
575 CALL pdlascl( 'G', smlnum, bnrm, scllen, nrhs, b, ib, jb,
576 $ descb, info )
577 ELSE IF( ibscl.EQ.2 ) THEN
578 CALL pdlascl( 'G', bignum, bnrm, scllen, nrhs, b, ib, jb,
579 $ descb, info )
580 END IF
581*
582 10 CONTINUE
583*
584 work( 1 ) = dble( lwmin )
585*
586 RETURN
587*
588* End of PDGELS
589*
590 END
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
Definition chk1mat.f:3
#define max(A, B)
Definition pcgemr.c:180
#define min(A, B)
Definition pcgemr.c:181
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
Definition pchkxmat.f:175
subroutine pdlaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
Definition pdblastst.f:6862
subroutine pdgelqf(m, n, a, ia, ja, desca, tau, work, lwork, info)
Definition pdgelqf.f:3
subroutine pdgels(trans, m, n, nrhs, a, ia, ja, desca, b, ib, jb, descb, work, lwork, info)
Definition pdgels.f:3
subroutine pdgeqrf(m, n, a, ia, ja, desca, tau, work, lwork, info)
Definition pdgeqrf.f:3
subroutine pdlabad(ictxt, small, large)
Definition pdlabad.f:2
subroutine pdlascl(type, cfrom, cto, m, n, a, ia, ja, desca, info)
Definition pdlascl.f:3
subroutine pdormlq(side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
Definition pdormlq.f:3
subroutine pdormqr(side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
Definition pdormqr.f:3
subroutine pxerbla(ictxt, srname, info)
Definition pxerbla.f:2