1 SUBROUTINE pcgels( TRANS, M, N, NRHS, A, IA, JA, DESCA, B, IB, JB,
2 $ DESCB, WORK, LWORK, INFO )
11 INTEGER IA, IB, INFO, JA, JB, LWORK, M, N, NRHS
14 INTEGER DESCA( * ), DESCB( * )
15 COMPLEX A( * ), B( * ), WORK( * )
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 )
235 parameter( zero = 0.0e+0, one = 1.0e+0 )
237 parameter( czero = ( 0.0e+0, 0.0e+0 ),
238 $ cone = ( 1.0e+0, 0.0e+0 ) )
242 INTEGER BROW, IACOL, IAROW, IASCL, IBCOL, IBROW, IBSCL,
243 $ icoffa, icoffb, ictxt, ipw, iroffa, iroffb,
244 $ lcm, lcmp, ltau, lwf, lwmin, lws, mpa0, mpb0,
245 $ mycol, myrow, npb0, npcol, nprow, nqa0,
247 REAL ANRM, BIGNUM, BNRM, SMLNUM
250 INTEGER IDUM1( 2 ), IDUM2( 2 )
256 INTEGER INDXG2P, NUMROC
257 REAL PCLANGE, PSLAMCH
258 EXTERNAL ilcm, indxg2p, lsame, numroc, pclange,
273 ictxt = desca( ctxt_ )
274 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
279 IF( nprow.EQ.-1 )
THEN
280 info = -( 800 + ctxt_ )
282 CALL chk1mat( m, 2, n, 3, ia, ja, desca, 8, info )
284 CALL chk1mat( m, 2, nrhs, 4, ib, jb, descb, 12, info )
286 CALL chk1mat( n, 3, nrhs, 4, ib, jb, descb, 12, info )
289 iroffa = mod( ia-1, desca( mb_ ) )
290 icoffa = mod( ja-1, desca( nb_ ) )
291 iroffb = mod( ib-1, descb( mb_ ) )
292 icoffb = mod( jb-1, descb( nb_ ) )
293 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
295 iacol = indxg2p( ia, desca( nb_ ), mycol, desca( csrc_ ),
297 mpa0 = numroc( m+iroffa, desca( mb_ ), myrow, iarow, nprow )
298 nqa0 = numroc( n+icoffa, desca( nb_ ), mycol, iacol, npcol )
300 ibrow = indxg2p( ib, descb( mb_ ), myrow, descb( rsrc_ ),
302 ibcol = indxg2p( ib, descb( nb_ ), mycol, descb( csrc_ ),
304 nrhsqb0 = numroc( nrhs+icoffb, descb( nb_ ), mycol, ibcol,
307 mpb0 = numroc( m+iroffb, descb( mb_ ), myrow, ibrow,
309 ltau = numroc( ja+
min(m,n)-1, desca( nb_ ), mycol,
310 $ desca( csrc_ ), npcol )
311 lwf = desca( nb_ ) * ( mpa0 + nqa0 + desca( nb_ ) )
312 lws =
max( ( desca( nb_ )*( desca( nb_ ) - 1 ) ) / 2,
313 $ ( mpb0 + nrhsqb0 ) * desca( nb_ ) ) +
314 $ desca( nb_ )*desca( nb_ )
316 lcm = ilcm( nprow, npcol )
318 npb0 = numroc( n+iroffb, descb( mb_ ), myrow, ibrow,
320 ltau = numroc( ia+
min(m,n)-1, desca( mb_ ), myrow,
321 $ desca( rsrc_ ), nprow )
322 lwf = desca( mb_ ) * ( mpa0 + nqa0 + desca( mb_ ) )
323 lws =
max( ( desca( mb_ )*( desca( mb_ ) - 1 ) ) / 2,
324 $ ( npb0 +
max( nqa0 + numroc( numroc( n+iroffb,
325 $ desca( mb_ ), 0, 0, nprow ), desca( mb_ ), 0, 0,
326 $ lcmp ), nrhsqb0 ) )*desca( mb_ ) ) +
327 $ desca( mb_ ) * desca( mb_ )
329 lwmin = ltau +
max( lwf, lws )
330 work( 1 ) =
cmplx( real( lwmin ) )
331 lquery = ( lwork.EQ.-1 )
334 IF( lsame( trans,
'N' ) )
337 IF( .NOT.( lsame( trans,
'N' ) .OR.
338 $ lsame( trans,
'C' ) ) )
THEN
340 ELSE IF( m.LT.0 )
THEN
342 ELSE IF( n.LT.0 )
THEN
344 ELSE IF( nrhs.LT.0 )
THEN
346 ELSE IF( m.GE.n .AND. iroffa.NE.iroffb )
THEN
348 ELSE IF( m.GE.n .AND. iarow.NE.ibrow )
THEN
350 ELSE IF( m.LT.n .AND. icoffa.NE.iroffb )
THEN
352 ELSE IF( m.GE.n .AND. desca( mb_ ).NE.descb( mb_ ) )
THEN
353 info = -( 1200 + mb_ )
354 ELSE IF( m.LT.n .AND. desca( nb_ ).NE.descb( mb_ ) )
THEN
355 info = -( 1200 + mb_ )
356 ELSE IF( ictxt.NE.descb( ctxt_ ) )
THEN
357 info = -( 1200 + ctxt_ )
358 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
364 idum1( 1 ) = ichar(
'N' )
366 idum1( 1 ) = ichar(
'C' )
369 IF( lwork.EQ.-1 )
THEN
375 CALL pchk2mat( m, 2, n, 3, ia, ja, desca, 8, n, 3, nrhs, 4,
376 $ ib, jb, descb, 12, 2, idum1, idum2, info )
380 CALL pxerbla( ictxt,
'PCGELS', -info )
382 ELSE IF( lquery )
THEN
388 IF(
min( m, n, nrhs ).EQ.0 )
THEN
389 CALL pclaset(
'Full',
max( m, n ), nrhs, czero, czero, b,
396 smlnum = pslamch( ictxt,
'S' )
397 smlnum = smlnum / pslamch( ictxt,
'P' )
398 bignum = one / smlnum
399 CALL pslabad( ictxt, smlnum, bignum )
403 anrm = pclange(
'M', m, n, a, ia, ja, desca, rwork )
405 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
409 CALL pclascl(
'G', anrm, smlnum, m, n, a, ia, ja, desca,
412 ELSE IF( anrm.GT.bignum )
THEN
416 CALL pclascl(
'G', anrm, bignum, m, n, a, ia, ja, desca,
419 ELSE IF( anrm.EQ.zero )
THEN
423 CALL pclaset(
'F',
max( m, n ), nrhs, czero, czero, b, ib,
432 bnrm = pclange(
'M', brow, nrhs, b, ib, jb, descb, rwork )
435 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
439 CALL pclascl(
'G', bnrm, smlnum, brow, nrhs, b, ib, jb,
442 ELSE IF( bnrm.GT.bignum )
THEN
446 CALL pclascl(
'G', bnrm, bignum, brow, nrhs, b, ib, jb,
457 CALL pcgeqrf( m, n, a, ia, ja, desca, work, work( ipw ),
468 CALL pcunmqr(
'Left',
'Conjugate transpose', m, nrhs, n, a,
469 $ ia, ja, desca, work, b, ib, jb, descb,
470 $ work( ipw ), lwork-ltau, info )
477 CALL pctrsm(
'Left',
'Upper',
'No transpose',
'Non-unit', n,
478 $ nrhs, cone, a, ia, ja, desca, b, ib, jb,
489 CALL pctrsm(
'Left',
'Upper',
'Conjugate transpose',
490 $
'Non-unit', n, nrhs, cone, a, ia, ja, desca,
495 CALL pclaset(
'All', m-n, nrhs, czero, czero, b, ib+n, jb,
501 CALL pcunmqr(
'Left',
'No transpose', m, nrhs, n, a, ia, ja,
502 $ desca, work, b, ib, jb, descb, work( ipw ),
515 CALL pcgelqf( m, n, a, ia, ja, desca, work, work( ipw ),
527 CALL pctrsm(
'Left',
'Lower',
'No transpose',
'Non-unit', m,
528 $ nrhs, cone, a, ia, ja, desca, b, ib, jb,
533 CALL pclaset(
'All', n-m, nrhs, czero, czero, b, ib+m, jb,
539 CALL pcunmlq(
'Left',
'Conjugate transpose', n, nrhs, m, a,
540 $ ia, ja, desca, work, b, ib, jb, descb,
541 $ work( ipw ), lwork-ltau, info )
553 CALL pcunmlq(
'Left',
'No transpose', n, nrhs, m, a, ia, ja,
554 $ desca, work, b, ib, jb, descb, work( ipw ),
562 CALL pctrsm(
'Left',
'Lower',
'Conjugate transpose',
563 $
'Non-unit', m, nrhs, cone, a, ia, ja, desca,
574 IF( iascl.EQ.1 )
THEN
575 CALL pclascl(
'G', anrm, smlnum, scllen, nrhs, b, ib, jb,
577 ELSE IF( iascl.EQ.2 )
THEN
578 CALL pclascl(
'G', anrm, bignum, scllen, nrhs, b, ib, jb,
581 IF( ibscl.EQ.1 )
THEN
582 CALL pclascl(
'G', smlnum, bnrm, scllen, nrhs, b, ib, jb,
584 ELSE IF( ibscl.EQ.2 )
THEN
585 CALL pclascl(
'G', bignum, bnrm, scllen, nrhs, b, ib, jb,
591 work( 1 ) =
cmplx( real( lwmin ) )