-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support force stop #24
Comments
Isn't this a problem of the C interface too (see forced termination)? The only way you can pass a In Ceres, the What you could do here is introduce a new set of callback interfaces which flip a |
Maybe using a derived type as the result could reduce interface verbosity: function nlopt_func_interface(x, gradient, func_data) result(f)
import :: c_int, c_double, c_ptr
implicit none
real(c_double), intent(in) :: x(:)
real(c_double), intent(inout), optional :: gradient(:)
class(*), intent(in), optional :: func_data
real(c_double) :: f
end function subroutine firstorder_callback(x,result,func_data)
real(c_double), intent(in) :: x(:)
type(result_type), intent(inout) :: result ! intent(inout) needed to keep gradient array intact
class(*), intent(in), optional :: func_data
result%success = .true. ! could be assumed by default
result%cost = ...
if (result%expects_grad) then ! or, if(has_grad(result)), or if (associated(result%gradient))
result%gradient = ... ! grad
end if
end subroutine |
In the C++ wrapper, they assume users will throw an exception to force a stop. They then pass the Seeing this solution, the lowest hanging fruit would be to provide an extended |
Passing through the object handle as In the current |
Indeed. If you can roll out an interface with a boolean, it can be reused for the Ceres first-order function solver. Same problem definition, but with two different solver libraries. |
NAG uses the following interface in e04kdf ! NAG E04KDF (bounds_mod_deriv_comp)
!
Subroutine funct ( iflag, n, xc, fc, gc, iw, liw, w, lw)
Integer, Intent (In) :: n, liw, lw ! Array sizes
Integer, Intent (Inout) :: iflag ! Will have been set to 1 or 2 on entry, set negative to terminate
Integer, Intent (Inout) :: iw(liw) ! Integer array (User workspace)
Real (Kind=nag_wp), Intent (In) :: xc(n) ! Real array, point x at which to evaluate
Real (Kind=nag_wp), Intent (Inout) :: w(lw) ! Real array (User Workspace)
Real (Kind=nag_wp), Intent (Out) :: fc ! Objective function F at the current point
Real (Kind=nag_wp), Intent (Out) :: gc(n) ! Gradient array The meaning of
Unfortunately, this specification is at odds with the NLopt expectations (either F or both F and grad(F)). Not that many NAG users are seeking an open-source alternative... Edit: Some of their newer routines, like e04kff (handle_solve_bounds_foas) also accept a void pointer for passing additional parameters: Subroutine objfun ( nvar, x, fx, inform, iuser, ruser, cpuser)
Integer, Intent (In) :: nvar
Integer, Intent (Inout) :: inform, iuser(*)
Real (Kind=nag_wp), Intent (In) :: x(nvar)
Real (Kind=nag_wp), Intent (Inout) :: ruser(*)
Real (Kind=nag_wp), Intent (Out) :: fx
Type (c_ptr), Intent (In) :: cpuser (In this routine, the gradient callback is passed separately; |
This is similar to the minpack callback which has an |
In many cases NAG has two sets of routines (and accompanying interfaces): "easy" routines, with no option to force stop or recover from errors, and expert routines for edge cases. An easy routine can help users adopt your library. They can upgrade to the expert interface when they need it. It does however increase the # of LOC in the library. |
Implementing the easy routines would be done by wrapping the expert routines internally, which should be more or less fine in term of required code. Having a different callback interface however means another adaption layer in between to match signatures, which might be undesirable, but I guess additional function calls themselves are not that expensive, depending on the objective function to evaluate. |
We have bindings for the force stop procedure, however there is no way to use them easily from the callback as we need access to the handle to make use of it.
Having the function wrapper store the handle might be an option, however this makes it more difficult to reuse a function in different optimizers.
The text was updated successfully, but these errors were encountered: