2012-03-13 18 views
3

私は引数として関数をとるFortran 90サブルーチンを持っています。その関数の修正バージョンを別のサブルーチンに渡したいと思います。私は「G」が唯一の通常の変数ではなく、機能を使用する必要がある場合にも、同様の何かをするために管理してきました別の関数からの動的関数の作成

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 

:私は、プログラムがこのような何かを見てみたいです。その場合、私はグローバル変数を使用してグローバル関数を作成し、 'foo'のグローバル変数に割り当てました。しかし、私は 'f'をグローバルにしたり、グローバル関数に割り当てる方法を見つけることはできません。

これを行う方法はありますか?ソリューションは、あなたが望むようにハッキリにすることができます。

答えて

1

プロシージャポインタで多くのことを行い、他の関数の組み合わせである関数を構築することができます。コード例については、Function pointer arrays in Fortranを参照してください。

4

これはあまり簡単ではありません。いくつかの言語では、ネストされた関数へのポインタを、いわゆるclosureで渡すことができます。これは、Fortran(またはCなどの言語)では可能ではありません。これは、上位の関数のスタックでデータが破壊されるためです。関数オブジェクト、つまりfunction pointer(以上)を持つclassとその関数に必要なデータを試してみることをお勧めします。このようにして、機能の構成や同様の機能を実行することさえできます。コンセプトの下http://en.wikipedia.org/wiki/Function_object

よりは、2つの引数の関数の合成のための関数オブジェクトのためのサンプルです:例えば

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 
+0

おかげで、それは、Fortran 90に働くだろうか?あなたが使用したキーワードの多くは、私には新しいものです。特に私は90年ではなく2003年の「手続き」への参照を見つけることができただけです。 –

関連する問題