I want to create a subroutine that gives back a function as an output. How can I do that? I'll put an example of how I think it should be (I know it's badly written)
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
With this I should take a function from the exponential family in the output.
When you use a function as part of an expression, such as an if statement, then MATLAB® calls the function with one output argument. Therefore, the nargout function returns 1 within expressions. If you check for a nargout value of 0 within a function and you specify the value of the output, MATLAB populates ans .
In mathematics, an argument of a function is a value provided to obtain the function's result. It is also called an independent variable. , is called a unary function. A function of two or more variables is considered to have a domain consisting of ordered pairs or tuples of argument values.
An argument default value can be any constant or expression that satisfies the size, class, and validation function requirements. Specifying a default value in an argument declaration makes the argument optional. MATLAB uses the default value when the argument is not included in the function call.
You would have to return a function pointer. That can be done in Fortran 2003.
procedure(name_of_interface), pointer :: f
You must however not expect full lexical scope closures, just pure pointers.
You must have the procedure prepared as a normal external, module or in F2008 even internal procedure (with some limitations) and just point to it:
f => my_function
In your case you have the argument a
, and you seem to want to use it a captured closure variable. It is not possible in Fortran. You either have to pass it every time to the function, or us the Functor pattern (derived type holding the captured parameters), or use an internal procedure (but that would be valid only inside its host procedure).
You can basically do that (as also mentioned in Vladimir's answer) with defining functor objects. They have one specific function returning the value (e.g. getvalue()
), and depending on their initialization, they may return customized function values.
The example below demonstrates that in detail. The general functor is defined in functor_module
, in expfunc_module
a concrete realization for the exponential function family is derived. Then, in the main program then you initialize different instances with different prefactors in the exponents and can use their getvalue()
method to obtain the appropriate function values.:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With