2013-10-30 20 views
5

関数として出力を返すサブルーチンを作成したいと思います。どうやってやるの?私は出力に指数の家族から機能を取るべきこれにより出力引数としての機能

module fun_out 

contains 

subroutine exponential(F,a) 
    interface, intent(out) 

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

    F=exp(a*x) 

end subroutine exponential 

end module 

(私はそれがひどく書かれている知っている)私はそれがあるべきだと思う方法の例をあげますよ。

答えて

2

関数ポインタを返す必要があります。これはFortran 2003で行うことができます。

procedure(name_of_interface), pointer :: f 

完全なレキシカルスコープクロージャーは、純粋なポインターだけではありません。

あなたはそれに正常な外部モジュールやF2008で(一部制限あり)も、内部手続、ちょうどポイントとして準備手順を持っている必要があります:あなたのケースでは

f => my_function 

をあなたは、引数aを持っており、キャプチャされたクロージャ変数を使用したいと思われます。 Fortranでは不可能です。関数に渡すたびに、またはFunctorパターン(取得されたパラメータを保持する派生型)を渡すか、内部プロシージャを使用する必要があります(ホストプロシージャ内でのみ有効です)。

1

functorオブジェクトを定義して基本的に(Vladimir's answerでも言及されているように)行うことができます。それらは値を返す1つの特定の関数(たとえばgetvalue())を持ち、初期化によってはカスタマイズされた関数値を返すことがあります。

以下の例は、その詳細を示しています。一般ファンクタはfunctor_moduleで定義され、expfunc_moduleでは指数関数ファミリの具体的な実現が導出されます。次に、メインプログラムで指数部の異なるプリ係数を持つ異なるインスタンスを初期化し、適切な関数値を得るためにgetvalue()メソッドを使用することができます。:

module functor_module 
    implicit none 

    integer, parameter :: wp = kind(1.0d0) 

    type, abstract :: functor 
    contains 
    procedure(getvalue_iface), deferred :: getvalue 
    end type functor 

    interface 
    function getvalue_iface(self, xx) result(yy) 
     import 
     class(functor), intent(in) :: self 
     real(wp), intent(in) :: xx 
     real(wp) :: yy 
    end function getvalue_iface 
    end interface 

end module functor_module 


module expfunc_module 
    use functor_module 
    implicit none 

    type, extends(functor) :: expfunc 
    real(wp) :: aa 
    contains 
    procedure :: getvalue 
    end type expfunc 

contains 

    function getvalue(self, xx) result(yy) 
    class(expfunc), intent(in) :: self 
    real(wp), intent(in) :: xx 
    real(wp) :: yy 

    yy = exp(self%aa * xx) 

    end function getvalue 

end module expfunc_module 


program test_functors 
    use expfunc_module 
    implicit none 

    type(expfunc) :: func1, func2 
    real(wp) :: xx 

    func1 = expfunc(1.0_wp) 
    func2 = expfunc(2.0_wp) 
    xx = 1.0_wp 
    print *, func1%getvalue(xx) ! gives exp(1.0 * xx) = 2.718... 
    print *, func2%getvalue(xx) ! gives exp(2.0 * xx) = 7.389... 

end program test_functors 
関連する問題