从另一个函数创建动态函数 [英] Dynamic function creation from another function

查看:181
本文介绍了从另一个函数创建动态函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个以函数作为参数的Fortran 90子例程,我想将该函数的修改版本传递给另一个子例程。我希望程序看起来像这样:

 子程序foo(f,...)
real :: pt(2),dir(2)

接口
函数f(x)结果(y)
实数,意图(in):: x(2)
real :: y
结束函数f
结束接口

pt = ...
dir = ...
!!以某种方式创建g(x)= f(pt + x * dir)
调用栏(g)

结束子程序foo

子程序栏(g)$ b (b)




$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

!用g
做结束子程序吧

我做了一些类似的事情, g'只需要使用正常变量,而不是函数。在这种情况下,我使用全局变量将其作为全局函数,并将其分配给'foo'中的全局变量。但是,我找不到一种方法将'f'全局化,或将其分配给全局函数。

任何人有任何想法如何做到这一点?解决方案可以像你想要的那样简单。 解决方案

这并不容易。在某些语言中,您可以在所谓的闭包中传递指向嵌套函数的指针。这在Fortran(或C语言和类似语言)中是不可能的,因为数据被更高级函数的堆栈所破坏。我建议你尝试函数对象,即 class 函数指针(或更多)以及所需的数据功能。通过这种方式,你甚至可以做功能组合和类似功能的东西。



更多关于概念 http://en.wikipedia.org/wiki/Function_object



下面是一个函数对象的示例

 模块ComposeObj 
使用参数
使用AritmFunctions
隐含无

private
public Compose

type撰写
private
过程(fce),指针,nopass :: f1 => null(),f2 => null()
包含
过程,public :: call =>助手
endtype构成

接口构成
过程NewCompose
结束接口

包含

函数NewCompose(f ,g)
程序(fce):: f,g
类型(Compose):: NewCompose

NewCompose%f1 => f
NewCompose%f2 => g
结束函数newCompose

纯真实(KND)函数帮助器(this,x)
类(Compose),intent(in):: this
real KND),intent(in):: x
helper = this%f1(this%f2(x))
结束函数助手

结束模块ComposeObj


I have a Fortran 90 subroutine which takes a function as an argument, and I would like to pass a modified version of that function into another subroutine. I want the program to look something like this:

subroutine foo(f, ...)
    real                 :: pt(2), dir(2)

    interface
    function f(x) result(y)
        real, intent(in) :: x(2)
        real             :: y
    end function f
    end interface

    pt = ...
    dir = ...
!! Somehow create g(x) = f(pt + x*dir)
    call bar(g)

end subroutine foo

subroutine bar(g)
    interface
    function g(x) result(y)
        real, intent(in) :: x
        real             :: y
    end function g
    end interface

!! Do stuff with g
end subroutine bar

I've managed to do something similar when 'g' only needs to use normal variables, not a function. In that case I made it a global function, using global variables, and assigned to those global variables in 'foo'. However, I can't find a way to turn 'f' global, or assign it to a global function.

Anybody have any ideas how to do this? The solution can be as hacky as you want.

解决方案

This is not so easy. In some languages you can pass pointers to nested functions in a so called closure. This is not possible in Fortran (or C and similar languages), because the data are destroyed with the stack of the higher function. I would suggest you to try function objects, i.e. a class with a function pointer (or more) and data needed for the function. In this way you can even do function composition and similar functional stuff.

More on the concept http://en.wikipedia.org/wiki/Function_object

Below is a sample for a function object for composition of two single argument functions:

module ComposeObj
  use Parameters
  use AritmFunctions
  implicit none

  private
  public Compose

  type Compose
    private
    procedure(fce),pointer,nopass :: f1 => null(),f2=>null()
  contains
    procedure,public :: call => helper
  endtype Compose

  interface Compose
    procedure NewCompose
  end interface

 contains

  function NewCompose(f,g)
    procedure(fce) :: f,g
    type(Compose) :: NewCompose

    NewCompose%f1 => f
    NewCompose%f2 => g
  end function NewCompose

  pure real(KND) function helper(this,x)
    class(Compose),intent(in) :: this
    real(KND),intent(in) :: x
    helper = this%f1(this%f2(x))
  end function helper

end module ComposeObj

这篇关于从另一个函数创建动态函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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