2 SUBROUTINE pzgesvd(JOBU,JOBVT,M,N,A,IA,JA,DESCA,S,U,IU,JU,DESCU,
3 + VT,IVT,JVT,DESCVT,WORK,LWORK,RWORK,INFO)
13 INTEGER IA,INFO,IU,IVT,JA,JU,JVT,LWORK,M,N
16 INTEGER DESCA(*),DESCU(*),DESCVT(*)
17 COMPLEX*16 A(*),U(*),VT(*),WORK(*)
19 DOUBLE PRECISION RWORK(*)
290 INTEGER BLOCK_CYCLIC_2D,DLEN_,DTYPE_,CTXT_,M_,N_,MB_,NB_,RSRC_,
292 parameter(block_cyclic_2d=1,dlen_=9,dtype_=1,ctxt_=2,m_=3,n_=4,
293 + mb_=5,nb_=6,rsrc_=7,csrc_=8,lld_=9,ithval=10)
295 parameter(zero= ((0.0d+0,0.0d+0)),one= ((1.0d+0,0.0d+0)))
296 DOUBLE PRECISION DZERO,DONE
297 parameter(dzero=0.0d+0,done=1.0d+0)
301 INTEGER CONTEXTC,CONTEXTR,I,INDD,INDD2,INDE,INDE2,INDTAUP,INDTAUQ,
302 + indu,indv,indwork,ioffd,ioffe,iscale,j,k,ldu,ldvt,llwork,
303 + lwmin,maxim,mb,mp,mypcol,mypcolc,mypcolr,myprow,myprowc,
304 + myprowr,nb,ncvt,npcol,npcolc,npcolr,nprocs,nprow,nprowc,
305 + nprowr,nq,nru,
SIZE,sizeb,sizep,sizepos,sizeq,wantu,wantvt,
306 + watobd,wbdtosvd,wzbdsqr,wpzgebrd,wpzlange,wpzormbrprt,
308 DOUBLE PRECISION ANRM,BIGNUM,EPS,RMAX,RMIN,SAFMIN,SIGMA,SMLNUM
311 INTEGER DESCTU(DLEN_),DESCTVT(DLEN_),IDUM1(3),IDUM2(3)
312 DOUBLE PRECISION C(1,1)
317 DOUBLE PRECISION PDLAMCH,PZLANGE
318 EXTERNAL lsame,numroc,pdlamch,pzlange
321 EXTERNAL blacs_get,blacs_gridexit,blacs_gridinfo,blacs_gridinit,
327 INTRINSIC max,
min,sqrt,dble
332 IF (block_cyclic_2d*dtype_*lld_*mb_*m_*nb_*n_.LT.0)
RETURN
334 CALL blacs_gridinfo(desca(ctxt_),nprow,npcol,myprow,mypcol)
338 IF (nprow.EQ.-1)
THEN
355 IF (lsame(jobu,
'V'))
THEN
360 IF (lsame(jobvt,
'V'))
THEN
366 CALL chk1mat(m,3,n,4,ia,ja,desca,8,info)
368 CALL chk1mat(m,3,
SIZE,sizepos,iu,ju,descu,13,info)
370 IF (wantvt.EQ.1)
THEN
371 CALL chk1mat(
SIZE,sizepos,n,4,ivt,jvt,descvt,17,info)
373 CALL igamx2d(desca(ctxt_),
'A',
' ',1,1,info,1,1,1,-1,-1,0)
380 inde = indd + sizeb + ioffd
381 indd2 = inde + sizeb + ioffe
382 inde2 = indd2 + sizeb + ioffd
385 indtaup = indtauq + sizeb + ja - 1
386 indwork = indtaup + sizeb + ia - 1
387 llwork = lwork - indwork + 1
391 CALL blacs_get(desca(ctxt_),10,contextc)
392 CALL blacs_gridinit(contextc,
'R',nprocs,1)
393 CALL blacs_gridinfo(contextc,nprowc,npcolc,myprowc,
395 CALL blacs_get(desca(ctxt_),10,contextr)
396 CALL blacs_gridinit(contextr,
'R',1,nprocs)
397 CALL blacs_gridinfo(contextr,nprowr,npcolr,myprowr,
402 nru = numroc(m,1,myprowc,0,nprocs)
403 ncvt = numroc(n,1,mypcolr,0,nprocs)
406 mp = numroc(m,mb,myprow,desca(rsrc_),nprow)
407 nq = numroc(n,nb,mypcol,desca(csrc_),npcol)
408 IF (wantvt.EQ.1)
THEN
409 sizep = numroc(
SIZE,descvt(mb_),myprow,descvt(rsrc_),
415 sizeq = numroc(
SIZE,descu(nb_),mypcol,descu(csrc_),
423 IF (myprow.EQ.0 .AND. mypcol.EQ.0)
THEN
425 CALL igebs2d(desca(ctxt_),
'All',
' ',1,1,maxim,1)
427 CALL igebr2d(desca(ctxt_),
'All',
' ',1,1,maxim,1,0,0)
431 wpzgebrd = nb* (mp+nq+1) + nq
432 watobd =
max(
max(wpzlange,wpzgebrd),maxim)
434 wzbdsqr =
max(1,4*size)
435 wpzormbrqln =
max((nb* (nb-1))/2, (sizeq+mp)*nb) + nb*nb
436 wpzormbrprt =
max((mb* (mb-1))/2, (sizep+nq)*mb) + mb*mb
437 wbdtosvd = size* (wantu*nru+wantvt*ncvt) +
438 +
max(wzbdsqr,
max(wantu*wpzormbrqln,
439 + wantvt*wpzormbrprt))
443 lwmin = 1 + 2*sizeb +
max(watobd,wbdtosvd)
444 work(1) = dcmplx(lwmin,0d+00)
445 rwork(1) = dble(1+4*sizeb)
447 IF (wantu.NE.1 .AND. .NOT. (lsame(jobu,
'N')))
THEN
449 ELSE IF (wantvt.NE.1 .AND. .NOT. (lsame(jobvt,
'N')))
THEN
451 ELSE IF (lwork.LT.lwmin .AND. lwork.NE.-1)
THEN
459 IF (lwork.EQ.-1)
THEN
467 CALL pchk1mat(m,3,n,4,ia,ja,desca,8,3,idum1,idum2,info)
470 CALL pchk1mat(m,3,
SIZE,4,iu,ju,descu,13,0,idum1,idum2,
473 IF (wantvt.EQ.1)
THEN
474 CALL pchk1mat(
SIZE,3,n,4,ivt,jvt,descvt,17,0,idum1,
482 CALL pxerbla(desca(ctxt_),
'PZGESVD',-info)
484 ELSE IF (lwork.EQ.-1)
THEN
490 IF (m.LE.0 .OR. n.LE.0)
GO TO 40
494 safmin = pdlamch(desca(ctxt_),
'Safe minimum')
495 eps = pdlamch(desca(ctxt_),
'Precision')
499 rmax =
min(sqrt(bignum),done/sqrt(sqrt(safmin)))
503 anrm = pzlange(
'1',m,n,a,ia,ja,desca,work(indwork))
504 IF (anrm.GT.dzero .AND. anrm.LT.rmin)
THEN
507 ELSE IF (anrm.GT.rmax)
THEN
512 IF (iscale.EQ.1)
THEN
513 CALL pzlascl(
'G',done,sigma,m,n,a,ia,ja,desca,info)
516 CALL pzgebrd(m,n,a,ia,ja,desca,rwork(indd),rwork(inde),
517 + work(indtauq),work(indtaup),work(indwork),llwork,
528 CALL pdlared1d(n+ioffd,ia,ja,desca,rwork(indd),rwork(indd2),
529 + work(indwork),llwork)
531 CALL pdlared2d(m+ioffe,ia,ja,desca,rwork(inde),rwork(inde2),
532 + work(indwork),llwork)
535 CALL pdlared2d(m+ioffd,ia,ja,desca,rwork(indd),rwork(indd2),
536 + work(indwork),llwork)
538 CALL pdlared1d(n+ioffe,ia,ja,desca,rwork(inde),rwork(inde2),
539 + work(indwork),llwork)
551 indv = indu + size*nru*wantu
552 indwork = indv + size*ncvt*wantvt
557 CALL descinit(desctu,m,
SIZE,1,1,0,0,contextc,ldu,info)
558 CALL descinit(desctvt,
SIZE,n,1,1,0,0,contextr,ldvt,info)
561 CALL pzlaset(
'Full',m,
SIZE,zero,one,work(indu),1,1,desctu)
566 IF (wantvt.EQ.1)
THEN
567 CALL pzlaset(
'Full',
SIZE,n,zero,one,work(indv),1,1,desctvt)
572 CALL zbdsqr(uplo,
SIZE,ncvt,nru,0,rwork(indd2+ioffd),
573 + rwork(inde2+ioffe),work(indv),
SIZE,work(indu),ldu,c,1,
574 + work(indwork),info)
578 IF (wantu.EQ.1)
CALL pzgemr2d(m,
SIZE,work(indu),1,1,desctu,u,iu,
579 + ju,descu,descu(ctxt_))
581 IF (wantvt.EQ.1)
CALL pzgemr2d(
SIZE,n,work(indv),1,1,desctvt,vt,
582 + ivt,jvt,descvt,descvt(ctxt_))
586 IF (m.GT.n .AND. wantu.EQ.1)
THEN
587 CALL pzlaset(
'Full',m-
SIZE,
SIZE,zero,zero,u,ia+
SIZE,ju,descu)
588 ELSE IF (n.GT.m .AND. wantvt.EQ.1)
THEN
589 CALL pzlaset(
'Full',
SIZE,n-
SIZE,zero,zero,vt,ivt,jvt+
SIZE,
595 IF (wantu.EQ.1)
CALL pzunmbr(
'Q',
'L',
'N',m,
SIZE,n,a,ia,ja,desca,
596 + work(indtauq),u,iu,ju,descu,
597 + work(indwork),llwork,info)
599 IF (wantvt.EQ.1)
CALL pzunmbr(
'P',
'R',
'C',
SIZE,n,m,a,ia,ja,desca,
600 + work(indtaup),vt,ivt,jvt,descvt,
601 + work(indwork),llwork,info)
606 s(i) = rwork(indd2+ioffd+i-1)
611 IF (iscale.EQ.1)
THEN
612 CALL dscal(
SIZE,one/sigma,s,1)
618 IF (size.LE.ithval)
THEN
627 rwork(i+inde) = s((i-1)*k+1)
628 rwork(i+indd2) = s((i-1)*k+1)
631 CALL dgamn2d(desca(ctxt_),
'a',
' ',j,1,rwork(1+inde),j,1,1,-1,-1,0)
632 CALL dgamx2d(desca(ctxt_),
'a',
' ',j,1,rwork(1+indd2),j,1,1,-1,-1,
636 IF ((rwork(i+inde)-rwork(i+indd2)).NE.dzero)
THEN
643 CALL blacs_gridexit(contextc)
644 CALL blacs_gridexit(contextr)