接口不匹配 - 高阶函数 [英] Interface mismatch - higher order functions
问题描述
模块rk4
包含
纯函数f(t,x)结果(fx)
实数,维(1),意图(in):: x
实数,意图(in):: t
实数,维(1):: fx
fx = x
结束函数f
函数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))
分配(k2(N))
分配(k3(N))
分配(k4(N))
k1 = f(t,x)
(t + 0.5 * dt,x + 0.5 * k2 * dt)
k4 = f(t + dt,x + dt * k3)
分配(xn(N))
xn = x +(dt / 6。)*(k1 + 2 * k2 + 2 * K3 + K4)
DEALLOCATE(K1)
DEALLOCATE(K2)
DEALLOCATE(K3)
DEALLOCATE(K4)
结束功能步骤
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 =步骤(X0,F,0.01)
1个
错误:虚拟过程'f'中的接口不匹配(1):函数结果中的类型/等级不匹配
什么可能导致此?
在错误消息抱怨功能˚F
与伪参数 f
不兼容。
您声明为
real,external :: f
这意味着它应该返回一个标量,而实际上函数 f
返回一个数组。
相同的名字并不真正帮助理解这里。我在下面的代码中将伪参数的名称更改为 g
。
解决这个问题的最简单的方法是
pre $纯函数f( t),x)result(fx)
real,dimension(1),intent(in):: x
real,intent(in):: t
real,dimension(1): :fx
fx = x
结束函数f
函数step(x,g,dt)result(xn)
real,intent(in ):: dt
real,intent(in),dimension(:) :: x
real,dimension(:),allocatable :: xn
过程(f):: g
!在这里叫g,而不是f!
过程语句来自Fortran 2003,并导致伪参数过程 g
与程序 f
。
具有相同的接口。否则,您可以使用接口块:
函数step(x,g,dt)result(xn)
real,intent(in): :dt
real,intent(in),dimension(:) :: x
real,dimension(:),allocatable :: xn
接口
纯函数g(t,x)result(fx)
real,dimension(1),intent(in):: x
real,intent(in):: t
real,dimension(1 ):: fx
结束函数g
结束接口
外部语句应该只能在一些特殊情况下用于现代代码。
I'm trying to 'reproduce' higher order functions in 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
When the module is called in the following way
real, dimension(1) :: x0 = 2
x0 = step(x0,f,0.01)
I get the following error
$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
What might be causing this?
The error message is complaining about the function f
being incompatible with the dummy argument f
.
You declare it as
real, external :: f
which means it should return a scalar whereas in reality the function f
returns an array.
The same names do not really help the understanding here. I changed the name of the dummy argument in the following code to g
.
The easiest way to solve this is
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!!!
The procedure statement comes from Fortran 2003 and causes the dummy argument procedure g
to have the same interface as the procedure f
.
Otherwise you can use an interface block:
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
The external statement should be used in modern code only in some exceptional cases.
这篇关于接口不匹配 - 高阶函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!