Dynamic function creation from another function - function

I have a Fortran 90 subroutine which takes a function as an argument, and I would like to pass a modified version of that function into another subroutine. I want the program to look something like this:
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
I've managed to do something similar when 'g' only needs to use normal variables, not a function. In that case I made it a global function, using global variables, and assigned to those global variables in 'foo'. However, I can't find a way to turn 'f' global, or assign it to a global function.
Anybody have any ideas how to do this? The solution can be as hacky as you want.

This is not so easy. In some languages you can pass pointers to nested functions in a so called closure. This is not possible in Fortran (or C and similar languages), because the data are destroyed with the stack of the higher function. I would suggest you to try function objects, i.e. a class with a function pointer (or more) and data needed for the function. In this way you can even do function composition and similar functional stuff.
More on the concept http://en.wikipedia.org/wiki/Function_object
Below is a sample for a function object for composition of two single argument functions:
module ComposeObj
use Parameters, only: rp
use AritmFunctions, only: fce
implicit none
private
public Compose
type Compose
private
procedure(fce),pointer,nopass :: f1 => null(),f2=>null()
contains
procedure,public :: call => helper
end type 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(rp) function helper(this,x)
class(Compose),intent(in) :: this
real(rp),intent(in) :: x
helper = this%f1(this%f2(x))
end function helper
end module ComposeObj

You could do a lot with procedure pointers, constructing a function that is a combination of other functions. See Function pointer arrays in Fortran for a code example.

Related

Julia - Change method definition within a function

So here's what I want, I have a function: f(x,t)=... where x is the "true" variable and t is a parameter. However, I need to use this function as a parameter in the Calculus package's derivative. This function requires a function with only one parameter. For this what I thought off was to redefine a method f(x)=f(x,t) where I fix the t parameter before passing it to the derivative function. This has to be done within another function.
However, doing this literally returns this error :
syntax: cannot add method to function argument f
I believe due to variable scope issues you should simply select a different name for your new function. You can also use anonymous functions instead of named definitions.
function foo(t_val)
newf(x) = f(x, t_val)
derivative(newf, otherparams...)
end
With anonymous functions,
function foo(t_val)
derivative(x -> f(x, t_val), otherparams...)
end
You can also assign anonymous functions to variables and use the variables as a function.
function foo(t_val)
newf = x -> f(x, t_val)
derivative(newf, otherparams...)
end

User defined constructor for Fortran derived type instance

This is my second question related to Fortran (I use C++, so forgive me my way of thinking).
I want to use OOP, to say, derived type in Fortran whenever appropriate.
In C++, you can use user defined constructor such as https://msdn.microsoft.com/en-us/library/s16xw1a8.aspx
Here in Fortran, things are different.
The first thing I tried is from here:
https://www.ibm.com/developerworks/community/blogs/b10932b4-0edd-4e61-89f2-6e478ccba9aa/entry/object_oriented_fortran_user_defined_constructors2?lang=en
Link is broken, so I pasted it here:
module m
!...
interface base
module procedure new_base
end interface
contains
!...
function new_base(I)
integer, intent(in) :: I
type(base) new_base
allocate(new_base%data(I))
new_base%data = I
end function
!...
end module
The interface above defines a user-defined constructor for type base. It is used in a similar way to a structure constructor. It can even take argument keywords.
Then I found some other ways to do it.
Here I listed a few approaches seemly to work but I only tested the first and second:
generic interface with the same name as the derived type they're supposed to construct, see link above;
use type-bound procedure (This is not even a "traditional" constructor)
MODULE mymod
TYPE mytype
Private
INTEGER :: x
CONTAINS
PROCEDURE, PASS :: init
END TYPE
CONTAINS
SUBROUTINE init(this, i)
CLASS(mytype), INTENT(OUT) :: this
INTEGER, INTENT(IN) :: i
write(*,*) this%x
IF(i > 0) THEN
this%x = 1
ELSE
this%x = 2
END IF
write(*,*) this%x
END SUBROUTINE init
END
PROGRAM test
USE mymod
TYPE(mytype) :: y
CALL y%init(1)
END PROGRAM
use Static Constructors or Structure Constructors (http://www.lahey.com/docs/lfenthelp/NLMOvUsInvConst.htm)
But it appears that this is NOT for general Fortran http://www.lahey.com/docs/lfenthelp/NLMGSWhatIs.htm
So I haven't understood well enough what is most preferred and flexible approach to initialize/construct a derived type in practice, especially when I use nested derived type in development. I hope I can organize this topic with some help.
OK, so I will assume you read well the answers at How to override a structure constructor in fortran and I will answer your problem raised in the comment. There is not enough place in the comment to answer that.
You can also make constructors in Fortran which accept variable number of arguments.
It is even possible with the default structure constructors which every derived type has by default. If you default-initialize a component, it is optional in the constructor. The same holds for allocatable and pointer components.
For type
type t1
integer :: i = 1
integer, pointer :: ip => null()
integer, allocatable :: ap
end type
you can call the default constructor just as
instance = t1()
and it is perfectly legal, i will be 1, ip will point to null and ap will not be allocated.
Or you can call it as
instance = t1(ap=5)
and the ap component will be allocated and set to 5 and the other components will be left default.
You can achieve similar stuff with user defined constructors just by making the arguments optional.
function t1_user(ap, i) result(res)
type(t1) :: res
integer, allocatable :: ap !this argument MUST be passed,
! it does not have to be allocated
integer, optional :: i ! this argument is optional
if (present(i)) then
...
end if
end function
any type-bound procedure can of-course also have optional arguments.
As for the nested types, that is really best done with constructors as functions, no matter if they are default or user defined:
type inner
real :: x, y
end type
type outer
type(inner), allocatable :: in
real :: z
end type
instance1 = outer(inner(1., 2.), 3.)
instance2 = outer(z=4.)

Procedure with assumed-shape dummy argument must have an explicit interface [duplicate]

This question already has an answer here:
Module calling an external procedure with implicit interface
(1 answer)
Closed 5 years ago.
I am completely new to Fortran 90 and I am trying to understand how to pass an array to a function. I looked on the web and I could not find any clear and simple enough example, so I decided to post here.
I would like the function be able to work on an array of any length (the length of the array should not be one of the parameters of the functions).
I tried to write a simple example of a function that returns the sum of the elements of an array:
function mysum(arr)
implicit none
real, dimension(:), intent(in) :: arr
real :: mysum
integer :: i,arrsize
arrsize = size(arr)
mysum=0.0
do i=1,arrsize
mysum=mysum+arr(i)
enddo
end function mysum
program test
implicit none
real, dimension(4) :: a
real :: mysum,a_sum
call random_number(a)
print *,a
a_sum=mysum(a)
print *,a_sum
end program
When I try to compile, I get the following error:
array_test.f90:17.14:
real mysum,a_sum
1
Error: Procedure 'mysum' at (1) with assumed-shape dummy argument 'arr' must have an explicit interface
What is the problem with my program?
Assumed shape dummy arguments (those with (:)) require explicit interface to the procedure to be available at the call site. That means the calling code must know how exactly the subroutine header looks like. See also Module calling an external procedure with implicit interface
That explicit interface can be provided in several ways
1.
preferred - a module procedure
module procedures
implicit none
contains
function mysum(arr)
real, dimension(:), intent(in) :: arr
real :: mysum
integer :: i,arrsize
arrsize = size(arr)
mysum=0.0
do i=1,arrsize
mysum=mysum+arr(i)
enddo
end function mysum
end module
program test
use procedures
implicit none
!no mysum declared here, it comes from the module
...
end program
2.
internal procedure - only for short simple procedures or if the procedure needs access to the host's variables. Because of the access to the host variables it is error-prone.
program test
implicit none
!no a_sum declared here, it is visible below contains
...
contains
function mysum(arr)
!implicit none inherited from the program
real, dimension(:), intent(in) :: arr
real :: mysum
integer :: i,arrsize
arrsize = size(arr)
mysum=0.0
do i=1,arrsize
mysum=mysum+arr(i)
enddo
end function mysum
end program
3.
interface block - not recommended at all, you should have some particular reason to use it
function mysum(arr)
! removed to save space
end function mysum
program test
implicit none
interface
function mysum(arr)
real, dimension(:), intent(in) :: arr
real :: mysum
end function
end interface
!no mysum declared there
!it is declared in the interface block
...
end program

Fortran and interface blocks in functions or subroutines

I would like to write a module which will perform some action based on function type provided by "user" in different file. This function will be passed as an argument of "execute(...)" subroutine of that module. This is basically what I want to obtain, but I don't know if this is possible and how should I do it correctly.
module mod1
contains
subroutine execute(func)
interface func
real function func1(a,b)
real a,b
end function
real function func2(a,b,c)
real a,b,c
end function
! more similar functions here
end interface func
! -------------------
! here some how choose between func1 or func2
! and do the calculations
if(func1) then ...
else if(func2) ...
! -------------------
endsubroutine execute
endmodule mod1
------------------------------------------
program
use mod1
call execute(test)
contains
real function test(a,b)
real a,b
test = a + b
end function
end program
I know that this code wont compile, but this is just a sketch how it would look like. For now, the only ugly solution for that problem for me is to write many alternatives for execute subroutine i.e execute_1, execute_2 and depending on the test function user will have to choose proper execute_X function.
Is there any better solution for that problem?
Thanks in advance. KK
You can also put the interfaces in the module header, and use the procedure attribute for func1 and func2 like so. This is useful if you want to use them elsewhere, since you are only defining them in one place.
module mod1
abstract interface
real function f1(a,b)
real,intent(in) :: a,b
end function f1
real function f2(a,b,c)
real,intent(in) :: a,b,c
end function f2
end interface
contains
subroutine execute(func1, func2)
procedure(f1),optional :: func1
procedure(f2),optional :: func2
!...
if (present(func1)) x = func1(a, b)
if (present(func2)) x = func2(a, b, c)
end subroutine execute
end module mod1
Guessing a little at your intent based on the example source, your problem is that you want a dummy procedure that may vary in its characteristics - for example the number of arguments.
I don't recommend this, but Fortran permits a dummy procedure to have an implicit interface - you could just give the func dummy procedure the external attribute, and then it is on the programmer's head to make sure that the nature of the reference through the dummy procedure is consistent with the interface of the actual procedure. Language facilities that require an explicit interface may not be used with this approach.
subroutine execute(func)
real, external :: func
!...
if (some_condition) then
x = func(a, b)
else
x = func(a, b, c)
end if
If you want the dummy procedure to have an explicit interface, then you might be able to use optional arguments.
module mod1
contains
subroutine execute(func1, func2)
interface
real function func1(a,b)
real a,b
end function func1
real function func2(a,b,c)
real a,b,c
end function func2
end interface
optional :: func1, func2
!...
if (present(func1)) x = func1(a, b)
if (present(func2)) x = func2(a, b, c)
end subroutine execute
end module mod1
program p
use mod1
call execute(func1=test)
contains
real function test(a,b)
real a,b
test = a + b
end function
end program p
More general solutions to this problem may invoke the procedure through a a binding of a derived type - the invocation of the procedure always uses the same interface, but additional information can then be passed through to the procedure using components of the derived type.

How to alias a function name in Fortran

Not sure if the title is well put. Suggestions welcome.
Here's what I want to do. Check a condition, and then decide which function to use in a loop. For example:
if (a < 0) then
loop_func = func1
else
loop_func = func2
endif
I can then use loop_func as a pointer when writing my loop. Both functions take exactly the same inputs, and are different approaches on tackling the problem based on the value of a. This will allow me to only have one block of code, instead of two nearly identical blocks. This could apply to subroutines too.
Any ideas how this might be implemented?
Thank you.
Yes, Fortran has procedure pointers, so you can in effect alias a function name. Here is a code example which assigns to the function pointer "f_ptr" one function or the other. Thereafter the program can use "f_ptr" and the selected function will be invoked.
module ExampleFuncs
implicit none
contains
function f1 (x)
real :: f1
real, intent (in) :: x
f1 = 2.0 * x
return
end function f1
function f2 (x)
real :: f2
real, intent (in) :: x
f2 = 3.0 * x**2
return
end function f2
end module ExampleFuncs
program test_func_ptrs
use ExampleFuncs
implicit none
abstract interface
function func (z)
real :: func
real, intent (in) :: z
end function func
end interface
procedure (func), pointer :: f_ptr => null ()
real :: input
write (*, '( / "Input test value: ")', advance="no" )
read (*, *) input
if ( input < 0 ) then
f_ptr => f1
else
f_ptr => f2
end if
write (*, '(/ "evaluate function: ", ES14.4 )' ) f_ptr (input)
stop
end program test_func_ptrs
Most Fortran implementations do not have a standard way to manipulate function pointers or procedure pointers. However, Fortran 2003 and later have something. (See page 6 of this.)
For the given situation, this will work pretty well in its place:
function func1 (p1, p2, etc)
... as you have it already
end
function func2 (p1, p2, etc)
... as you have it already
end
function funcselect (a, p1, p2, etc)
if (a < 0) then
x = func1 (p1, p2, etc)
else
x = func2 (p1, p2, etc)
endif
end
Then just call funcselect with the extra parameter instead of what you would have done with loop_func.