I am trying to use STOGO algorithm from NLOPT in Fortran. The algorithm never stops running. If I give a value for maxeval, the algorithm always stops after the maximum number of evaluations and gives a return value of 1 (generic success return value) whereas I would expect it to be 5 (Optimization stopped because maxeval was reached). Adding stopping criteria such as $ftol_rel$ or $ftol_abs$ has no effect. Below is the minimal code I am using. Any clue on what I should do? Thanks!
In the module to count the number of function evaluations: module myparams integer :: counter = 0 ! counts the number of calls end module myparams In the main program program main use myparams implicit none external myfunc integer, parameter :: dim = 2 ! dimension of the problem double precision lb(dim), ub(dim) ! lower and upper bounds of the domain integer*8 opt double precision x(dim), minf integer ires integer idim include 'nlopt.f' !defines bounds do idim = 1,dim lb(idim) = -10.0 ub(idim) = 10.0 enddo ! initial guess point x(1) = 1.234 x(2) = 5.678 call nlo_create(opt, NLOPT_GD_STOGO, dim) ! set lower and upper bounds call nlo_set_lower_bounds(ires, opt, lb) call nlo_set_upper_bounds(ires, opt, ub) !defines the tolerance (stopping criteria) call nlo_set_ftol_rel(ires, opt, 1.D-15) call nlo_set_maxeval(ires, opt, 600000) ! the counter always reaches maxeval. but the return value (ires) is 1 = generic success. call nlo_set_stopval(ires, opt, 1.01) ! initialize counter of number of calls to the function during search counter = 0 call nlo_set_min_objective(ires, opt, myfunc, 0) call nlo_optimize(ires, opt, x, minf) if (ires.lt.0) then write(*,*) 'nlopt failed! error code: ', ires else write(*,*) 'found min at ', x write(*,*) 'min val = ', minf write(*,*) 'found after ', counter, 'iterations' write(*,*) 'ires code: ', ires, ' (1 means generic success)' write(*,*) endif call nlo_destroy(opt) end program main subroutine myfunc(val, n, x, grad, need_gradient) use myparams, only: counter double precision val, x(n), grad(n) integer n, need_gradient counter = counter + 1 val = (x(1) - 1.0)**2.0 + (x(2)-2.0)**2.0 + 1.0D0 if (need_gradient.ne.0) then grad(1) = 2.0*(x(1) - 1.0) grad(2) = 2.0*(x(2) - 2.0) endif end subroutine myfunc
_______________________________________________ NLopt-discuss mailing list NLopt-discuss@ab-initio.mit.edu http://ab-initio.mit.edu/cgi-bin/mailman/listinfo/nlopt-discuss