C  *DECK OPTMZ2
C     SUBROUTINE OPTMZ2 IS CALLED BY OPTMIZ WHEN MAXIMIZING THE
C     LOG-LIKELIHOOD FUNCTION.
C     FUNCTION            - THIS IS A NUCLEUS CALLED ONLY BY
C                           SUBROUTINE OPTMIZ.
C     PRECISION           - SINGLE
C     LANGUAGE            - FORTRAN
C
C     ******************************************************************
C
      SUBROUTINE OPTMZ2 (A,N,Z,SIG,W,IR,MK,EPS)
      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
      DOUBLE PRECISION A(*), Z(N), W(N), SIG, EPS, ZERO, ONE, FOUR, TI,
     1 V, TIM, AL, R, B, GM, Y
      INTEGER N,IR,MK,I,J,II,JJ,IJ,MM
      DATA ZERO /0.0D0/, ONE /1.0D0/, FOUR /4.0D0/
C                                  UPDATE FACTORS GIVEN IN A
C                                    SIG*Z*Z-TRANSPOSE IS ADDED
      IF (N.GT.1) GO TO 10
C                                  N .EQ. 1
      A(1)=A(1)+SIG*Z(1)*Z(1)
      IR=1
      IF (A(1).GT.ZERO) GO TO 240
      A(1)=ZERO
      IR=0
      GO TO 240
C                                  N .GT. 1
   10 IF (SIG.GT.ZERO) GO TO 130
      IF (SIG.EQ.ZERO.OR.IR.EQ.0) GO TO 240
      TI=ONE/SIG
      JJ=0
      IF (MK.EQ.0) GO TO 30
C                                  L*W = Z ON INPUT
      DO 20 J=1,N
      JJ=JJ+J
      IF (A(JJ).NE.ZERO) TI=TI+(W(J)*W(J))/A(JJ)
   20 CONTINUE
      GO TO 80
C                                  SOLVE L*W = Z
   30 DO 40 J=1,N
      W(J)=Z(J)
   40 CONTINUE
      DO 70 J=1,N
      JJ=JJ+J
      V=W(J)
      IF (A(JJ).GT.ZERO) GO TO 50
      W(J)=ZERO
      GO TO 70
   50 TI=TI+(V*V)/A(JJ)
      IF (J.EQ.N) GO TO 70
      IJ=JJ
      DO 60 I=J+1,N
      IJ=IJ+I-1
      W(I)=W(I)-V*A(IJ)
   60 CONTINUE
   70 CONTINUE
C                                  SET TI, TIM AND W
   80 IF (IR.LE.0) GO TO 90
      IF (TI.GT.ZERO) GO TO 100
      IF (MK-1) 130,130,110
   90 TI=ZERO
      IR=-IR-1
      GO TO 110
  100 TI=EPS/SIG
      IF (EPS.EQ.ZERO) IR=IR-1
  110 TIM=TI
      II=JJ
      I=N
      DO 120 J=1,N
      IF (A(II).NE.ZERO) TIM=TI-(W(I)*W(I))/A(II)
      W(I)=TI
      TI=TIM
      II=II-I
      I=I-1
  120 CONTINUE
      MM=1
      GO TO 140
  130 MM=0
      TIM=ONE/SIG
  140 JJ=0
C                                  UPDATE A
      DO 220 J=1,N
      JJ=JJ+J
      IJ=JJ
C                                  UPDATE A(J,J)
      V=Z(J)
      IF (A(JJ).GT.ZERO) GO TO 170
C                                  A(J,J) .EQ. ZERO
      IF (IR.GT.0.OR.SIG.LT.ZERO.OR.V.EQ.ZERO) GO TO 160
      IR=1-IR
      A(JJ)=(V*V)/TIM
      IF (J.EQ.N) GO TO 240
      DO 150 I=J+1,N
      IJ=IJ+I-1
      A(IJ)=Z(I)/V
  150 CONTINUE
      GO TO 240
  160 TI=TIM
      GO TO 220
C                                  A(J,J) .GT. ZERO
  170 AL=V/A(JJ)
      TI=W(J)
      IF (MM.EQ.0) TI=TIM+V*AL
      R=TI/TIM
      A(JJ)=R*A(JJ)
      IF (R.EQ.ZERO) GO TO 230
      IF (J.EQ.N) GO TO 230
C                                  UPDATE REMAINDER OF COLUMN J
      B=AL/TI
      IF (R.GT.FOUR) GO TO 190
      DO 180 I=J+1,N
      IJ=IJ+I-1
      Z(I)=Z(I)-V*A(IJ)
      A(IJ)=A(IJ)+B*Z(I)
  180 CONTINUE
      GO TO 210
  190 GM=TIM/TI
      DO 200 I=J+1,N
      IJ=IJ+I-1
      Y=A(IJ)
      A(IJ)=B*Z(I)+Y*GM
      Z(I)=Z(I)-V*Y
  200 CONTINUE
  210 TIM=TI
  220 CONTINUE
  230 IF (IR.LT.0) IR=-IR
  240 CONTINUE
      RETURN
      END
