8

関数を出力として返すサブルーチンを作成したいと考えています。どうやってやるの?私はそれがどうあるべきだと思うかの例を挙げます(私はそれがひどく書かれていることを知っています)

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

これにより、出力で指数ファミリから関数を取得する必要があります。

4

2 に答える 2

3

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

   procedure(name_of_interface), pointer :: f

ただし、完全なレキシカル スコープ クロージャを期待してはいけません。純粋なポインタだけです。

通常の外部、モジュール、または F2008 の内部プロシージャ (いくつかの制限あり) としてプロシージャを準備し、それをポイントする必要があります。

    f => my_function

あなたの場合、引数がaあり、それをキャプチャされたクロージャー変数として使用したいようです。Fortran ではできません。毎回関数に渡すか、Functor パターン (キャプチャされたパラメーターを保持する派生型) を使用するか、内部プロシージャーを使用する必要があります (ただし、これはホスト プロシージャー内でのみ有効です)。

于 2013-10-30T07:11:42.840 に答える
2

ファンクターオブジェクトを定義することで、基本的にそれを行うことができます(ウラジミールの回答にも記載されています)。値を返す特定の関数が 1 つあり (例: getvalue())、初期化に応じて、カスタマイズされた関数値を返す場合があります。

以下の例は、その詳細を示しています。一般関手は で定義されfunctor_moduleexpfunc_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
于 2013-10-30T17:09:33.463 に答える