      SUBROUTINE LOCMIN(M,X,N,P,SSQ,ALF,EFS,ITRAP,ESCF)
      implicit double precision (A-H,O-Z)
      include 'SIZES'
      include 'MOP6FILE'
      common /NLLSQI/ NCOUNT
      common /KEYWRD/ CONTRL
      common /NUMCAL/ NUMCAL
      dimension X(*), P(*), EFS(*)
      dimension CONST(MAXPAR), XSTOR(MAXPAR), GSTOR(MAXPAR)
      dimension PHI(3),VT(3)
      INTEGER LEFT,RIGHT,CENTER
      character*241 KEYWRD, CONTRL
      logical FIRST, DEBUG, LOWER
      save XMAXM, SCALE, FIRST, KEYWRD, EPS, DEBUG, TEE, YMAXST, XCRIT
      save MXCNT2, IPRINT, CONST
      data CONST/MAXPAR*1.D0/, FIRST /.TRUE./
      data ICALCN/0/
************************************************************************
*
*    LOCMIN IS CALLED BY NLLSQ ONLY. IT IS A LINE-SEARCH PROCEDURE FOR
*    LOCATING A MINIMUM IN THE FUNCTION SPACE OF COMPFG.  SEE NLLSQ
*    FOR MORE DETAILS
*
************************************************************************
      if (ICALCN.NE.NUMCAL) then
         ICALCN=NUMCAL
         XMAXM=1.D9
         SCALE=1.D0
         KEYWRD=CONTRL
C
C THE ABOVE LINE IS TO TRY TO PREVENT OVERFLOW IN NLLSQ
C
         EPS=1.D-5
         DEBUG=(INDEX(KEYWRD,'LINMIN') .NE. 0)
         TEE=1.D-2
         YMAXST=0.005D0
         XCRIT=0.0002D0
         MXCNT2=30
         IPRINT=0
         if (DEBUG) IPRINT=-1
      end if
      XMAXM=1.D-11
      do 10 I=1,N
   10 XMAXM=MAX(XMAXM,ABS(P(I)))
      XMINM=XMAXM*SCALE
      XMAXM=YMAXST/XMAXM/SCALE
      FIN = SSQ
      LOWER = .FALSE.
      T=ALF
      PHI(1) = SSQ
      VT(1) = 0.0D0
      VT(2) = T/4.0D0
      if (VT(2).GT.XMAXM) VT(2)=XMAXM
      T = VT(2)
      do 20 I=1,N
   20 X(I) = X(I)+T*P(I)*CONST(I)*SCALE
      call COMPFG(X,.TRUE.,ESCF,.TRUE.,EFS,.TRUE.)
      PHI(2)=DOT(EFS,EFS,N)
      call EXCHNG(PHI(2),SQSTOR,ENERGY,ESTOR,X,XSTOR,T,ALFS,N)
      do 30 I=1,M
   30 GSTOR(I)=EFS(I)
      if (PHI(1) .LE. PHI(2)) then
         VT(3) = -VT(2)
         LEFT = 3
         CENTER = 1
         RIGHT = 2
      else
         VT(3)=2.0D0*VT(2)
         LEFT = 1
         CENTER = 2
         RIGHT = 3
      end if
      TLAST = VT(3)
      T = TLAST-T
      do 40 I=1,N
   40 X(I) = X(I)+T*P(I)*CONST(I)*SCALE
      FLAST=PHI(2)
      call COMPFG(X,.TRUE.,ESCF,.TRUE.,EFS,.TRUE.)
      F=DOT(EFS,EFS,N)
      if (F.LT.SQSTOR) call EXCHNG(F,SQSTOR,ENERGY,ESTOR,X,
     1                            XSTOR,T,ALFS,N)
      do 50 I=1,M
   50 GSTOR(I)=EFS(I)
      if (F.LT.FIN) LOWER = .TRUE.
      NCOUNT = NCOUNT+2
      PHI(3) = F
      if (IPRINT) 60,70,70
   60 write(MIOB,310) VT(1),PHI(1),VT(2),PHI(2),VT(3),PHI(3)
   70 MXCT=MXCNT2
      do 250 ICTR=3,MXCT
         XMAXM=XMAXM*3.D0
         ALPHA = VT(2) - VT(3)
         BETA = VT(3) - VT(1)
         GAMMA = VT(1)-VT(2)
         if (ALPHA.EQ.0.D0) ALPHA=1.D-20
         if (BETA.EQ.0.D0)  BETA=1.D-20
         if (GAMMA.EQ.0.D0) GAMMA=1.D-20
         ABG =-(PHI(1)*ALPHA+PHI(2)*BETA+PHI(3)*GAMMA)/ALPHA
         ABG=ABG/BETA
         ABG=ABG/GAMMA
         ALPHA=ABG
         BETA = ((PHI(1)-PHI(2))/GAMMA)-ALPHA*(VT(1)+VT(2))
         if (ALPHA)  80,80,110
   80    if (PHI(RIGHT) .GT. PHI(LEFT))  go to 90
         T = 3.0D0*VT(RIGHT)-2.0D0*VT(CENTER)
         go to 100
   90    T = 3.0D0*VT(LEFT)-2.0D0*VT(CENTER)
  100    S=T-TLAST
         T=S+TLAST
         go to 150
  110    T = -BETA/(2.0D0*ALPHA)
         S=T-TLAST
         if (S) 120,260,130
  120    AMDIS=VT(LEFT)-TLAST-XMAXM
         go to 140
  130    AMDIS=VT(RIGHT)-TLAST+XMAXM
  140    if (ABS(S).GT.ABS(AMDIS)) S=AMDIS
         T=S+TLAST
  150    continue
         if (ICTR.GT.3.AND.ABS(S*XMINM).LT.XCRIT) then
            if ( DEBUG )
     1    write(MIOB,'('' EXIT DUE TO SMALL PROJECTED STEP'')')
            go to 260
         end if
         T=S+TLAST
         do 160 I=1,N
  160    X(I) = X(I)+S*P(I)*CONST(I)*SCALE
         FLAST=F
         call COMPFG(X,.TRUE.,ESCF,.TRUE.,EFS,.TRUE.)
         F=DOT(EFS,EFS,N)
         if (F.LT.SQSTOR) call EXCHNG(F,SQSTOR,ENERGY,ESTOR,X,XSTOR,
     1                                                     T,ALFS,N)
         do 170 I=1,M
  170    GSTOR(I)=EFS(I)
         if (F.LT.FIN) LOWER = .TRUE.
         NCOUNT = NCOUNT+1
         if (IPRINT) 180,190,190
  180    write(MIOB,320) VT(LEFT),PHI(LEFT),VT(CENTER),PHI(CENTER),
     %                   VT(RIGHT),PHI(RIGHT),T,F
  190    continue
C
C    TEST FOR EXCITED STATES AND POTHOLES
C
         ITRAP=0
         if (ABS(VT(CENTER)).GT.1.D-10) go to 200
         if (ABS(T)/(ABS(VT(LEFT))+1.D-15).GT.0.3333) go to 200
         if (2.5D0*F-PHI(RIGHT)-PHI(LEFT).LT.0.5D0*PHI(CENTER))
     1                    go to 200
C
C   WE ARE STUCK ON A FALSE MINIMUM
C
         ITRAP=1
         go to 260
  200    continue
*
* NOW FOR THE MAIN stopPING TESTS.  LOCMIN WILL STOP IF:-
*     THE ERROR FUNCTION HAS BEEN REDUCED, AND
*     THE RATE OF DROP OF THE ERROR FUNCTION IS LESS THAN 0.5% PER STEP
*     AND
*     (A) THE RATIO OF THE PROPOSED STEP TO THE TOTAL STEP IS LESS THAN
*         EPS,   OR
*     (B) THE LAST DROP IN ERROR FUNCTION WAS LESS THAN 5%OFTHETOTALDROP
*         DURING THIS call TO LOCMIN.
*
         if (DEBUG) write(MIOB,'('' F/FLAST'',F13.6)') F/FLAST
         if ( LOWER  .AND. F/FLAST .GT. 0.995D0) then
            if ((ABS(T-TLAST).LE.EPS*ABS(T+TLAST)+TEE)) then
               if ( DEBUG )
     1       write(MIOB,'('' EXIT AS STEP IS ABSOLUTELY SMALL '')')
               go to 260
            end if
            SUM=MIN(ABS(F-PHI(1)),ABS(F-PHI(2)),ABS(F-PHI(3)))
            SUM2=(FIN-SQSTOR)*0.05D0
            if (SUM .LT. SUM2) then
               if ( DEBUG )
     1        write(MIOB,'('' EXIT DUE TO HAVING REACHED BOTTOM'')')
               go to 260
            end if
         end if
         TLAST = T
         if ((T .GT. VT(RIGHT)) .OR. (T .GT. VT(CENTER) .AND. F .LT.
     1  PHI(CENTER)) .OR. (T .GT. VT(LEFT) .AND. T .LT. VT(CENTER) .AND.
     2  F .GT. PHI(CENTER)))  go to 210
         VT(RIGHT) = T
         PHI(RIGHT) = F
         go to 220
  210    VT(LEFT) = T
         PHI(LEFT) = F
  220    if (VT(CENTER) .LT. VT(RIGHT))  go to 230
         I = CENTER
         CENTER = RIGHT
         RIGHT = I
  230    if (VT(LEFT) .LT. VT(CENTER))  go to 240
         I = LEFT
         LEFT = CENTER
         CENTER = I
  240    if (VT(CENTER) .LT. VT(RIGHT))  go to 250
         I = CENTER
         CENTER = RIGHT
         RIGHT = I
  250 continue
  260 continue
      call EXCHNG(SQSTOR,F,ESTOR,ENERGY,XSTOR,X,ALFS,T,N)
      do 270 I=1,M
  270 EFS(I)=GSTOR(I)
      SSQ=(F)
      ALF=T
      if (T) 280,300,300
  280 T = -T
      do 290 I=1,N
  290 P(I) = -P(I)
  300 continue
      ALF=T
      return
  310 format(' ---LOCMIN'/5X,'LEFT   ...',2F19.6/5X,'CENTER ...',
     1  2F19.6/5X,'RIGHT  ...',2F19.6/' ')
  320 format(5X,'LEFT   ...',2F19.6/5X,'CENTER ...',2F19.6/5X,
     1  'RIGHT  ...',2F19.6/5X,'NEW    ...',2F19.6/' ')
      end
