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

Reply via email to