Fortran 拉帕克DGETRF&x2B;DGETRI失败
我试图通过LAPACK的DGETRF和DGETRI例程对矩阵进行求逆,但代码如下:Fortran 拉帕克DGETRF&x2B;DGETRI失败,fortran,gfortran,lapack,Fortran,Gfortran,Lapack,我试图通过LAPACK的DGETRF和DGETRI例程对矩阵进行求逆,但代码如下: program Tester !use LapackMatrixOps use MathematicalResources implicit none real :: B(2, 2), A(2, 2), WORK(2) integer :: i, j, SIZ, IPIV(2), INFO SIZ=2 do i=1, SIZ do
program Tester
!use LapackMatrixOps
use MathematicalResources
implicit none
real :: B(2, 2), A(2, 2), WORK(2)
integer :: i, j, SIZ, IPIV(2), INFO
SIZ=2
do i=1, SIZ
do j=1, SIZ
!if(i==j) then
! A(i, j)=1
!else
! A(i, j)=0
!end if
A(i, j)=rand(0)/2+0.5
B(i, j)=0
end do
end do
B=A
call PrintMatrix(A)
call dgetrf(size(B, 1), size(B, 2), B, size(B, 1), IPIV, INFO)
print *, "========="
call PrintMatrix(B)
print *, IPIV
call dgetri(size(B, 1), B, size(B, 1), IPIV, WORK, size(WORK), INFO);
print *, "========="
call PrintMatrix(B)
end program Tester
Program Tester
implicit none
real :: B(2, 2), A(2, 2), WORK(2)
integer :: i, j, SIZ, IPIV(2), INFO
SIZ=2
do i=1, SIZ
do j=1, SIZ
A(i, j)=rand(0)/2+0.5
B(i, j)=0
end do
end do
B=A
print *, A
call sgetrf(size(B, 1), size(B, 2), B, size(B, 1), IPIV, INFO)
print *, "========="
print *, B
print *, IPIV
call sgetri(size(B, 1), B, size(B, 1), IPIV, WORK, size(WORK), INFO);
print *, "========="
print *, B
end program Tester
汇编时使用:
CC=gfortran
CFLAGS=-O2 -W -g
LFLAGS=-L/usr/lib/lapack -llapack -lblas
TARGET=Tester
all: install clean
.PHONY: install
install:
$(CC) *.f90 $(CFLAGS) $(LFLAGS) -o $(TARGET)
.PHONY: test
test:
$(CC) *.f90 $(CFLAGS) $(LFLAGS) -o $(TARGET)
#==============TEST=============#
./$(TARGET)
.PHONY: clean
clean:
rm -rf ./*.o
似乎失败了。当我运行make test时,我得到:
gfortran *.f90 -O2 -W -g -L/usr/lib/lapack -llapack -lblas -o Tester
#==============TEST=============#
./Tester
0.500003815 0.565768838
0.877802610 0.729325056
=========
0.500003815 1.89445039E+28
0.877802610 1.57469535
1 2
=========
NaN 6.86847806E-20
NaN -1.28451300
pedro@pedro-300E5M-300E5L:~/Área de Trabalho/AED/openpypm2$
我做错了什么?
我尝试了自定义编译的LAPACK库和ATLAS库二进制文件,它们得到了相同的结果。我还尝试更改某些参数,例如工作数组的长度,我所做的一切都导致了这一点。您定义了单精度数组,但称为双精度例程。改为调用
sgetrf
和sgetri
。或者,如果需要双精度,请使用以下命令声明变量:
integer, parameter :: dp = kind(1.d0)
real(kind=dp) :: B(2,2), A(2,2), work(2)
无论如何,使用单精度,以下代码:
program Tester
!use LapackMatrixOps
use MathematicalResources
implicit none
real :: B(2, 2), A(2, 2), WORK(2)
integer :: i, j, SIZ, IPIV(2), INFO
SIZ=2
do i=1, SIZ
do j=1, SIZ
!if(i==j) then
! A(i, j)=1
!else
! A(i, j)=0
!end if
A(i, j)=rand(0)/2+0.5
B(i, j)=0
end do
end do
B=A
call PrintMatrix(A)
call dgetrf(size(B, 1), size(B, 2), B, size(B, 1), IPIV, INFO)
print *, "========="
call PrintMatrix(B)
print *, IPIV
call dgetri(size(B, 1), B, size(B, 1), IPIV, WORK, size(WORK), INFO);
print *, "========="
call PrintMatrix(B)
end program Tester
Program Tester
implicit none
real :: B(2, 2), A(2, 2), WORK(2)
integer :: i, j, SIZ, IPIV(2), INFO
SIZ=2
do i=1, SIZ
do j=1, SIZ
A(i, j)=rand(0)/2+0.5
B(i, j)=0
end do
end do
B=A
print *, A
call sgetrf(size(B, 1), size(B, 2), B, size(B, 1), IPIV, INFO)
print *, "========="
print *, B
print *, IPIV
call sgetri(size(B, 1), B, size(B, 1), IPIV, WORK, size(WORK), INFO);
print *, "========="
print *, B
end program Tester
使用以下生成文件编译:
FC =gfortran
MKL_LIB = -L${MKLROOT}/lib/intel64 -Wl,--no-as-needed -lmkl_gf_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl -m64 -I${MKLROOT}/include
all: test.f90
$(FC) -o test.exe $^ $(MKL_LIB) -I$(MKLROOT)/include
产生此输出:
0.500003815 0.877802610 0.565768838 0.729325056
=========
0.877802610 0.569608510 0.729325056 0.150339082
2 2
=========
-5.52652836 6.65163040 4.28716612 -3.78882527
注:如评论中所述,出于方便起见,我使用了MKL的LAPACK实现。无论实现如何,例程和变量的精度都应该匹配。不需要时会发生什么情况可能取决于实现,但在所有情况下都很可能是垃圾。您建议使用作为英特尔套件一部分的MKL库,如果这些库不可访问,该怎么办?@R.N:他使用MKL可能是因为他的环境中有MKL。然而,同样的问题wrt单精度与双精度适用于正在使用的LAPACK实现。@janneb:这是正确的,我使用MKL的LAPACK是出于方便。我不认为实现对标准例程(如
?getri
和?getrf
)很重要。很高兴能确认这一点。