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
[email protected]
http://ab-initio.mit.edu/cgi-bin/mailman/listinfo/nlopt-discuss