我正在对方阵A进行svd分解,A = U S Vdag,在fortran代码中,行读取
lwork = -1
call zgesvd( 'A', 'A', A%d, A%d, A%m, A%d, S, U%m, U%d, Vdag%m, Vdag%d,work, lwork, rwork, info )
lwork = int(work(1));deallocate(work); allocate(work(lwork))
call zgesvd( 'A', 'A', A%d, A%d, A%m, A%d, S, U%m, U%d, Vdag%m, Vdag%d,work, lwork, rwork, info )
当我使用gfortran编译时,它没有任何错误或警告。但是,当我运行程序时,它显示错误消息:
" **进入ZGESVD参数号11时有非法值"
我无法弄清楚出了什么问题。
供参考,参数的定义:
type cmatrix
integer(4) d
complex(8), allocatable :: m(:,:)
end type
type (cmatrix) A,U,Vdag
allocate(A%m(dim,dim),U%m(dim,dim),Vdag%m(dim,dim))
A%d = dim; U%m = dim; Vdag%d = dim
real(8) S(dim)
提前致谢! 小予
P.S。应该提到的是,当使用ifort编译时,这样的程序运行顺利,但gfortran给出了运行时错误,如上所示
---问题解决了!
似乎问题在于ifortran和gfortran如何分配内存。我在代码中定义了USV类型:
type USV
integer is_alloc
type (cmatrix) U,V
real(8), allocatable :: S(:)
end USV
按
初始化时type(USV) Test_usv(:)
allocate(Test_usv(3)),
使用intel fortran编译器,is_alloc的值为0,而gfortran为任意数。我需要使用此值作为分配U V矩阵的标准:
if (is_alloc.eq.0) then
allocate(U%m(dim,dim))
end if
答案 0 :(得分:1)
根本问题不在于ifort和gfortran之间的区别。您对变量初始化的方法是无效的Fortran。除非使用声明,赋值语句等初始化变量,否则其值是未定义的。解决此问题的一种方法是在类型定义中添加默认初始化:
type USV
integer is_alloc = 0
type (cmatrix) U,V
real(8), allocatable :: S(:)
end USV
另一种方法是不自己跟踪分配状态,并依赖Fortran为此目的提供的内在功能:
if (.NOT. allocated (U%m) ) allocate(U%m(dim,dim))
P.S。最佳做法是不依赖于特定的数值。种类值是任意的,不一定是该类型的字节数。有些编译器使用字节数,有些则没有。指定字节数和具有可移植代码的一种方法是使用ISO Fortran环境提供的类型:
use, intrinsic :: ISO_FORTRAN_ENV
integer(int32) :: d
real(real64), allocatable :: S(:)
类型以位数命名。可用类型的列表位于gfortran手册的“内在模块”一章中。