- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi
I have a problem and I guess the correct approach is procedure pointers.
Here is the problem
I have derived type contains a procedure for optimization. Lets say simplexb.
This function gets a set of numbers -- say coeff-- and needs to call a cost function to optimize.
At this point I want to have a freedom to pick cost function at runtime according to settings.
I have declared a pointer procedure with an interface.
[fortran] type , abstract :: parent_optimizer real(8) :: tolerance contains procedure ( opt_solve) , deferred :: optimizer end type parent_optimizer abstract interface function opt_solve(this,coeff) result ( iostat) import :: parent_optimizer class(parent_optimizer) :: this real(8) , dimension (:),intent(inout) :: coeff integer :: iostat end function end interface !--------------------------------------------------- type , extends(parent_optimizer) :: simplexb_opt integer :: iteration procedure(cost_func), nopass, pointer :: cost contains procedure :: optimizer => simplexb end type !--------------------------------------------------- interface function cost_func(coeff) result ( total_cost) real(8) , dimension(:) :: coeff real(8) :: total_cost end function end interface[/fortran]
[fortran]
[/fortran]
ifort compiles this part .
To use this setup I have defined another derived type with a procedure with no pass attribute:
[fortran]module fitdriver_module use opt_simplexb_module use parameters_module use structures_module type test_cost contains procedure ,nopass:: test_cost_function end type contains subroutine fitdriver(structure,parset) type(structures) :: structure type(parameters) :: parset class(*) , allocatable :: optimizer type(test_cost),target :: tc allocate(simplexb_opt :: optimizer) optimizer%cost=> tc%test_cost_function end subroutine fitdriver !----------------------------------------------------------------------------- function test_cost_function(coeff) result (cost) real(8) , dimension(:) :: coeff real(8) :: cost integer :: ndim integer :: i ndim=size(coeff) cost=0.d0 do i=1,ndim cost=cost+(-1)**i*sin(coeff(i)) end do end function end module fitdriver_module[/fortran]When I compile this I receive following errror:
error #6460: This is not a field name that is defined in the encompassing structure. [COST]
optimizer%cost=> tc%test_cost_function
error #6460: This is not a field name that is defined in the encompassing structure. [COST] optimizer%cost=> tc%test_cost_functionThe main aim is to be able to choose cost function at runtime. I don't know if there is a better approach?
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your main problem here is in declaring optimizer to be CLASS(*) - as such, the compiler has no idea what fields it contains unless you are within a SELECT TYPE construct. Either use SELECT TYPE or declare optimizer to be type(simplexb_opt). What did you want the CLASS(*) to do for you?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I will have different optimizer types for different optimizer algorithms but at the driver stage
they all should be same and user will choose one of them with settings file.
Similarly I will have different cost_function objects but all of them will receive a set of number.
In the runtime code will decide which optimizer algorithm will be used and which cost_function object
will be called. My idea was to put a pointer procedure for cost function to the optimizer object and in the runtimeI can point (associate) this procedure with actual cost function.
Is that doable?
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can use procedure pointers for this, but the "selection" part will require an approach other than using CLASS(*). The problem is that you want to decide at run-time, based on some external value, which set of routines to use. The usual way of doing this is to have an array of procedure pointers and select one array element based on the requirement. A complication is that Fortran does not have the concept of an array of pointers, so you have to do it as an array of derived types with a pointer component. When the program starts, it fills the array with the possible values.
Perhaps one of the users here will have another approach to recommend.
Perhaps one of the users here will have another approach to recommend.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My another and possibly more important problem here is to link optimizer%cost to cost_funct%cost
cost_func is a derived type and has a component procedure function called cost.
On the other hand optimizer%cost is a pointer procedure with an abstract interface.
What will be the correct syntax to assign a derived type's pointer component to another derived types component procedure?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am not sure what you mean by "component procedure". If you mean that cost_func has a procedure pointer component, then you use pointer assignment just as you did in the code you posted.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page