Matrix Fortran-如果十进制较长,则逆矩阵结果不相同

Matrix Fortran-如果十进制较长,则逆矩阵结果不相同,matrix,fortran,fortran90,matrix-inverse,fortran95,Matrix,Fortran,Fortran90,Matrix Inverse,Fortran95,我的真实数据是第一次输入,但结果的倒数太大了。当您与第一个和第二个输入进行比较时,它们是相同的数据。只有十进制大小不同。为什么会有不同的结果?因为它们是相同的数据。他们怎么会有不同的结果呢?您可以看到结果和输入。真奇怪 program test Implicit none double precision,allocatable,dimension(:,:) :: A double precision,allocatable,dimension(:)

我的真实数据是第一次输入,但结果的倒数太大了。当您与第一个和第二个输入进行比较时,它们是相同的数据。只有十进制大小不同。为什么会有不同的结果?因为它们是相同的数据。他们怎么会有不同的结果呢?您可以看到结果和输入。真奇怪

program test

Implicit none

double precision,allocatable,dimension(:,:)         :: A       
double precision,allocatable,dimension(:)           :: WORK
integer ,allocatable,dimension(:)       :: ipiv
integer                                 :: n,info,M
 external     DGETRF,DGETRI
M=8
allocate(A(M,M),WORK(M),IPIV(M))
!!! First Input !!!!
A(1,:)=(/3.740486048842566D-4, 0.0D0, 0.0D0, 4.987315029057229D-5, 0.0D0, 0.0D0, 0.0D0, 0.0D0/)
A(2,:)=(/0.0D0 , 3.740486048842566D-4, 0.0D0, 0.0D0, 4.987315029057229D-5 ,0.0D0 ,0.0D0 ,0.0D0 /)
A(3,:)=(/0.0D0 , 0.0D0 ,3.740486048842566D-4, 0.0D0 ,0.0D0, 4.987315029057229D-5, 0.0D0 ,0.0D0/)
A(4,:)=(/4.987315029057229D-5 ,0.0D0 ,0.0D0 ,6.649753768432517D-6, 0.0D0 ,0.0D0, 0.0D0, 0.0D0 /)
A(5,:)=(/0.0D0 , 4.987315029057229D-5, 0.0D0, 0.0D0 ,6.649753768432517D-6 ,0.0D0 ,0.0D0 ,0.0D0 /)
A(6,:)=(/0.0D0, 0.0D0, 4.987315029057229D-5, 0.0D0 ,0.0D0, 6.649753768432517D-6, 0.0D0 ,0.0D0 /)
A(7,:)=(/0.0D0, 0.0D0 ,0.0D0, 0.0D0 ,0.0D0 ,0.0D0 ,1.499999910593033D-11, 0.0D0 /)
A(8,:)=(/0.0D0 ,0.0D0 ,0.0D0 ,0.0D0 ,0.0D0 ,0.0D0, 0.0D0 ,1.499999910593033D-11 /)
 !!!! Second Input !!!! 
!A(1,:)=(/3.74D-4, 0.0D0, 0.0D0, 4.98D-5, 0.0D0, 0.0D0, 0.0D0, 0.0D0/)
!A(2,:)=(/0.0D0 , 3.74D-4, 0.0D0, 0.0D0, 4.98D-5 ,0.0D0 ,0.0D0 ,0.0D0 /)
!A(3,:)=(/0.0D0 , 0.0D0 ,3.74D-4, 0.0D0 ,0.0D0, 4.98D-5, 0.0D0 ,0.0D0/)
!A(4,:)=(/4.98D-5 ,0.0D0 ,0.0D0 ,6.64D-6, 0.0D0 ,0.0D0, 0.0D0, 0.0D0 /)
!A(5,:)=(/0.0D0 , 4.98D-5, 0.0D0, 0.0D0 ,6.64D-6 ,0.0D0 ,0.0D0 ,0.0D0 /)
!A(6,:)=(/0.0D0, 0.0D0, 4.98D-5, 0.0D0 ,0.0D0, 6.64D-6, 0.0D0 ,0.0D0 /)
!A(7,:)=(/0.0D0, 0.0D0 ,0.0D0, 0.0D0 ,0.0D0 ,0.0D0 ,1.49D-11, 0.0D0 /)
!A(8,:)=(/0.0D0 ,0.0D0 ,0.0D0 ,0.0D0 ,0.0D0 ,0.0D0, 0.0D0 ,1.49D-11 /)


call DGETRF(M,M,A,M,IPIV,info)
if(info .eq. 0) then
Print *,'succeded'
else
Print *,'failed'
end if

call DGETRI(M,A,M,IPIV,WORK,M,info)
if(info .eq. 0) then
 Print *,'succeded'
else
Print *,'failed'
end if
Print *,A

deallocate(A,IPIV,WORK)

end 
!!!!! Second Input Result
!1.0e+10 *
! 0.0002     0       0   -0.0015       0      0        0   0
!     0      0.0002  0       0       -0.0015  0        0   0
!     0      0    0.0002     0         0     -0.0015   0   0
! -0.0015    0       0     0.0113      0      0        0   0
!     0     -0.0015  0       0       0.0113   0        0   0
!     0      0   -0.0015     0         0    0.0113     0   0
!     0      0       0       0         0      0     6.7114 0
!     0      0       0       0         0      0        0   6.7114

!!! First Input Result
!   1.0e+21 *

!-0.0238         0         0    0.1783         0         0         0         0
!     0   -0.0238         0         0    0.1783         0         0         0
!     0         0    0.0000         0         0   -0.0000         0         0
! 0.1783         0         0   -1.3375         0         0         0         0
!     0    0.1783         0         0   -1.3375         0         0         0
!     0         0   -0.0000         0         0    0.0000         0         0
!     0         0         0         0         0         0    0.0000         0
!     0         0         0         0         0         0         0    0.0000

创建矩阵逆不是一个困难的问题。 我将您前面的示例转换为使用一种简单的方法,该方法基于带阴影的单位矩阵的高斯消去,适用于大多数情况。附加的程序将反转先前的对称矩阵,而无需借助行的旋转。它不需要“黑匣子”

用不同的系数得到不同的结果并不奇怪。由于输入值的微小变化导致结果发生显著变化,这表明您使用的方程关系的敏感性和条件可能较差

关于“首次输入”的附加响应

此最新链接(16-6)包含两个数据集。在“第一次输入”中,您的方程式基本上是第4:6行,第1:3/7.5行+小噪声

这个最新的代码示例在矩阵求逆期间和之后都进行了精度检查。测试期间检查行更改是否正确,而测试后检查为“A.A^-1-I”和“A-(A^-1)^-1”,这更好地表明准确性较差

有趣的是,“第二次输入”(噪音较大)报告的结果相当准确。如果不能用8字节的实数求逆,需要一个相当做作的矩阵!同样,随机数导出的系数示例显示了良好的精度

这些例子表明,我所介绍的精度测试并不总是确定定义不清的方程关系。您对反向的检查也很有用,可以识别值中的较大变化


考虑到方程式的定义方式,我不确定您想要的结果是什么。

创建矩阵逆不是一个困难的问题。 我将您前面的示例转换为使用一种简单的方法,该方法基于带阴影的单位矩阵的高斯消去,适用于大多数情况。附加的程序将反转先前的对称矩阵,而无需借助行的旋转。它不需要“黑匣子”

用不同的系数得到不同的结果并不奇怪。由于输入值的微小变化导致结果发生显著变化,这表明您使用的方程关系的敏感性和条件可能较差

关于“首次输入”的附加响应

此最新链接(16-6)包含两个数据集。在“第一次输入”中,您的方程式基本上是第4:6行,第1:3/7.5行+小噪声

这个最新的代码示例在矩阵求逆期间和之后都进行了精度检查。测试期间检查行更改是否正确,而测试后检查为“A.A^-1-I”和“A-(A^-1)^-1”,这更好地表明准确性较差

有趣的是,“第二次输入”(噪音较大)报告的结果相当准确。如果不能用8字节的实数求逆,需要一个相当做作的矩阵!同样,随机数导出的系数示例显示了良好的精度

这些例子表明,我所介绍的精度测试并不总是确定定义不清的方程关系。您对反向的检查也很有用,可以识别值中的较大变化



考虑到方程式的定义方式,我不确定您想要的结果是什么。

您必须告诉我们“错误”是什么意思。你的结果是什么?正确的结果是什么?尝试一个简单的矩阵,你知道它的精确解,或者只是将你的结果与Matlab的结果进行比较。但是给我们看看比较。@VladimirF谢谢我改变了它。问题是十进制大小。怎样才能改变结果?但应该是正确的结果吗?为什么你认为目前的结果是错误的?它们是相同的数字和大小几乎是相同的,它们怎么会不同呢?而且,差异是10^10。它们几乎不一样,差异很大!你必须告诉我们“错”是什么意思。你的结果是什么?正确的结果是什么?尝试一个简单的矩阵,你知道它的精确解,或者只是将你的结果与Matlab的结果进行比较。但是给我们看看比较。@VladimirF谢谢我改变了它。问题是十进制大小。怎样才能改变结果?但应该是正确的结果吗?为什么你认为目前的结果是错误的?它们是相同的数字和大小几乎是相同的,它们怎么会不同呢?而且,差异是10^10。它们几乎不一样,差异很大!谢谢你的代码。这也是逆矩阵的一个很好的例子。不需要使用黑匣子:)但我认为问题在于
病态。因为,在我尝试得到cholesky分解后,矩阵是奇异的!Cholesky分解需要一个正定矩阵,因此可能会受到限制。您已经给出了多个示例矩阵,尽管我考虑的不是单数矩阵。我已经包括了部分旋转,这对一般矩阵很有用,尽管我所拥有的大多数实用矩阵都是对称的和非奇异的。在Fortran 90之前,创建临时数组是一个问题,但从那时起,大多数矩阵求逆都不是问题。倒排矩阵可以很方便,尤其是在最小二乘法计算中。确切地说,cholesky要求的位置是确定的,但矩阵不是PD,所以我将检查@kvantour注释。@A-(A^-1)^-1=1.9840899756484731E-017中没有人得到
最大错误,使用gFortran 7.2.0 64位和
A-(A^-1)中的最大错误^-1=2.260561529632E-17
使用Silverfrost FTN95 32 bitI现在已经查看了您的“第一个示例”:row_1=7.5*