I using DUVMIF to estimate the minimum of my objective function, defined in the following code block:
!********************************************************************************************
subroutine optimize(b_next,gn_value, h_value,v_value,a_initial2,b_initial2,i_default_global2)
USE GLOBAL
USE UVMIF_INT
implicit none
REAL(8),INTENT(IN)::a_initial2,b_initial2
INTEGER,INTENT(IN)::i_default_global2
REAL(8),INTENT(OUT)::b_next,gn_value,h_value,v_value
INTEGER, PARAMETER::num=100,XACC = 1d-4,MAXFN = 1000
integer :: i,t, d, index_opt, index_vector(1) ,index_opt2
REAL(8) :: new_value, old_value,old_value2, b, q,vector(nb),&
b_next_grid(num), STEP, BOUND, b_next_guess
real(8)::b_next_inf,b_next_sup
EXTERNAL DUVMIF
REAL(8)::value1,value2
b_next_inf = bmin
b_next_sup = -0.48d0
old_value = 10d+33
do i=1,num
b_next_grid(i) = b_next_inf + (b_next_sup - b_next_inf) * (i-1)/ (num - 1)
new_value = objective_fun2(b_next_grid(i))
if (new_value <= old_value) then
index_opt = i
b_next_guess = b_next_grid(i)
old_value = new_value
end if
if ((DABS(old_value-new_value) <= 1d-6)) then
index_opt2 = i
old_value2 = new_value
end if
end do
STEP = (b_next_grid(2) - b_next_grid(1))*0.5
BOUND = EXP(amax)
PRINT*,'initial guess obtained'
PRINT*,' '
IF (old_value.GE.1d5) THEN
b_next = 0d0
gn_value=0d0
h_value=0d0
v_value = -old_value
ELSEIF (((DABS(old_value2 - old_value)) < 1d-6).AND.(index_opt2.NE.index_opt)) THEN
b_next = b_next_grid(index_opt2)
call objective_fun(b_next,gn_value,h_value,v_value,a_initial2,b_initial2,i_default_global2)
v_value=-v_value
ELSE
call DUVMIF(objective_fun2, b_next_guess, STEP, BOUND, XACC, MAXFN, b_next)
call objective_fun(b_next,gn_value,h_value,v_value,a_initial2,b_initial2,i_default_global2)
v_value = -v_value
end if
CONTAINS
REAL(8) FUNCTION objective_fun2(x)
REAL(8),INTENT(IN)::x
REAL(8)::xgn,xh,xvalue
CALL objective_fun(x,xgn,xh,xvalue,a_initial2,b_initial2,i_default_global2)
objective_fun2 = xvalue
END FUNCTION
end subroutine
!*******************************************************************************************
However, despite the function being flat and DUVMIF seeming to find a minimum, I am receiving an error 1 from using DUVMIF, see the following output: Output
I am unsure why this error is occurring as it seems DUVMIF has arrived in a reasonably precise neighborhood. I am new to Fortran and any guidance is appreciate.
Thanks.
I have tried altering the arguments of DUVMIF to use different thresholds of accuracy and it seems to not resolve the issue. I am expecting DUVMIF to settle in the region described in the last five rows of the output in the image posted before throwing the error.
The error codes for the UVMIF routines from the IMSL library are in the manual page https://help.imsl.com/fortran/6.0/math/uvmif.htm linked in the comments section by PierU. Please note that they are described as "Informational errors":
Informational errors
Type Code
3 1 Computer rounding errors prevent further refinement of X.
3 2 The final value of X is at a bound. The minimum is probably beyond the bound.
4 3 The number of function evaluations has exceeded MAXFN.
In this case for "Computer rounding errors prevent further refinement of X." it simply means that the algorithm cannot get any more refined value of X. If you apply the algorithm to get a new value, you will get the same value. What you get is the final answer from the algorithm and you will not get anything more precise unless you get a version of the subroutine with a higher floating point precision. The library offers single and double precision and since you are already using double precision, there is no higher precision version available.