虚拟过程中的接口不匹配

时间:2014-10-25 12:53:00

标签: fortran

我正在尝试使用牛顿法求解非线性方程 这是主程序

 program  main  
    use nrtype; use nr ! The type and module is copyed by the numeric recipes
    implicit none
    integer(i4b) :: ntrial =20
    real(sp) :: x(2)= [0.9,0.8]
    real(sp) :: tolx = 1.0e-4_sp
    real(sp) :: tolf = 1.0e-6_sp
    call mnewt(ntrial,x,tolx,tolf,usrfun)
    write (*,*) x
contains
    SUBROUTINE usrfun(x,fvec,fjac)
        USE nrtype
        IMPLICIT NONE
        REAL(SP),intent(in) :: x(2)
        REAL(SP),intent(out) :: fvec(2)
        REAL(SP),intent(out) :: fjac(2,2)
        fvec(1) = x(1)**2 + 2*x(2)
        fvec(2) = x(2)**2 - 3*x(1)
        fjac(1,1) = 2*x(1)
        fjac(1,2) = 2
        fjac(2,1) = 2*x(2)
        fjac(2,2) = 3
    END SUBROUTINE usrfun
end program  main

这是主程序调用的子程序

SUBROUTINE mnewt(ntrial,x,tolx,tolf,usrfun)
  USE nrtype
  USE nr, ONLY : lubksb,ludcmp
  IMPLICIT NONE
  INTEGER(I4B), INTENT(IN) :: ntrial
  REAL(SP), INTENT(IN) :: tolx,tolf
  REAL(SP), DIMENSION(:), INTENT(INOUT) :: x
  INTERFACE
    SUBROUTINE usrfun(x,fvec,fjac)
      USE nrtype
      IMPLICIT NONE
      REAL(SP), DIMENSION(:), INTENT(IN) :: x
      REAL(SP), DIMENSION(:), INTENT(OUT) :: fvec
      REAL(SP), DIMENSION(:,:), INTENT(OUT) :: fjac
  END SUBROUTINE usrfun
END INTERFACE
....  ! the detail to solve the nolinear equations

END SUBROUTINE mnewt

然后编译fortran文件,它运行

gfortran  -c nrtype.f90
gfortran  -c nrutil.f90
gfortran  -c nr.f90
gfortran  -c ludcmp.f90
gfortran  -c lubksb.f90
gfortran  -c mnewt.f90
gfortran  -c main.f90
main.f90:9.31:
call mnewt(ntrial,x,tolx,tolf,usrfun)
                               1
Interface mismatch in dummy procedure 'usrfun' at (1): Shape mismatch in argument 'x'

它类似于链接。为什么会这样? Interface mismatch - higher order functions

1 个答案:

答案 0 :(得分:1)

您在主程序中使用usrfun中的显式大小数组(即dimension(2)),但在界面中假设形状数组(即dimension(:))。你必须选择一个。

在这种情况下,最简单的可能是将主程序中的子程序改为

    REAL(SP),intent(in) :: x(:)
    REAL(SP),intent(out) :: fvec(:)
    REAL(SP),intent(out) :: fjac(:,:)

请注意,仅在Fortran 2008中允许将内部过程作为实际参数传递,并且仅由某些编译器支持。