General API for optimizing routines
Fortran has a huge ecosystem in optimization libraries, but they are dispersed with different APIs and different ways to define objective functions. This library aims to standarize the way to call optimization functions to ease the process of selecting algorithms to optimize problems.
This is still a prototype project so big changes can happen
For examples of usage check the examples
directory.
The objective function that should be minimized must have the following interface
module my_objective
use ForTimize, only: pr
contains
subroutine foo(X, F, dF, data)
real(pr), intent(in) :: x(:)
!! Vector of parameters to optimize
real(pr), intent(out) :: F
!! Value of the objetive function after optimization.
real(pr), optional, intent(out) :: dF(:) !!
!! Optional gradient.
class(*), optional, intent(in out) :: data
!! Special data that the function could use.
F = sum(x+2)**2
end subroutine
end module
Then the objective function can be optimized with:
program main
use ForTimize, only: pr, minimize
use my_objective, only: foo
real(pr) :: x(3), F
! Initial guess
x = [1, 2, 5]
! Minimize uses the Nelder-Mead algorithm as a default
call minimize(foo, x, F)
! Print results
print *, x
print *, F
end program
All the optimization algorithms should extend
the Abstract type Optimizer
,
which ensures that the optimize
method is respected.
module my_new_optimizer
use ForTimize__constants, only: pr
use ForTimize__core, only: Optimizer, objective_function
type, extends(Optimizer) :: MyNewAlgorithm
contains
procedure :: optimize => optimizer_implementation
end type
contains
subroutine optimizer_implementation(self, foo, X, F, data)
class(Optimizer), intent(in out) :: self
!! Optimizer object
procedure(objective_function) :: foo
!! Objective function to minimize
real(pr), intent(in out) :: X(:)
!! Vector of parameters
real(pr), intent(out) :: F
!! Function value after optimization
class(*), optional, target, intent(in out) :: data
!! Optional data that could be useful for the function
! Optimizer procedures here.
end subroutine