我正试图在fortran中“重现”高阶函数。
module rk4
contains
pure function f(t,x) result (fx)
real, dimension(1), intent(in) :: x
real, intent(in) :: t
real, dimension(1) :: fx
fx = x
end function f
function step(x,f,dt) result(xn)
real, intent(in) :: dt
real, intent(in), dimension(:) :: x
real, dimension(:), allocatable :: k1,k2,k3,k4,xn
real, external :: f
integer :: N
N = size(x)
allocate(k1(N))
allocate(k2(N))
allocate(k3(N))
allocate(k4(N))
k1 = f(t,x)
k2 = f(t+0.5*dt,x+0.5*k1*dt)
k3 = f(t+0.5*dt,x+0.5*k2*dt)
k4 = f(t+dt,x+dt*k3)
allocate(xn(N))
xn = x + (dt/6.)*(k1 + 2*k2 + 2*k3 + k4)
deallocate(k1)
deallocate(k2)
deallocate(k3)
deallocate(k4)
end function step
end module rk4
以下列方式调用模块时
real, dimension(1) :: x0 = 2
x0 = step(x0,f,0.01)
我收到以下错误
$gfortran -c test_rk4.f95
test_rk4.f95:7.15:
x0 = step(x0,f,0.01)
1
Error: Interface mismatch in dummy procedure 'f' at (1): Type/rank mismatch in function result
可能导致这种情况的原因是什么?
答案 0 :(得分:3)
错误消息抱怨函数f
与伪参数f
不兼容。
您将其声明为
real, external :: f
表示它应该返回一个标量,而实际上函数f
返回一个数组。
同样的名字并不能帮助理解这里。我将以下代码中伪参数的名称更改为g
。
解决此问题的最简单方法是
pure function f(t,x) result (fx)
real, dimension(1), intent(in) :: x
real, intent(in) :: t
real, dimension(1) :: fx
fx = x
end function f
function step(x,g,dt) result(xn)
real, intent(in) :: dt
real, intent(in), dimension(:) :: x
real, dimension(:), allocatable :: xn
procedure(f) :: g
!here call g, not f!!!
过程语句来自Fortran 2003,并使伪参数过程g
具有与过程f
相同的接口。
否则您可以使用接口块:
function step(x,g,dt) result(xn)
real, intent(in) :: dt
real, intent(in), dimension(:) :: x
real, dimension(:), allocatable :: xn
interface
pure function g(t,x) result (fx)
real, dimension(1), intent(in) :: x
real, intent(in) :: t
real, dimension(1) :: fx
end function g
end interface
只有在某些特殊情况下,才应在现代代码中使用外部语句。