!+ Subroutine to locate minimum of residual polynommial.
!
! Method:
!	A golden search is used to find the minima between pairs 
!	of roots of the polynomial. The lowest minimum is selected.
!
! Current Owner of Code: J. M. Edwards
!
! History:
!	Version		Date			Comment
!	1.0		12-04-95		First Version under RCS
!						(J. M. Edwards)
!
! Description of Code:
!   FORTRAN 77  with extensions listed in documentation.
!
!- ---------------------------------------------------------------------
      SUBROUTINE LOCATE_MINIMUM(N_TERM, N_DATA
     &   , K, WEIGHT, RESIDUAL, U
     &   , K_MINIMUM, R_MINIMUM
     &   )
!
!
!
      IMPLICIT NONE
!
!
!     INCLUDE HEADER FILES.
      INCLUDE 'incl/dimensions_spec.ucf'
      INCLUDE 'incl/dimensions_pp.ucf'
!
!     DUMMY ARGUMENTS.
      INTEGER 	!, INTENT(IN)
     &     N_TERM                           
!             NUMBER OF ESFT TERMS
     &   , N_DATA                           
!             NUMBER OF DATA POINTS
      REAL*8 	!, INTENT(IN)
     &     WEIGHT(NPD_AMOUNT+1)         
!             WEIGHTS FOR TERMS
     &   , RESIDUAL(NPD_AMOUNT+1)       
!             RESIDUALS
     &   , U(NPD_AMOUNT+1)              
!             AMOUNT OF ABSORBER
     &   , K(NPD_ESFT_TERM)                   
!             ESFT EXPONENTS
      REAL*8 	!, INTENT(OUT)
     &     K_MINIMUM                        
!             K-VALUE OF MINIMUM
     &   , R_MINIMUM                        
!             MINIMUM VALUE
!
!     LOCAL ARGUMENTS.
      INTEGER
     &     I                                
!             LOOP VARIABLE
      REAL*8
     &     K_UPPER                          
!             UPPER BOUND FOR MINIMUM
     &   , K_MIDDLE                         
!             MIDDLE VALUE FOR MINIMUM
     &   , RESIDUAL_1                       
!             RESIDUAL VALUE
     &   , RESIDUAL_2                       
!             RESIDUAL VALUE
     &   , K_MINIMUM_TEMPORARY              
!             TEMPORARY POSITION OF MINIMUM
     &   , R_MINIMUM_TEMPORARY              
!             TEMPORARY VALUE OF MINIMUM
!
!     FUNCTIONS CALLED:
      REAL*8
     &     RESIDUAL_POLYNOMIAL
!             VALUE OF RESIDUAL POLYNOMIAL
     &   , GOLDEN
!             RESULT OF SEARCH BY GOLDEN SECTIONS
      EXTERNAL
     &     RESIDUAL_POLYNOMIAL, GOLDEN
!
!
!     INITIALIZE R_MINIMUM AND K_MINIMUM AND THEN BEGIN SEARCHING IN
!     THE REGION OF LARGE K.
      R_MINIMUM=0.0D+00
      K_MINIMUM=0.0D+00
!
!     THE ONLY ROOTS OF RESIDUAL_POLYNOMIAL=0 ARE AT THE K'S.
!     RESIDUAL_POLYNOMIAL TENDS TO 0 AT INFINITY. HENCE THERE IS
!     A MINIMUM ABOVE K(N_TERM) IF RESIDUAL_POLYNOMIAL IS
!     NEGATIVE IN THIS REGION.
      K_UPPER=2.0D+00*K(N_TERM)+1.0D+00
      RESIDUAL_2=RESIDUAL_POLYNOMIAL(N_DATA
     &   , WEIGHT, RESIDUAL, U, K_UPPER)
      IF (RESIDUAL_2.LT.0.0D+00) THEN
!        FIND A TRIPLE OF POINTS BRACKETING THE MINIMUM.
         K_MIDDLE=1.50D+00*K(N_TERM)+0.50D+00
         RESIDUAL_1=RESIDUAL_POLYNOMIAL(N_DATA
     &      , WEIGHT, RESIDUAL, U, K_MIDDLE
     &      )
100      IF (RESIDUAL_1.GT.RESIDUAL_2) THEN
!           THE FUNCTION IS STILL DECREASING.
            RESIDUAL_1=RESIDUAL_2
            K_MIDDLE=K_UPPER
            K_UPPER=K_UPPER+K(N_TERM)+0.50D+00
            RESIDUAL_2=RESIDUAL_POLYNOMIAL(N_DATA
     &         , WEIGHT, RESIDUAL, U, K_UPPER
     &         )
            GOTO 100
         ENDIF
!        THE MINIMUM LIES IN THE INTERVAL (K(N_TERM), K_UPPER)
         R_MINIMUM_TEMPORARY=GOLDEN(K(N_TERM), K_UPPER, K_MIDDLE
     &      , K_MINIMUM_TEMPORARY
     &      , N_DATA, WEIGHT, RESIDUAL, U
     &      )
         IF (R_MINIMUM_TEMPORARY.LT.R_MINIMUM) THEN
            R_MINIMUM=R_MINIMUM_TEMPORARY
            K_MINIMUM=K_MINIMUM_TEMPORARY
         ENDIF
      ENDIF
!
!     NOW WORK BACKWARDS TOWARDS 0, FINDING MINIMA.
!
      DO I=N_TERM, 2, -1
         K_MIDDLE=0.50D+00*(K(I)+K(I-1))
         R_MINIMUM_TEMPORARY=RESIDUAL_POLYNOMIAL(N_DATA
     &      , WEIGHT, RESIDUAL, U, K_MIDDLE)
         IF (R_MINIMUM_TEMPORARY.LT.0.0D+00) THEN
!           THERE IS A MINIMUM BETWEEN THIS K AND THE PREVIOUS ONE.
!           THE MINIMUM IS NOW RETURNED AS R_MINIMUM_TEMPORARY.
            R_MINIMUM_TEMPORARY=GOLDEN(K(I-1), K(I), K_MIDDLE
     &         , K_MINIMUM_TEMPORARY
     &         , N_DATA, WEIGHT, RESIDUAL, U
     &         )
            IF (R_MINIMUM_TEMPORARY.LT.R_MINIMUM) THEN
               R_MINIMUM=R_MINIMUM_TEMPORARY
               K_MINIMUM=K_MINIMUM_TEMPORARY
            ENDIF
         ENDIF
      ENDDO
!
!     IF THE RESIDUAL POLYNOMIAL IS NEGATIVE BETWEEN 0 AND K(1), 0
!     WILL GIVE WILL GIVE THE LOWEST VALUE OVER THIS INTERVAL.
      R_MINIMUM_TEMPORARY=RESIDUAL_POLYNOMIAL(N_DATA
     &   , WEIGHT, RESIDUAL, U, 0.0D+00)
      IF (R_MINIMUM_TEMPORARY.LT.R_MINIMUM) THEN
         R_MINIMUM=R_MINIMUM_TEMPORARY
         K_MINIMUM=0.0D+00
      ENDIF
!
!     THE NEW MINIMUM IS K_MINIMUM, WHICH IS ADDED TO THE LIST OF K'S.
!
!
      RETURN
      END
