Search code examples
fortran

DUVMIF Fortran Error 1 Computer Rounding Error


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.


Solution

  • 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.