从另一个函数创建动态函数 [英] Dynamic function creation from another function
问题描述
我有一个以函数作为参数的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屋!