2013-10-30 3 views
5

Ich möchte ein Unterprogramm erstellen, das eine Funktion als Ausgabe zurückgibt. Wie kann ich das machen? Ich werde ein Beispiel setzen, wie ich denke, es sollte sein (ich weiß, es ist schlecht geschrieben)Funktion als Ausgabeargument

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 

Damit ich eine Funktion aus der exponentiellen Familie in der Ausgabe nehmen.

Antwort

2

Sie müssten einen Funktionszeiger zurückgeben. Das kann in Fortran 2003 getan werden.

procedure(name_of_interface), pointer :: f 

Sie müssen jedoch nicht volle lexical Umfangabschlüsse erwarten, nur pure Zeiger.

Sie müssen die Prozedur als normales externes Modul oder in F2008 sogar internes Verfahren (mit einigen Einschränkungen) vorbereitet haben und weisen nur darauf:

f => my_function 

In Ihrem Fall haben Sie das Argument a und Sie scheinen eine erfasste Schließvariable verwenden zu wollen. In Fortran ist das nicht möglich. Sie müssen es entweder jedes Mal an die Funktion oder das Functor-Muster (abgeleiteter Typ, der die erfassten Parameter enthält) übergeben oder eine interne Prozedur verwenden (die aber nur innerhalb der Host-Prozedur gültig wäre).

1

Das können Sie grundsätzlich (wie auch in Vladimir's answer erwähnt) mit der Definition von Funktor-Objekten tun. Sie haben eine spezifische Funktion, die den Wert zurückgibt (z. B. getvalue()), und sie können abhängig von ihrer Initialisierung angepasste Funktionswerte zurückgeben.

Das Beispiel unten demonstriert das im Detail. Der allgemeine Funktor ist in functor_module definiert, in expfunc_module ist eine konkrete Realisierung für die Exponentialfunktionsfamilie abgeleitet. Dann initialisieren Sie im Hauptprogramm verschiedene Instanzen mit unterschiedlichen Vorfaktoren in den Exponenten und können ihre -Methode verwenden, um die entsprechenden Funktionswerte zu erhalten:

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