Strange phenomenon of ZGESVD

Open discussion regarding features, bugs, issues, vendors, etc.

Strange phenomenon of ZGESVD

Postby chenxikane » Thu Feb 16, 2012 2:02 pm

Hello, everyone, thank you for reading my topic.

I have encountered a strange phenomenon, when I call ZGESVD to Singular Value Decomposition, I discover it can not handle the matrix which size bigger than 132 in my program(it needs unbelievable memory >2.7G), however the similar ZGGSVD works well for the same size of matrix. So I am confused to this. Then I tried ZGGSVD and ZGESVD both, if matrix is not bigger than 132, both of ZGGSVD and ZGESVD can be functional both, however if W>=16, ZGGSVD works well, but ZGESVD crushed. I do not understand this. And I checked my program many times, I can not find what could cause this strange result. Anyway, I think even I inputted a weird matrix, the result of ZGESVD should not be crush of program.

Therefore, if anyone can help me, I will very appreciate.

My program is following, my FORTRAN environment is IVF2011+MVS+MKL(lapack). And one can input the wcs, then the later subroutine will generate a square matrix for SVD. If wcs <=15, everything is OK, if wcs>=16, ZGGSVD is OK, ZZGESVD will crush.
!=================================================
program tryZGESVD
implicit none
external zgesvd
external zggsvd

integer :: Wcs,Sz
complex(8),dimension(4) :: MtrxElmt

!input and output for ZGGSVD and ZGGSVD
integer :: lwork,info,SDK,SDL
real(8),dimension(:),allocatable :: sglV(:),rwork2(:),rwork1(:),alpha,beta
complex(8),dimension(:,:),allocatable :: SVDU,SVDVt,SVDQ,Mtrx00,Mtrx,Mtrxb
complex,allocatable,dimension(:) :: work0,work1,work2,iwork

write(*,*) "input Wcs(INTEGER), the size of matirx = (wcs*2+1)*4"
write(*,*) "if wcs<=15, everything works well, but if wcs>=16, ZGESVD directly crushed"
read(*,*) wcs

sz=(wcs*2+1)*4

!Establish Matrix, by the following subroutine, just a sz by sz matrix, which only lower-left block is valued
allocate(Mtrx00(sz,sz))
allocate(Mtrx(sz,sz))
Mtrx00=0
MtrxElmt=(/-1.0d0,-0.1d0,-0.1d0,-1.0d0/)
call MFSup1(wcs*2+1,wcs*2+1,2,2,(/Wcs,wcs+1/),(/wcs+1,Wcs/),MtrxElmt,Mtrx00(6*Wcs+4:Sz,1:wcs*2+1))


allocate(SVDU(sz,sz))
allocate(SVDvt(sz,sz))
allocate(SVDQ(sz,sz))

!zggsvd can give the SVD when wcs>16, i.e. sz>132
Mtrx=Mtrx00
allocate(alpha(sz))
allocate(beta(sz))
allocate(work1(4*sz))
allocate(Mtrxb(sz,sz))
allocate(iwork(sz))
allocate(rwork1(sz*2))
Mtrxb=0
call zggsvd( "N", "N", "Q", sz,sz,sz,SDk,SDl,Mtrx,sz,Mtrxb,sz, alpha, beta,SVDu,sz,SVDvt,sz,SVDQ,sz, work1, rwork1, iwork, info)
!write(*,*) "SVDQ",SVDQ(1:sz,1)

!zgesvd can NOT give the SVD when wcs>16, i.e. sz>132
allocate(sglV(sz))
allocate(rwork2(sz*5))
SVDU=0
SVDvt=0
Mtrx=Mtrx00
!call zgesvd( jobu,jobvt, m, n, a, lda, s, SVDU, ldu, SVDvt,ldvt, work, lwork, rwork, info)
call zgesvd( "A", "A",Sz,Sz,Mtrx, Sz,sglV, SVDU, Sz, SVDVt, Sz, rwork2, -1, rwork2, info)
lwork=rwork2(1)
allocate(work0(lwork))
write(*,*) lwork
rwork2=0
Mtrx=Mtrx00
!call zgesvd( jobu,jobvt, m, n, a, lda, s, SVDU, ldu, SVDvt,ldvt, work, lwork, rwork, info)
call zgesvd( "A", "A",Sz,Sz,Mtrx, Sz,sglV, SVDU, Sz, SVDVt, Sz, work0, lwork, rwork2, info)
deallocate(work0)
!write(*,*) "SVDvt",SVDvt(1:sz,1)
write(*,*) "sglV",sglV
end program

! ============================================================
subroutine MFSup1(SizeLTotal,SizeCTotal,BlockL,BlockC,SizeL,sizeC,BlockValue,res)
!This give all kinds of matrix block.
! ============================================================
implicit none
integer,intent(in) :: SizeLTotal,SizeCTotal,BlockL,BlockC
integer,intent(in) :: SizeL(BlockL),SizeC(BlockC)
complex(8),intent(in),dimension(BlockL*BlockC) :: BlockValue
complex(8),intent(out),dimension(SizeLTotal,SizeCTotal) :: res
integer :: StartL(BlockL),EndL(BlockL),StartC(BlockC),EndC(BlockC)
integer :: i1,i2,InitialL,FinalL,InitialC,FinalC

if (Sum(SizeL).ne.SizeLTotal.or.Sum(SizeC).ne.SizeCTotal) then
continue
stop 'MFSup1'
end if

InitialL=1
FinalL=0
StartL(1)=InitialL
EndL(BlockL)=SizeLTotal
do i1=1,BlockL-1
InitialL=InitialL+SizeL(i1)
StartL(i1+1)=InitialL
FinalL=FinalL+SizeL(i1)
EndL(i1)=FinalL
end do
InitialC=1
FinalC=0
StartC(1)=InitialC
EndC(BlockC)=SizeCTotal
do i1=1,BlockC-1
InitialC=InitialC+SizeC(i1)
StartC(i1+1)=InitialC
FinalC=FinalC+SizeC(i1)
EndC(i1)=FinalC
end do

do i1=1,BlockL
do i2=1,BlockC
call MFOri2(SizeL(i1),SizeC(i2),BlockValue((i1-1)*BlockC+i2),res(StartL(i1):EndL(i1),StartC(i2):EndC(i2)))
end do
end do

end subroutine MFSup1

! ============================================================
subroutine MFOri2(Size1,Size2,DiagE,res)
!This give the non-square matrix with only semi-diagonal elements.
! ============================================================
implicit none
integer,intent(in) :: size1,Size2
complex(8),intent(in) :: DiagE
complex(8),intent(out),dimension(size1,size2) :: res
integer :: i1,i2,temp
res=0

if (size1.gt.size2) then
temp=size1-size2
do i1=1,size2
res(i1,i1)=DiagE
res(i1+temp,i1)=DiagE
end do
else if (size1.lt.size2) then
temp=size2-size1
do i1=1,size1
res(i1,i1)=DiagE
res(i1,i1+temp)=DiagE
end do
else if (size1.eq.size2) then
do i1=1,size1
res(i1,i1)=DiagE
end do
end if

end subroutine MFOri2
chenxikane
 
Posts: 1
Joined: Thu Feb 16, 2012 12:49 pm

Return to User Discussion

Who is online

Users browsing this forum: Google [Bot], Yahoo [Bot] and 2 guests

cron