接口不匹配 - 高阶函数 [英] Interface mismatch - higher order functions

查看:197
本文介绍了接口不匹配 - 高阶函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在Fortran中复制更高阶的函数。

 模块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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆