2 SUBROUTINE pdgesvd(JOBU,JOBVT,M,N,A,IA,JA,DESCA,S,U,IU,JU,DESCU,
3 + VT,IVT,JVT,DESCVT,WORK,LWORK,INFO)
13 INTEGER IA,INFO,IU,IVT,JA,JU,JVT,LWORK,M,N
16 INTEGER DESCA(*),DESCU(*),DESCVT(*)
17 DOUBLE PRECISION A(*),U(*),VT(*),WORK(*)
286 INTEGER BLOCK_CYCLIC_2D,DLEN_,DTYPE_,CTXT_,M_,N_,MB_,NB_,RSRC_,
288 parameter(block_cyclic_2d=1,dlen_=9,dtype_=1,ctxt_=2,m_=3,n_=4,
289 + mb_=5,nb_=6,rsrc_=7,csrc_=8,lld_=9,ithval=10)
290 DOUBLE PRECISION ZERO,ONE
291 parameter(zero= (0.0d+0),one= (1.0d+0))
295 INTEGER CONTEXTC,CONTEXTR,I,INDD,INDD2,INDE,INDE2,INDTAUP,INDTAUQ,
296 + indu,indv,indwork,ioffd,ioffe,iscale,j,k,ldu,ldvt,llwork,
297 + lwmin,maxim,mb,mp,mypcol,mypcolc,mypcolr,myprow,myprowc,
298 + myprowr,nb,ncvt,npcol,npcolc,npcolr,nprocs,nprow,nprowc,
299 + nprowr,nq,nru,
SIZE,sizeb,sizep,sizepos,sizeq,wantu,wantvt,
300 + watobd,wbdtosvd,wdbdsqr,wpdgebrd,wpdlange,wpdormbrprt,
302 DOUBLE PRECISION ANRM,BIGNUM,EPS,RMAX,RMIN,SAFMIN,SIGMA,SMLNUM
305 INTEGER DESCTU(DLEN_),DESCTVT(DLEN_),IDUM1(3),IDUM2(3)
306 DOUBLE PRECISION C(1,1)
311 DOUBLE PRECISION PDLAMCH,PDLANGE
312 EXTERNAL lsame,numroc,pdlamch,
pzlange
315 EXTERNAL blacs_get,blacs_gridexit,blacs_gridinfo,blacs_gridinit,
321 INTRINSIC max,
min,sqrt,dble
325 IF (block_cyclic_2d*dtype_*lld_*mb_*m_*nb_*n_.LT.0)
RETURN
327 CALL blacs_gridinfo(desca(ctxt_),nprow,npcol,myprow,mypcol)
331 IF (nprow.EQ.-1)
THEN
348 IF (lsame(jobu,
'V'))
THEN
353 IF (lsame(jobvt,
'V'))
THEN
359 CALL chk1mat(m,3,n,4,ia,ja,desca,8,info)
361 CALL chk1mat(m,3,
SIZE,sizepos,iu,ju,descu,13,info)
363 IF (wantvt.EQ.1)
THEN
364 CALL chk1mat(
SIZE,sizepos,n,4,ivt,jvt,descvt,17,info)
366 CALL igamx2d(desca(ctxt_),
'A',
' ',1,1,info,1,1,1,-1,-1,0)
373 inde = indd + sizeb + ioffd
374 indd2 = inde + sizeb + ioffe
375 inde2 = indd2 + sizeb + ioffd
377 indtauq = inde2 + sizeb + ioffe
378 indtaup = indtauq + sizeb + ja - 1
379 indwork = indtaup + sizeb + ia - 1
380 llwork = lwork - indwork + 1
384 CALL blacs_get(desca(ctxt_),10,contextc)
385 CALL blacs_gridinit(contextc,
'R',nprocs,1)
386 CALL blacs_gridinfo(contextc,nprowc,npcolc,myprowc,
388 CALL blacs_get(desca(ctxt_),10,contextr)
389 CALL blacs_gridinit(contextr,
'R',1,nprocs)
390 CALL blacs_gridinfo(contextr,nprowr,npcolr,myprowr,
395 nru = numroc(m,1,myprowc,0,nprocs)
396 ncvt = numroc(n,1,mypcolr,0,nprocs)
399 mp = numroc(m,mb,myprow,desca(rsrc_),nprow)
400 nq = numroc(n,nb,mypcol,desca(csrc_),npcol)
401 IF (wantvt.EQ.1)
THEN
402 sizep = numroc(
SIZE,descvt(mb_),myprow,descvt(rsrc_),
408 sizeq = numroc(
SIZE,descu(nb_),mypcol,descu(csrc_),
416 IF (myprow.EQ.0 .AND. mypcol.EQ.0)
THEN
418 CALL igebs2d(desca(ctxt_),
'All',
' ',1,1,maxim,1)
420 CALL igebr2d(desca(ctxt_),
'All',
' ',1,1,maxim,1,0,0)
424 wpdgebrd = nb* (mp+nq+1) + nq
425 watobd =
max(
max(wpdlange,wpdgebrd),maxim)
427 wdbdsqr =
max(1,4*size)
428 wpdormbrqln =
max((nb* (nb-1))/2, (sizeq+mp)*nb) + nb*nb
429 wpdormbrprt =
max((mb* (mb-1))/2, (sizep+nq)*mb) + mb*mb
430 wbdtosvd = size* (wantu*nru+wantvt*ncvt) +
431 +
max(wdbdsqr,
max(wantu*wpdormbrqln,
432 + wantvt*wpdormbrprt))
436 lwmin = 1 + 6*sizeb +
max(watobd,wbdtosvd)
437 work(1) = dble(lwmin)
439 IF (wantu.NE.1 .AND. .NOT. (lsame(jobu,
'N')))
THEN
441 ELSE IF (wantvt.NE.1 .AND. .NOT. (lsame(jobvt,
'N')))
THEN
443 ELSE IF (lwork.LT.lwmin .AND. lwork.NE.-1)
THEN
451 IF (lwork.EQ.-1)
THEN
459 CALL pchk1mat(m,3,n,4,ia,ja,desca,8,3,idum1,idum2,info)
462 CALL pchk1mat(m,3,
SIZE,4,iu,ju,descu,13,0,idum1,idum2,
465 IF (wantvt.EQ.1)
THEN
466 CALL pchk1mat(
SIZE,3,n,4,ivt,jvt,descvt,17,0,idum1,
474 CALL pxerbla(desca(ctxt_),
'PDGESVD',-info)
476 ELSE IF (lwork.EQ.-1)
THEN
482 IF (m.LE.0 .OR. n.LE.0)
GO TO 40
486 safmin = pdlamch(desca(ctxt_),
'Safe minimum')
487 eps = pdlamch(desca(ctxt_),
'Precision')
491 rmax =
min(sqrt(bignum),one/sqrt(sqrt(safmin)))
495 anrm = pdlange(
'1',m,n,a,ia,ja,desca,work(indwork))
496 IF (anrm.GT.zero .AND. anrm.LT.rmin)
THEN
499 ELSE IF (anrm.GT.rmax)
THEN
504 IF (iscale.EQ.1)
THEN
505 CALL pdlascl(
'G',one,sigma,m,n,a,ia,ja,desca,info)
508 CALL pdgebrd(m,n,a,ia,ja,desca,work(indd),work(inde),
509 + work(indtauq),work(indtaup),work(indwork),llwork,
520 CALL pdlared1d(n+ioffd,ia,ja,desca,work(indd),work(indd2),
521 + work(indwork),llwork)
523 CALL pdlared2d(m+ioffe,ia,ja,desca,work(inde),work(inde2),
524 + work(indwork),llwork)
527 CALL pdlared2d(m+ioffd,ia,ja,desca,work(indd),work(indd2),
528 + work(indwork),llwork)
530 CALL pdlared1d(n+ioffe,ia,ja,desca,work(inde),work(inde2),
531 + work(indwork),llwork)
543 indv = indu + size*nru*wantu
544 indwork = indv + size*ncvt*wantvt
549 CALL descinit(desctu,m,
SIZE,1,1,0,0,contextc,ldu,info)
550 CALL descinit(desctvt,
SIZE,n,1,1,0,0,contextr,ldvt,info)
553 CALL pdlaset(
'Full',m,
SIZE,zero,one,work(indu),1,1,desctu)
558 IF (wantvt.EQ.1)
THEN
559 CALL pdlaset(
'Full',
SIZE,n,zero,one,work(indv),1,1,desctvt)
564 CALL dbdsqr(uplo,
SIZE,ncvt,nru,0,work(indd2+ioffd),
565 + work(inde2+ioffe),work(indv),
SIZE,work(indu),ldu,c,1,
566 + work(indwork),info)
570 IF (wantu.EQ.1)
CALL pdgemr2d(m,
SIZE,work(indu),1,1,desctu,u,iu,
571 + ju,descu,descu(ctxt_))
573 IF (wantvt.EQ.1)
CALL pdgemr2d(
SIZE,n,work(indv),1,1,desctvt,vt,
574 + ivt,jvt,descvt,descvt(ctxt_))
578 IF (m.GT.n .AND. wantu.EQ.1)
THEN
579 CALL pdlaset(
'Full',m-
SIZE,
SIZE,zero,zero,u,ia+
SIZE,ju,descu)
580 ELSE IF (n.GT.m .AND. wantvt.EQ.1)
THEN
581 CALL pdlaset(
'Full',
SIZE,n-
SIZE,zero,zero,vt,ivt,jvt+
SIZE,
587 IF (wantu.EQ.1)
CALL pdormbr(
'Q',
'L',
'N',m,
SIZE,n,a,ia,ja,desca,
588 + work(indtauq),u,iu,ju,descu,
589 + work(indwork),llwork,info)
591 IF (wantvt.EQ.1)
CALL pdormbr(
'P',
'R',
'T',
SIZE,n,m,a,ia,ja,desca,
592 + work(indtaup),vt,ivt,jvt,descvt,
593 + work(indwork),llwork,info)
598 s(i) = work(indd2+ioffd+i-1)
603 IF (iscale.EQ.1)
THEN
604 CALL dscal(
SIZE,one/sigma,s,1)
610 IF (size.LE.ithval)
THEN
619 work(i+inde) = s((i-1)*k+1)
620 work(i+indd2) = s((i-1)*k+1)
623 CALL dgamn2d(desca(ctxt_),
'a',
' ',j,1,work(1+inde),j,1,1,-1,-1,0)
624 CALL dgamx2d(desca(ctxt_),
'a',
' ',j,1,work(1+indd2),j,1,1,-1,-1,0)
627 IF ((work(i+inde)-work(i+indd2)).NE.zero)
THEN
634 CALL blacs_gridexit(contextc)
635 CALL blacs_gridexit(contextr)