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
Function 南·乔尔斯基';如果我没有';不要使用打印子程序_Function_Fortran_Nan_Subroutine - Fatal编程技术网

Function 南·乔尔斯基';如果我没有';不要使用打印子程序

Function 南·乔尔斯基';如果我没有';不要使用打印子程序,function,fortran,nan,subroutine,Function,Fortran,Nan,Subroutine,我编写了一个函数来获得实矩阵的Cholesky分解。问题是它在矩阵的某些点返回NaN值。代码如下: MODULE funciones2 IMPLICIT NONE CONTAINS FUNCTION cholesky(a) USE ::comprob !Module to test whether or not a matrix is square and symmetric IMPLICIT NONE REAL, ALLOCATABLE :: cholesky(:,:),u(:,:) REA

我编写了一个函数来获得实矩阵的Cholesky分解。问题是它在矩阵的某些点返回NaN值。代码如下:

MODULE funciones2
IMPLICIT NONE
CONTAINS
FUNCTION cholesky(a)
USE ::comprob !Module to test whether or not a matrix is square and symmetric 
IMPLICIT NONE
REAL, ALLOCATABLE :: cholesky(:,:),u(:,:)
REAL :: a(:,:),s
INTEGER :: i,j,k,n
LOGICAL :: comp

comp=symmat(a)

IF (comp) THEN
n=size(a,1)
ALLOCATE (u(n,n))
u=0.0
u(1,1)=sqrt(a(1,1))

DO j=2,n,1
    u(1,j)=a(1,j)/u(1,1)
END DO

DO i=2,n,1
    DO k=1,i-1,1
        s=s+(u(k,i)**2)
    END DO
    u(i,i)=sqrt(a(i,i)-s)
    s=0
    DO j=i+1,n,1
        DO k=1,i-1,1
            s=s+u(k,i)*u(k,j)
        END DO
        u(i,j)=(1/u(i,i))*(a(i,j)-s)
        s=0
    END DO
END DO

cholesky=u

ELSE
    print*,"CHOLESKY: The matrix is not symmetric."
ENDIF
ENDFUNCTION
ENDMODULE
程序代码为:

PROGRAM pchol
USE :: funciones2
USE :: dispmodule
IMPLICIT NONE
REAL, ALLOCATABLE :: a(:,:),af(:,:)
CHARACTER(LEN=20) :: na

na='B.txt'

a=loadm(na)
CALL DISP('A =',a,ADVANCE='DOUBLE')

a=matmul(transpose(a),a)
!CALL DISP('ATA =',a,ADVANCE='DOUBLE') 

af=cholesky(a)
CALL DISP('Ach ',af,ADVANCE='DOUBLE')

af=transpose(af)
CALL DISP('AchT ',af,ADVANCE='DOUBLE')

ENDPROGRAM
“dispmodule”是一个用于漂亮打印矩阵的模块(Jonasson,2009)(您可以在这里查看:)。我发现如果我在这一部分中使用子程序DISP:

a=matmul(transpose(a),a)
CALL DISP('ATA =',a,ADVANCE='DOUBLE')
南的问题消失了!(请注意,在最后一部分中,“CALL DISP”之前没有“!”)

为什么会这样?我将对另一个函数使用Cholesky分解函数,我不能一直调用DISP来避免问题。我怎样才能解决这个问题

编辑: 以下是不使用DISP子程序编译程序的数值结果:

A =3.00000   2.00000  4.00000   5.00000
   2.00000  -3.00000  1.00000  -2.00000
   1.00000   1.00000  2.00000   0.00000

Ach 3.74166  0.26726  4.27618  2.93987
    0.00000      NaN      NaN      NaN
    0.00000  0.00000      NaN      NaN
    0.00000  0.00000  0.00000      NaN

AchT 3.74166  0.00000  0.00000  0.00000
     0.26726      NaN  0.00000  0.00000
     4.27618      NaN      NaN  0.00000
     2.93987      NaN      NaN      NaN
A =3.00000   2.00000  4.00000   5.00000
   2.00000  -3.00000  1.00000  -2.00000
   1.00000   1.00000  2.00000   0.00000

ATA =14.0000   1.0000  16.0000  11.0000
      1.0000  14.0000   7.0000  16.0000
     16.0000   7.0000  21.0000  18.0000
     11.0000  16.0000  18.0000  29.0000

Ach 3.74166  0.26726  4.27618   2.93987
    0.00000  3.73210  1.56940   4.07660
    0.00000  0.00000  0.50128  -1.93350
    0.00000  0.00000  0.00000   0.00648

AchT 3.74166  0.00000   0.00000  0.00000
     0.26726  3.73210   0.00000  0.00000
     4.27618  1.56940   0.50128  0.00000
     2.93987  4.07660  -1.93350  0.00648
以下是编译DISP子程序时的数值结果:

A =3.00000   2.00000  4.00000   5.00000
   2.00000  -3.00000  1.00000  -2.00000
   1.00000   1.00000  2.00000   0.00000

Ach 3.74166  0.26726  4.27618  2.93987
    0.00000      NaN      NaN      NaN
    0.00000  0.00000      NaN      NaN
    0.00000  0.00000  0.00000      NaN

AchT 3.74166  0.00000  0.00000  0.00000
     0.26726      NaN  0.00000  0.00000
     4.27618      NaN      NaN  0.00000
     2.93987      NaN      NaN      NaN
A =3.00000   2.00000  4.00000   5.00000
   2.00000  -3.00000  1.00000  -2.00000
   1.00000   1.00000  2.00000   0.00000

ATA =14.0000   1.0000  16.0000  11.0000
      1.0000  14.0000   7.0000  16.0000
     16.0000   7.0000  21.0000  18.0000
     11.0000  16.0000  18.0000  29.0000

Ach 3.74166  0.26726  4.27618   2.93987
    0.00000  3.73210  1.56940   4.07660
    0.00000  0.00000  0.50128  -1.93350
    0.00000  0.00000  0.00000   0.00648

AchT 3.74166  0.00000   0.00000  0.00000
     0.26726  3.73210   0.00000  0.00000
     4.27618  1.56940   0.50128  0.00000
     2.93987  4.07660  -1.93350  0.00648
编辑2:我为每个新的计算矩阵分配了新的变量,但问题仍然存在

PROGRAM pchol
USE :: funciones2
USE :: dispmodule
IMPLICIT NONE
REAL, ALLOCATABLE :: a(:,:),af(:,:),at(:,:),am(:,:),am1(:,:)
CHARACTER(LEN=20) :: na
INTEGER :: m,n

na='B.txt'

a=loadm(na)
!CALL DISP('A =',a,ADVANCE='DOUBLE')

m=size(a,1)
n=size(a,2)

ALLOCATE (at(n,m))
ALLOCATE (am(n,n))
ALLOCATE (af(n,n))

at=transpose(a)
am=matmul(at,a)
am1=am
!CALL DISP('ATA =',am1,ADVANCE='DOUBLE')

af=cholesky(am)
CALL DISP('Ach ',af,ADVANCE='DOUBLE')

af=transpose(af)
CALL DISP('AchT ',af,ADVANCE='DOUBLE')

ENDPROGRAM
更新:最小可编译示例。我取出了子程序DISP()及其相应的模块。我还取出了对矩阵对称性进行压缩的模和函数。此外,我取出了我编写的用于从文件中读取矩阵的函数(我直接在程序中编写了相同的矩阵)和用于打印矩阵的函数。问题变得更糟了,现在没有数字,甚至第一行也不像以前那样,在使用cholesky()之后,所有矩阵都变为NaN。gfortran版本是5.3.0

PROGRAM pcholstack
IMPLICIT NONE
REAL, ALLOCATABLE :: af(:,:),at(:,:),am(:,:),am1(:,:)
REAL :: a(3,4)
INTEGER :: m,n,i,j

a(1,1)=3
a(2,1)=2
a(3,1)=1
a(1,2)=2
a(2,2)=-3
a(3,2)=1
a(1,3)=4
a(2,3)=1
a(3,3)=2
a(1,4)=5
a(2,4)=-2
a(3,4)=1

m=size(a,1)
n=size(a,2)

do i=1,m,1
    write(*,1017),(a(i,j),j=1,n)
    end do
        1017 format (10f15.2)

write(*,*)

ALLOCATE (at(n,m))
ALLOCATE (am(n,n))
ALLOCATE (af(n,n))

at=transpose(a)
am=matmul(at,a)
am1=am
write(*,*) am1(1,1)
write(*,*)

do i=1,n,1
    write(*,1018),(at(i,j),j=1,m)
    end do
        1018 format (10f15.2)

write(*,*)

do i=1,n,1
    write(*,1019),(am(i,j),j=1,n)
    end do
        1019 format (10f15.2)

write(*,*)

af=cholesky(am)

!af=transpose(af)

do i=1,n,1
    write(*,1016),(af(i,j),j=1,n)
    end do
        1016 format (10f15.2) 

CONTAINS

FUNCTION cholesky(a)
IMPLICIT NONE
REAL, ALLOCATABLE :: u(:,:),cholesky(:,:)
REAL :: a(:,:),s
INTEGER :: i,j,k,n

n=size(a,1)
ALLOCATE (u(n,n))
u=0.0
u(1,1)=sqrt(a(1,1))

DO j=2,n,1
    u(1,j)=a(1,j)/u(1,1)
END DO

DO i=2,n,1
    DO k=1,i-1,1
        s=s+(u(k,i)**2)
    END DO
    u(i,i)=sqrt(a(i,i)-s)
    s=0
    DO j=i+1,n,1
        DO k=1,i-1,1
            s=s+u(k,i)*u(k,j)
        END DO
        u(i,j)=(1/u(i,i))*(a(i,j)-s)
        s=0
    END DO
END DO

cholesky=u

ENDFUNCTION

ENDPROGRAM

我相信你的问题在于这两方面:

a=loadm(na)

a=matmul(transpose(a),a)
我没有
loadm
的代码,但您的
a
矩阵是4x3。然后调用
matmul
并将一个4x4放入其中(从而使用非为其保留的内存,其他东西可以写入该内存)。
cholesky
功能将其视为4x3,而不是4x4


更新:

它实际上在
gfortran
中工作,自动分配变量。但是它在pgfortran中失败了

问题是:
cholesky
的返回值没有正确定义。最简单的方法就是返回
u

FUNCTION cholesky(a) result (u)

取出
cholesky
数组的定义,不要在函数结尾处为其赋值。

英特尔Fortran发现您在cholesky中使用的
s
不正确。首次使用时未定义
s
的值

因此,结果可以是任何东西

可能您想将其设置为0

> ifort cholesky.f90 -g -check -traceback -standard-semantics
> ./a.out 
           3.00           2.00           4.00           5.00
           2.00          -3.00           1.00          -2.00
           1.00           1.00           2.00           1.00

 14.00000

           3.00           2.00           1.00
           2.00          -3.00           1.00
           4.00           1.00           2.00
           5.00          -2.00           1.00

          14.00           1.00          16.00          12.00
           1.00          14.00           7.00          17.00
          16.00           7.00          21.00          20.00
          12.00          17.00          20.00          30.00

forrtl: severe (194): Run-Time Check Failure. The variable 'cholesky$S$_1' is being used in 'cholesky.f90(82,9)' without being defined
Image              PC                Routine            Line        Source             
a.out              0000000000407DB7  pcholstack_IP_cho          82  cholesky.f90
a.out              0000000000405B47  MAIN__                     54  cholesky.f90
a.out              000000000040261E  Unknown               Unknown  Unknown
libc.so.6          00007F41B73496E5  Unknown               Unknown  Unknown
a.out              0000000000402529  Unknown               Unknown  Unknown
报告的代码为:

s = 0  !you probably wanted

DO i=2,n,1
    DO k=1,i-1,1
        s=s+(u(k,i)**2)   !<<<=====
s=0!你可能想要
i=2,n,1吗
DO k=1,i-1,1

s=s+(u(k,i)**2)!哪些地方?请阅读,我们需要一个确切的案例,看看完整的输入数据和完整的输出。我们需要能够复制您的计算。请注意,您依赖于Fortran 2003自动分配分配分配数组。默认情况下,某些编译器(尤其是较旧版本的英特尔Fortran)不会启用此功能。如何编译源代码?您还没有显示全部代码,所以我不能100%确定,但从我所看到的情况来看,这段代码是非法的-cholesky有一个假定的形状伪参数,但在调用点的作用域中没有接口。请显示完整的代码,以便进行检查。也请使用隐式无。同样,因为您没有显示整个程序,我无法确定,但程序中似乎没有cholesky声明,@VladimirF,我已经添加了输出计算。我使用gfortran作为编译器。您应该使用
-fcheck=all-Wall-g-fbacktrace
进行编译,然后再次运行。每当你怀疑有错误时,就应该这样做。我认为这也可能是问题所在,所以我在第二次编辑中修复了它,为每个新的计算矩阵分配了新的变量,但问题仍然存在。现在,
at
am
没有分配。我现在分配了它们,它仍然无法找到,并且修复了另一个问题。我想主要有两种可能会造成麻烦。。一个是您的代码中仍然存在一些bug(从问题中的代码中看不到),另一个是您的gfortran版本存在一些编译器bug,例如,对于具有可分配返回数组的函数。(您可以通过
gfortran-v
检查版本)无论如何,我相信如果您准备一个最小的可编译示例(不使用“dispmodule”),以便我们可以尝试代码,这将非常有用。此外,如上所述,附加选项,如
-fcheck=all-Wall-g-fbacktrace
,可能会给出一些提示。