Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matrix 用Fortran中的ZGETRI求逆矩阵_Matrix_Fortran_Lapack_Intel Fortran - Fatal编程技术网

Matrix 用Fortran中的ZGETRI求逆矩阵

Matrix 用Fortran中的ZGETRI求逆矩阵,matrix,fortran,lapack,intel-fortran,Matrix,Fortran,Lapack,Intel Fortran,我试图用ZGETRI计算复矩阵的逆,但是 即使执行时没有错误(info=0), 它没有给我正确的逆矩阵,我有绝对的 不知道错误来自哪里 PROGRAM solvelinear implicit none INTEGER :: i,j,info,lwork INTEGER,dimension(3) :: ipiv COMPLEX(16), dimension(3,3) :: C,Cinv,M,LU COMPLEX(16),allocata

我试图用ZGETRI计算复矩阵的逆,但是 即使执行时没有错误(info=0), 它没有给我正确的逆矩阵,我有绝对的 不知道错误来自哪里

PROGRAM solvelinear
implicit none
INTEGER                        :: i,j,info,lwork
INTEGER,dimension(3)        :: ipiv
COMPLEX(16), dimension(3,3) :: C,Cinv,M,LU
COMPLEX(16),allocatable :: work(:)

info=0
lwork=100
allocate(work(lwork))
ipiv=0
work=(0.d0,0.d0)

C(1,1)=(0.d0,-1.d0)
C(1,2)=(1.d0,5.d0)
C(1,3)=(2.d0,-2.d0)
C(2,1)=(4.d0,-1.d0)
C(2,2)=(2.d0,-3.d0)
C(2,3)=(-1.d0,2.d0)
C(3,1)=(1.d0,0.d0)
C(3,2)=(3.d0,-2.d0)
C(3,3)=(0.d0,1.d0)

write(*,*)"C = "
do i=1,3
   write(*,10)(C(i,j),j=1,3)
end do

!-- LU factorisation
LU=C
CALL ZGETRF(3,3,LU,3,ipiv,info)
write(*,*)'info = ',info
write(*,*)"LU = "
do i=1,3
   write(*,10)(LU(i,j),j=1,3)
end do

!-- Inversion of matrix C using the LU

Cinv=LU
CALL ZGETRI(3,Cinv,3,ipiv,work,lwork,info)
write(*,*)'info = ',info
write(*,*)"Cinv = "
do i=1,3
   write(*,10)(Cinv(i,j),j=1,3)
end do

!-- computation of C^-1 * C to check the inverse
M = matmul(Cinv,C)
write(*,*)"M = "
do i=1,3
   write(*,10)(M(i,j),j=1,3)
end do
          10 FORMAT(3('(',F20.10,',',F20.10,') '))

END PROGRAM solvelinear
我用ifort编译(我的
LAPACK
libraries版本3.7.1也用ifort编译)。生成文件:

#$Id: Makefile $
.SUFFIXES: .f90 .f .c .o
FC = ifort
FFLAGS = -g -check all -zmuldefs -i8
LIBS = -L/path/to/lapack-3.7.1 -llapack -ltmglib -lrefblas
MAIN = prog.o
EXEC = xx
all:  ${MAIN} Makefile
    ${FC} ${FFLAGS} -o ${EXEC} ${MAIN} ${LIBS}
.f.o: ${MODS} Makefile
    ${FC} ${FFLAGS} -c $<
.f90.o: ${MODS} Makefile
    ${FC} ${FFLAGS} -c $<

如果我没弄错的话,M应该是身份。

我建议你不要使用像
REAL(4)
COMPLEX(16)
这样的文字数字表示法

首先,它很难看,不便于携带

第二,对于复杂的变量,它可能会令人困惑

在这里,您将变量定义为
COMPLEX(16)
,但
ZGETRI
,以及所有其他LAPACK
Z
例程需要
COMPLEX*16
。这些是不一样的

COMPLEX*16
是包含
REAL*8
组件的复数的非标准表示法
REAL*8
是8字节实数的非标准表示法,通常相当于
双精度

COMPLEX(16)
是一个包含两个
REAL(16)
组件的复数,前提是存在此类组件。在提供
REAL(16)
的编译器中,此REAL是四倍精度,而不是双精度

因此,您实际上是在传递32字节的复杂变量,而不是16字节的复杂变量

有足够的资源学习如何正确使用Fortran。你可以从

integer, parameter :: dp = kind(1.d0)


请不要像以前那样将标签放在括号中的标题中。StackOverflow有一个丰富的标签系统,将标签放在它们所属的问题下面。如果它们是标题不可分割的一部分,它们可以留在那里(如“in-Fortran”或“in-a-Fortran function”或类似),但不要只在那里列出标签列表,标签列表就在问题的下方。我想知道“最佳”方法是否是使用复数*16而不是复数(种类(1.0d0))来匹配原始源代码中使用的类型,但我不确定它在参考(或最新版本或mkl或…)库中是如何定义的。我在回答中提到了这一点,但我不推荐这种方式,因为它不是(标准)Fortran。@roygvib复杂*16的主要原因是因为没有标准的双复杂度,但DGETRF使用双精度,因此,我建议使用
kind(1.d0)
。感谢您提供的信息,是的,我同意kind(1.d0)实际上是最好的(我使用它)。我担心的是,如果默认实数设置为64位(通过编译器选项或其他方式),将来可能会出现问题。。。(从这个意义上讲,来自iso_fortran_env的complex(real64)可能更安全)。但在此之前,Lapack本身以混合方式使用1.0D0和复数*16(或实数*8),因此混乱。。。哈哈(但这只是一个非常小的问题,所以我也认为复杂(种类(0.d0))是最实用的。)@B_runo不完全是这样。编译器确实具有四倍精度,但四倍精度与
Z
例程(如
ZGETRF
)不兼容。它们需要双重精度。
integer, parameter :: dp = kind(1.d0)
real(dp) :: x
complex(dp) :: c