为Lapack子例程构建Fortran 90包装器

时间:2017-08-31 13:09:36

标签: segmentation-fault fortran fortran90 lapack

这是我第一次尝试使用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,那么在第二次调用中它会导致分段错误。它必须是与矩阵分配有关的傻事,但我已经尝试了很多东西,而且我的想法已经不多了。

0 个答案:

没有答案