这是我第一次尝试使用Lapack。我正在使用Forgran 90,我想构建一个易于使用的包装器子程序SVD(A,U,S,V)供我稍后在计算奇异值分解问题时使用。特别是,我使用DGESDD函数,并且我将我的程序基于example,我能够编译并运行。
我制作的代码如下:
module Statistics
contains
subroutine SVD(a,u,s,v)
real, dimension(:,:), intent(inout) :: a
real, dimension(:,:), intent(out) :: u,v
real, dimension(:), intent(out) :: s
real, dimension(:,:), allocatable :: vt
real, dimension(:), allocatable :: work
integer, dimension(:), allocatable :: iwork
integer :: lda, m, n, lwork, ldvt, info, mx, mn, lwmax=1000
character(len=1) :: jobz
m=size(a,1)
n=size(a,2)
mx=max(m,n)
mn=min(m,n)
jobz='a'
lda=m
ldu=m
ldvt=n
lwork=-1
allocate(vt(n,n))
allocate(work(lwmax))
allocate(iwork(8*mn))
! print*, 'a', shape(a)
! print*, 'vt', shape(vt)
! print*, 'u', shape(u)
! print*, 'work', shape(work)
! print*, 'iwork', shape(iwork)
call dgesdd( jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, iwork, info )
lwork = min( lwmax, int( work( 1 ) ) )
print*, lwork
call dgesdd(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, iwork, info )
v=transpose(vt)
end subroutine SVD
end module Statistics
program test
use Statistics
external dgesdd
real a(4,2),u(4,4),s(2),v(2,2)
k=1
do i=1,4
do j=1,2
a(i,j)=k*1.0d0
k=k+1
end do
end do
write(*,*) 'a ='
write(*,'(2f10.4)') ((a(i,j),j=1,2),i=1,4)
call svd(a,u,s,v)
write(*,*) 'u ='
write(*,'(4f10.4)') ((u(i,j),j=1,4),i=1,4)
write(*,*) 'v='
write(*,'(2f10.4)') v
write(*,*) 's ='
write(*,'(2f10.4)')s
end program test
但是它拒绝工作,虽然我没有看到它与上面的例子有什么不同。在第一次调用子例程以查询iwork的最佳大小时,问题就出现了。它返回0.但是,如果我覆盖该值并将其设置为1000,那么在第二次调用中它会导致分段错误。它必须是与矩阵分配有关的傻事,但我已经尝试了很多东西,而且我的想法已经不多了。