OK so maybe what I did is somewhat opinionated.
If you look more closely, you will see that brentq
is not designed to be called directly. It鈥檚 only called though the higher-level class method solve
(part of the root_solver
class). opt-lib/stdlib_root_core.F90 at 0ce2825f87d511bc33764e0aadd3f3061c9c8ca6 路 jacobwilliams/opt-lib 路 GitHub
(the intent being not to duplicate code that is common to all methods).
What you are looking for is already there: opt-lib/stdlib_root_core.F90 at 0ce2825f87d511bc33764e0aadd3f3061c9c8ca6 路 jacobwilliams/opt-lib 路 GitHub
subroutine root_scalar(method,fun,ax,bx,xzero,fzero,iflag,&
ftol,rtol,atol,maxiter,fax,fbx,bisect_on_failure)
implicit none
character(len=*),intent(in) :: method !! the method to use
procedure(func2) :: fun !! user function to find the root of
real(wp),intent(in) :: ax !! left endpoint of initial interval
real(wp),intent(in) :: bx !! right endpoint of initial interval
real(wp),intent(out) :: xzero !! abscissa approximating a zero of `f` in the interval `ax`,`bx`
real(wp),intent(out) :: fzero !! value of `f` at the root (`f(xzero)`)
integer,intent(out) :: iflag !! status flag (`-1`=error, `0`=root found, `-999`=invalid method)
real(wp),intent(in),optional :: ftol !! absolute tolerance for `f=0`
real(wp),intent(in),optional :: rtol !! relative tol for x
real(wp),intent(in),optional :: atol !! absolute tol for x
integer,intent(in),optional :: maxiter !! maximum number of iterations
real(wp),intent(in),optional :: fax !! if `f(ax)` is already known, it can be input here
real(wp),intent(in),optional :: fbx !! if `f(ax)` is already known, it can be input here
logical,intent(in),optional :: bisect_on_failure !! if true, then if the specified method fails,
!! it will be retried using the bisection method.
!! (default is False). Note that this can use up
!! to `maxiter` additional function evaluations.
Which is called like so:
call root_scalar('brentq', func, ...)
So, this is the interface you want, I think. But notice that it is simply a wrapper to the object-oriented interface (and not vice versa). To me, the object-oriented interface is the real one, and this one is just a simple wrapper (that has some compromises under the hood since there is a class allocation that is happening, as well as a string comparison and case statement).
My intent is to add a speed test to the unit tests to see what the runtime overhead of this is and we can decide if it is OK or not. Nothing is set in stone right now.