*
* $Id$
*
* $Log$
* Revision 1.1  1996/03/07 14:31:28  mclareni
* Initial revision
*
*
#include "minuit/pilot.h"
      SUBROUTINE MNEIG(A,NDIMA,N,MITS,WORK,PRECIS,IFAULT)
#include "minuit/d506dp.inc"
C
      PARAMETER (ZERO=0.0,  ONE=1.0,   TWO=2.0)
      PARAMETER (TOL=1.0E-35)
      DIMENSION A(NDIMA,*),WORK(*)
C          PRECIS is the machine precision EPSMAC
      IFAULT = 1
C
      I = N
      DO 70 I1 = 2,N
      L = I-2
      F = A(I,I-1)
      GL = ZERO
C
      IF(L .LT. 1) GO TO 25
C
      DO 20 K = 1,L
   20 GL = GL+A(I,K)**2
   25 H = GL + F**2
C
      IF(GL .GT. TOL) GO TO 30
C
      WORK(I) = ZERO
      WORK(N+I) = F
      GO TO 65
   30 L = L+1
C
      GL = SQRT(H)
C
      IF(F .GE. ZERO) GL = -GL
C
      WORK(N+I) = GL
      H = H-F*GL
      A(I,I-1) = F-GL
      F = ZERO
      DO 50 J = 1,L
      A(J,I) = A(I,J)/H
      GL = ZERO
      DO 40 K = 1,J
   40 GL = GL+A(J,K)*A(I,K)
C
      IF(J .GE. L) GO TO 47
C
      J1 = J+1
      DO 45 K = J1,L
   45 GL = GL+A(K,J)*A(I,K)
   47 WORK(N+J) = GL/H
      F = F+GL*A(J,I)
   50 CONTINUE
      HH = F/(H+H)
      DO 60 J = 1,L
      F = A(I,J)
      GL = WORK(N+J)-HH*F
      WORK(N+J) = GL
      DO 60 K = 1,J
      A(J,K) = A(J,K)-F*WORK(N+K)-GL*A(I,K)
   60 CONTINUE
      WORK(I) = H
   65 I = I-1
   70 CONTINUE
      WORK(1) = ZERO
      WORK(N+1) = ZERO
      DO 110 I = 1,N
      L = I-1
C
      IF(WORK(I) .EQ. ZERO .OR. L .EQ. 0) GO TO 100
C
      DO 90 J = 1,L
      GL = ZERO
      DO 80 K = 1,L
   80 GL = GL+A(I,K)*A(K,J)
      DO 90 K = 1,L
      A(K,J) = A(K,J)-GL*A(K,I)
   90 CONTINUE
  100 WORK(I) = A(I,I)
      A(I,I) = ONE
C
      IF(L .EQ. 0) GO TO 110
C
      DO 105 J = 1,L
      A(I,J) = ZERO
      A(J,I) = ZERO
  105 CONTINUE
  110 CONTINUE
C
C
      N1 = N-1
      DO 130 I = 2,N
      I0 = N+I-1
  130 WORK(I0) = WORK(I0+1)
      WORK(N+N) = ZERO
      B = ZERO
      F = ZERO
      DO 210 L = 1,N
      J = 0
      H = PRECIS*(ABS(WORK(L))+ABS(WORK(N+L)))
C
      IF(B .LT. H) B = H
C
      DO 140 M1 = L,N
      M = M1
C
      IF(ABS(WORK(N+M)) .LE. B) GO TO 150
C
  140 CONTINUE
C
  150 IF(M .EQ. L) GO TO 205
C
  160 IF(J .EQ. MITS) RETURN
C
      J = J+1
      PT = (WORK(L+1)-WORK(L))/(TWO*WORK(N+L))
      R = SQRT(PT*PT+ONE)
      PR = PT+R
C
      IF(PT .LT. ZERO) PR=PT-R
C
      H = WORK(L)-WORK(N+L)/PR
      DO 170 I=L,N
  170 WORK(I) = WORK(I)-H
      F = F+H
      PT = WORK(M)
      C = ONE
      S = ZERO
      M1 = M-1
      I = M
      DO 200 I1 = L,M1
      J = I
      I = I-1
      GL = C*WORK(N+I)
      H = C*PT
C
      IF(ABS(PT) .GE. ABS(WORK(N+I))) GO TO 180
C
      C = PT/WORK(N+I)
      R = SQRT(C*C+ONE)
      WORK(N+J) = S*WORK(N+I)*R
      S = ONE/R
      C = C/R
      GO TO 190
  180 C = WORK(N+I)/PT
      R = SQRT(C*C+ONE)
      WORK(N+J) = S*PT*R
      S = C/R
      C = ONE/R
  190 PT = C*WORK(I)-S*GL
      WORK(J) = H+S*(C*GL+S*WORK(I))
      DO 200 K = 1,N
      H = A(K,J)
      A(K,J) = S*A(K,I)+C*H
      A(K,I) = C*A(K,I)-S*H
  200 CONTINUE
      WORK(N+L) = S*PT
      WORK(L) = C*PT
C
      IF(ABS(WORK(N+L)) .GT. B) GO TO 160
C
  205 WORK(L) = WORK(L)+F
  210 CONTINUE
      DO 240 I=1,N1
      K = I
      PT = WORK(I)
      I1 = I+1
      DO 220 J = I1,N
C
      IF(WORK(J) .GE. PT) GO TO 220
C
      K = J
      PT = WORK(J)
  220 CONTINUE
C
      IF(K .EQ. I) GO TO 240
C
      WORK(K) = WORK(I)
      WORK(I) = PT
      DO 230 J=1,N
      PT = A(J,I)
      A(J,I) = A(J,K)
      A(J,K) = PT
  230 CONTINUE
  240 CONTINUE
      IFAULT = 0
C
      RETURN
      END
