1 SUBROUTINE pzgels( 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*16 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 )
234 DOUBLE PRECISION ZERO, ONE
235 parameter( zero = 0.0d+0, one = 1.0d+0 )
236 COMPLEX*16 CZERO, CONE
237 parameter( czero = ( 0.0d+0, 0.0d+0 ),
238 $ cone = ( 1.0d+0, 0.0d+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 DOUBLE PRECISION ANRM, BIGNUM, BNRM, SMLNUM
250 INTEGER IDUM1( 2 ), IDUM2( 2 )
251 DOUBLE PRECISION RWORK( 1 )
256 INTEGER INDXG2P, NUMROC
257 DOUBLE PRECISION PDLAMCH, PZLANGE
258 EXTERNAL ilcm, indxg2p, lsame, numroc, pdlamch,
267 INTRINSIC dble, dcmplx, ichar,
max,
min, mod
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 ) = dcmplx( dble( 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,
'PZGELS', -info )
382 ELSE IF( lquery )
THEN
388 IF(
min( m, n, nrhs ).EQ.0 )
THEN
389 CALL pzlaset(
'Full',
max( m, n ), nrhs, czero, czero, b,
396 smlnum = pdlamch( ictxt,
'S' )
397 smlnum = smlnum / pdlamch( ictxt,
'P' )
398 bignum = one / smlnum
399 CALL pdlabad( ictxt, smlnum, bignum )
403 anrm = pzlange(
'M', m, n, a, ia, ja, desca, rwork )
405 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
409 CALL pzlascl(
'G', anrm, smlnum, m, n, a, ia, ja, desca,
412 ELSE IF( anrm.GT.bignum )
THEN
416 CALL pzlascl(
'G', anrm, bignum, m, n, a, ia, ja, desca,
419 ELSE IF( anrm.EQ.zero )
THEN
423 CALL pzlaset(
'F',
max( m, n ), nrhs, czero, czero, b, ib,
432 bnrm = pzlange(
'M', brow, nrhs, b, ib, jb, descb, rwork )
435 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
439 CALL pzlascl(
'G', bnrm, smlnum, brow, nrhs, b, ib, jb,
442 ELSE IF( bnrm.GT.bignum )
THEN
446 CALL pzlascl(
'G', bnrm, bignum, brow, nrhs, b, ib, jb,
457 CALL pzgeqrf( m, n, a, ia, ja, desca, work, work( ipw ),
468 CALL pzunmqr(
'Left',
'Conjugate transpose', m, nrhs, n, a,
469 $ ia, ja, desca, work, b, ib, jb, descb,
470 $ work( ipw ), lwork-ltau, info )
477 CALL pztrsm(
'Left',
'Upper',
'No transpose',
'Non-unit', n,
478 $ nrhs, cone, a, ia, ja, desca, b, ib, jb,
489 CALL pztrsm(
'Left',
'Upper',
'Conjugate transpose',
490 $
'Non-unit', n, nrhs, cone, a, ia, ja, desca,
495 CALL pzlaset(
'All', m-n, nrhs, czero, czero, b, ib+n, jb,
501 CALL pzunmqr(
'Left',
'No transpose', m, nrhs, n, a, ia, ja,
502 $ desca, work, b, ib, jb, descb, work( ipw ),
515 CALL pzgelqf( m, n, a, ia, ja, desca, work, work( ipw ),
527 CALL pztrsm(
'Left',
'Lower',
'No transpose',
'Non-unit', m,
528 $ nrhs, cone, a, ia, ja, desca, b, ib, jb,
533 CALL pzlaset(
'All', n-m, nrhs, czero, czero, b, ib+m, jb,
539 CALL pzunmlq(
'Left',
'Conjugate transpose', n, nrhs, m, a,
540 $ ia, ja, desca, work, b, ib, jb, descb,
541 $ work( ipw ), lwork-ltau, info )
553 CALL pzunmlq(
'Left',
'No transpose', n, nrhs, m, a, ia, ja,
554 $ desca, work, b, ib, jb, descb, work( ipw ),
562 CALL pztrsm(
'Left',
'Lower',
'Conjugate transpose',
563 $
'Non-unit', m, nrhs, cone, a, ia, ja, desca,
574 IF( iascl.EQ.1 )
THEN
575 CALL pzlascl(
'G', anrm, smlnum, scllen, nrhs, b, ib, jb,
577 ELSE IF( iascl.EQ.2 )
THEN
578 CALL pzlascl(
'G', anrm, bignum, scllen, nrhs, b, ib, jb,
581 IF( ibscl.EQ.1 )
THEN
582 CALL pzlascl(
'G', smlnum, bnrm, scllen, nrhs, b, ib, jb,
584 ELSE IF( ibscl.EQ.2 )
THEN
585 CALL pzlascl(
'G', bignum, bnrm, scllen, nrhs, b, ib, jb,
591 work( 1 ) = dcmplx( dble( lwmin ) )