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

Reply via email to