      SUBROUTINE QR2NOZ(NM, N, LOW, IGH, H, WR, WI, IERR)               QR2   10
C PURPOSE
C THE FORTRAN SUBROUTINE QR2NOZ COMPUTES THE EIGENVALUES OF A REAL
C      UPPER HESSENBERG MATRIX USING THE QR METHOD AND REDUCES THE
C      MATRIX TO A STANDARDIZED QUASI-TRIANGULAR FORM.  COMPUTATIONS
C      ARE DONE IN REAL ARITHMETIC.
C THE SUBROUTINE STATEMENT IS
C    SUBROUTINE QR2NOZ(NM,N,LOW,IGH,H,WR,WI,IERR).
C NM       IS AN INTEGER INPUT VARIABLE SET EQUAL TO THE ROW DIMENSION
C          OF THE ARRAY H AS SPECIFIED IN THE CALLING PROGRAM.
C N        IS AN INTEGER INPUT VARIABLE SET EQUAL TO THE ORDER OF THE
C          MATRIX H.  N  .LE.  NM
C LOW,IGH  ARE INTEGER INPUT VARIABLES INDICATING THE BOUNDARY INDICES
C          FOR THE BALANCED MATRIX.  IF THE MATRIX IS NOT BALANCED SET
C          LOW TO 1 AND IGH TO N.
C H        IS A REAL TWO-DIMENSIONAL ARRAY WITH ROW DIMENSION NM AND
C          COLUMN DIMENSION AT LEAST N.  ON INPUT IT CONTAINS THE
C          UPPER HESSENBERG MATRIX OF ORDER N.  ON OUTPUT IT CONTAINS
C          THE STANDARDIZED QUASI-TRIANGULAR MATRIX.
C WR,WI    ARE REAL OUTPUT ONE-DIMENSIONAL VARIABLES OF DIMENSION AT
C          LEAST N CONTAINING THE REAL AND IMAGINARY PARTS,
C          RESPECTIVELY, OF THE EIGENVALUES OF THE HESSENBERG MATRIX.
C          THE EIGENVALUES ARE UNORDERED EXCEPT THAT COMPLEX CONJUGATE
C          PAIRS OF EIGENVALUES APPEAR CONSECUTIVELY WITH THE
C          EIGENVALUE HAVING THE POSITIVE IMAGINARY PART FIRST.
C IERR     IS AN INTEGER OUTPUT VARIABLE SET EQUAL TO AN ERROR
C          COMPLETION CODE.  IF MORE THAN 30 ITERATIONS ARE REQUIRED
C          TO DETERMINE AN EIGENVALUE, THIS SUBROUTINE TERMINATES WITH
C          IERR SET EQUAL TO THE INDEX OF THE EIGENVALUE FOR WHICH
C          FAILURE OCCURS.  THE EIGENVALUES IN THE WR AND WI ARRAYS
C          SHOULD BE CORRECT FOR INDICES  IERR+1,IERR+2,...,N.  IF ALL
C          THE EIGENVALUES ARE DETERMINED WITHIN 30 ITERATIONS, IERR
C          IS SET TO ZERO.
      DIMENSION H(NM,N), WR(N), WI(N)
      REAL MACHEP
      INTEGER EN, ENM2
      LOGICAL NOTLAS
C MACHEP IS A MACHINE DEPENDENT PARAMETER SPECIFYING THE RELATIVE
C PRECISION OF FLOATING POINT ARITHMETIC.  THE VALUE BELOW IS
C EQUAL TO 2.**(-46), WHICH IS APPROPRIATE FOR CDC 6000-SERIES
C MACHINES.
      DATA MACHEP /16424000000000000000B/
      IERR = 0
C STORE ROOTS ISOLATED BY BALANC
      DO 10 I=1,N
        IF (I.GE.LOW .AND. I.LE.IGH) GO TO 10
        WR(I) = H(I,I)
        WI(I) = 0.0
   10 CONTINUE
      EN = IGH
      T = 0.0
C SEARCH FOR NEXT EIGENVALUES
   20 IF (EN.LT.LOW) RETURN
      ITS = 0
      NA = EN - 1
      ENM2 = NA - 1
C LOOK FOR SINGLE SMALL SUB-DIAGONAL ELEMENT
C    FOR L=EN STEP -1 UNTIL LOW DO
   30 IF (EN.EQ.LOW) GO TO 50
      DO 40 LL=LOW,NA
        L = EN + LOW - LL
        IF (ABS(H(L,L-1)).LE.MACHEP*(ABS(H(L-1,L-1))+ABS(H(L,L))))
     *   GO TO 60
   40 CONTINUE
   50 L = LOW
C FORM SHIFT
   60 X = H(EN,EN)
      IF (L.EQ.EN) GO TO 200
      Y = H(NA,NA)
      W = H(EN,NA)*H(NA,EN)
      IF (L.EQ.NA) GO TO 210
      IF (ITS.EQ.30) GO TO 270
      IF (ITS.NE.10 .AND. ITS.NE.20) GO TO 80
C FORM EXCEPTIONAL SHIFT
      T = T + X
      DO 70 I=LOW,EN
        H(I,I) = H(I,I) - X
   70 CONTINUE
      S = ABS(H(EN,NA)) + ABS(H(NA,ENM2))
      X = 0.75*S
      Y = X
      W = -0.4275*S*S
   80 ITS = ITS + 1
C LOOK FOR TWO CONSECUTIVE SMALL SUB-DIAGONAL
C  ELEMENTS.  FOR M=EN-2 STEP -1 UNTIL L DO
      DO 90 MM=L,ENM2
        M = ENM2 + L - MM
        ZZ = H(M,M)
        R = X - ZZ
        S = Y - ZZ
        P = (R*S-W)/H(M+1,M) + H(M,M+1)
        Q = H(M+1,M+1) - ZZ - R - S
        R = H(M+2,M+1)
        S = ABS(P) + ABS(Q) + ABS(R)
        P = P/S
        Q = Q/S
        R = R/S
        IF (M.EQ.L) GO TO 100
        IF (ABS(H(M,M-1))*(ABS(Q)+ABS(R)).LE.MACHEP*ABS(P)*
     *   (ABS(H(M-1,M-1))+ABS(ZZ)+ABS(H(M+1,M+1)))) GO TO 100
   90 CONTINUE
  100 MP2 = M + 2
      DO 110 I=MP2,EN
        H(I,I-2) = 0.0
        IF (I.EQ.MP2) GO TO 110
        H(I,I-3) = 0.0
  110 CONTINUE
C DOUBLE QR STEP INVOLVING ROWS L TO EN
C   AND COLUMNS M TO EN.
      DO 190 K=M,NA
        NOTLAS = K.NE.NA
        IF (K.EQ.M) GO TO 120
        P = H(K,K-1)
        Q = H(K+1,K-1)
        R = 0.0
        IF (NOTLAS) R = H(K+2,K-1)
        X = ABS(P) + ABS(Q) + ABS(R)
        IF (X.EQ.0.0) GO TO 190
        P = P/X
        Q = Q/X
        R = R/X
  120   S = SIGN(SQRT(P*P+Q*Q+R*R),P)
        IF (K.EQ.M) GO TO 130
        H(K,K-1) = -S*X
        GO TO 140
  130   IF (L.NE.M) H(K,K-1) = -H(K,K-1)
  140   P = P + S
        X = P/S
        Y = Q/S
        ZZ = R/S
        Q = Q/P
        R = R/P
C ROW MODIFICATION
        DO 160 J=K,N
          P = H(K,J) + Q*H(K+1,J)
          IF (.NOT.NOTLAS) GO TO 150
          P = P + R*H(K+2,J)
          H(K+2,J) = H(K+2,J) - P*ZZ
  150     H(K+1,J) = H(K+1,J) - P*Y
          H(K,J) = H(K,J) - P*X
  160   CONTINUE
        J = MIN0(EN,K+3)
C COLUMN MODIFICATION
        DO 180 I=1,J
          P = X*H(I,K) + Y*H(I,K+1)
          IF (.NOT.NOTLAS) GO TO 170
          P = P + ZZ*H(I,K+2)
          H(I,K+2) = H(I,K+2) - P*R
  170     H(I,K+1) = H(I,K+1) - P*Q
          H(I,K) = H(I,K) - P
  180   CONTINUE
  190 CONTINUE
      GO TO 30
C ONE ROOT FOUND
  200 H(EN,EN) = X + T
      WR(EN) = H(EN,EN)
      WI(EN) = 0.0
      EN = NA
      GO TO 20
C TWO ROOTS FOUND
  210 P = (Y-X)/2.0
      Q = P*P + W
      ZZ = SQRT(ABS(Q))
      H(EN,EN) = X + T
      X = H(EN,EN)
      H(NA,NA) = Y + T
      IF (Q.LT.0.0) GO TO 220
      ZZ = P + SIGN(ZZ,P)
C REAL PAIR
      WR(NA) = X + ZZ
      WR(EN) = WR(NA)
      IF (ZZ.NE.0.0) WR(EN) = X - W/ZZ
      WI(NA) = 0.0
      WI(EN) = 0.0
      X = H(EN,NA)
      R = SQRT(X*X+ZZ*ZZ)
      P = X/R
      Q = ZZ/R
      GO TO 230
C COMPLEX PAIR
  220 WR(NA) = X + P
      WR(EN) = X + P
      WI(NA) = ZZ
      WI(EN) = -ZZ
C MAKE DIAGONAL ELEMENTS EQUAL
      IF (P.EQ.0.0) GO TO 260
      BPC = H(EN,NA) + H(NA,EN)
      TX = SQRT(BPC*BPC+4.0*P*P)
      Q = SQRT(.5*(1.0+ABS(BPC)/TX))
      P = SIGN(P/(Q*TX),-BPC*P)
C ROW MODIFICATION
  230 DO 240 J=NA,N
        ZZ = H(NA,J)
        H(NA,J) = Q*ZZ + P*H(EN,J)
        H(EN,J) = Q*H(EN,J) - P*ZZ
  240 CONTINUE
C COLUMN MODIFICATION
      DO 250 I=1,N
        ZZ = H(I,NA)
        H(I,NA) = Q*ZZ + P*H(I,EN)
        H(I,EN) = Q*H(I,EN) - P*ZZ
  250 CONTINUE
  260 EN = ENM2
      GO TO 20
  270 IERR = EN
      RETURN
      END
      SUBROUTINE CONDIT(NM, N, A, V1, V2, WI, COND)                     CON   10
C  CONDIT COMPUTES THE CONDITION NUMBERS OF THE EIGENVALUES OF A
C      STANDARDIZED QUASI-TRIANGULAR MATRIX.
C  THE SUBROUTINE STATEMENT IS
C                SUBROUTINE CONDIT(NM,N,A,V1,V2,WI,COND).
C  ON INPUT
C    NM     MUST BE SET TO THE ROW DIMENSION OF THE TWO DIMENSIONAL
C           ARRAY AS DECLARED IN THE CALLING PROGRAM.
C    N      IS THE ORDER OF THE MATRIX.  N.LE.NM
C    A      CONTAINS THE STANDARDIZED QUASI-TRIANGULAR MATRIX PRODUCED
C           BY QR2NOZ.
C    WI     CONTAINS THE IMAGINARY PARTS OF THE EIGENVALUES.  THE
C           EIGENVALUES ARE UNORDERED EXCEPT THAT COMPLEX CONJUGATE
C           PAIRS APPEAR CONSECUTIVELY.
C    V1,V2  ARE FOR TEMPORARY STORAGE.
C  ON OUTPUT
C    A      IS UNALTERED.
C    COND   CONTAINS THE CONDITION NUMBERS CORRESPONDING TO THE
C           EIGENVALUES IN (V2,WI).  COND = 1./TOL IF THE USUAL
C           FORMULA WOULD CAUSE OVERFLOW OR YIELD A VALUE EXCEEDING
C           1/TOL.  TOL NEED NOT DEPEND ON THE COMPUTER.
C    V2     CONTAINS THE REAL PARTS OF THE EIGENVALUES.
C                     TYPICAL USAGE
C      DIMENSION A(50,50),WR(50),WI(50),COND(50),ORT(50)
C *******************ENTER MATRIX A AND DIMENSIONS N,NM*****************
C      LOW=1
C      IGH=N
C      CALL ORTHES(NM,N,LOW,IGH,A,ORT)
C      CALL QR2NOZ(NM,N,LOW,IGH,A,WR,WI,IERR)
C      CALL CONDIT(NM,N,A,ORT,WR,WI,COND)
C **********************************************************************
C  NOTE THE USE OF ORT AND WR IN CONDIT
      DIMENSION A(NM,NM), V1(NM), V2(NM), WI(NM), COND(NM)
      DIMENSION R1(2), R2(2)
      DATA TOL /1.E-30/
C ----------------------------------------------------------------------
      I = 1
   10 IF (I.GT.N) GO TO 190
      VALR = A(I,I)
      VALI = WI(I)
      VALI2 = VALI*VALI
C NJ GIVES EIGENVECTOR TYPE, 0 FOR COLUMN, 1 FOR ROW
      NJ = 0
C INITIALIZE NONZERO ELEMENTS OF EIGENVECTOR (V1,V2)
      V1(I) = 1.0
      V2(I) = 0.0
   20 J = I - 1 + 2*NJ
      IF (VALI.EQ.0.0) GO TO 30
      V2(I+1) = VALI/A(I,I+1)
      V1(I+1) = 0.0
      IF (NJ.EQ.1) V2(I+1) = 1.0/V2(I+1)
      J = I - 1 + 3*NJ
C FIND THE INDICES OF ELEMENTS COMPUTED SO FAR
   30 KS = J + 1 + NJ*(I-J-1)
      KF = I + 1 + NJ*(J-I-2)
      IF (VALI.EQ.0.0 .AND. NJ.EQ.0) KF = KF - 1
C TEST FOR COMPLETION OF EIGENVECTOR
      IF ((J+NJ.LT.1) .OR. (J+NJ.GT.N+1)) GO TO 130
C **********************************************************************
C *SOLVE -D*V + V*E = R FOR V = (V1,V2).  D IS A DIAGONAL BLOCK IN ROWS
C * J1,J2, AND E IS THE REAL CANONICAL FORM OF THE ITH EIGENVALUE.
C * EITHER D OR E OR BOTH CAN BE  1 BY 1
C **********************************************************************
C  FIND J1 AND J2 (J1.LE.J2) FOR ALL CASES
      JJ = J
      IF (WI(J).NE.0.0) JJ = J - 1 + 2*NJ
      J0 = NJ*(J-JJ)
      J1 = JJ + J0
      J2 = J - J0
      D1 = VALR - A(J,J)
C CALCULATE RIGHT HAND SIDE R
      DO 70 L=J1,J2
        LJ = L - J1 + 1
        R1(LJ) = 0.0
        R2(LJ) = 0.0
        IF (VALI.NE.0.0) GO TO 50
        DO 40 K=KS,KF
          LK = NJ*(K-L)
          AA = A(L+LK,K-LK)
          R1(LJ) = R1(LJ) + AA*V1(K)
   40   CONTINUE
        GO TO 70
   50   DO 60 K=KS,KF
          LK = NJ*(K-L)
          AA = A(L+LK,K-LK)
          R1(LJ) = R1(LJ) + AA*V1(K)
          R2(LJ) = R2(LJ) + AA*V2(K)
   60   CONTINUE
   70 CONTINUE
      IF (JJ.NE.J) GO TO 100
C *****************************D IS 1 BY 1 *****************************
      IF (VALI.NE.0.0) GO TO 80
C E IS 1 BY 1 (D IS 1 BY 1)
      IF (ABS(D1).LT.TOL*ABS(R1(1))) GO TO 180
      V1(J) = 0.0
      V2(J) = 0.0
      IF (D1.NE.0.0) V1(J) = R1(1)/D1
      GO TO 90
C E IS 2 BY 2 ( D IS 1 BY 1 )
   80 DEN = D1*D1 + VALI2
      VAL = VALI*(-1.0)**NJ
      V1(J) = R1(1)*D1 + R2(1)*VAL
      V2(J) = R2(1)*D1 - R1(1)*VAL
      VMAX = AMAX1(ABS(V1(J)),ABS(V2(J)))
      IF (DEN.LT.TOL*VMAX) GO TO 180
      V1(J) = V1(J)/DEN
      V2(J) = V2(J)/DEN
C NEXT J
   90 J = J - 1 + 2*NJ
      GO TO 30
C ********************************D IS 2 BY 2***************************
  100 IF (VALI.NE.0.0) GO TO 110
C E IS 1 BY 1 (D IS 2 BY 2)
      DEN = D1*D1 + WI(J)**2
      V2(J1) = 0.0
      V2(J2) = 0.0
      V1(J1) = R1(1)*D1 + R1(2)*A(JJ,J)
      V1(J2) = R1(1)*A(J,JJ) + R1(2)*D1
      VMAX = AMAX1(ABS(V1(J1)),ABS(V1(J2)))
      IF (DEN.LT.TOL*VMAX) GO TO 180
      V1(J1) = V1(J1)/DEN
      V1(J2) = V1(J2)/DEN
      GO TO 120
C E IS 2 BY 2 (D IS 2 BY 2).  CLOSED FORM SOLUTION
  110 B = A(JJ,J)
      C = A(J,JJ)
      VAL = VALI*(-1.0)**NJ
      BXC = B*C
      H = D1*D1 + VALI2 - BXC
      E = D1*H
      F = VAL*(H+2.0*BXC)
      G = H - 2.0*VALI2
      H = 2.0*D1*VAL
      V1(J1) = R1(1)*E + R2(1)*F + R1(2)*B*G + R2(2)*B*H
      V2(J1) = -R1(1)*F + R2(1)*E - R1(2)*B*H + R2(2)*B*G
      V1(J2) = R1(1)*C*G + R2(1)*C*H + R1(2)*E + R2(2)*F
      V2(J2) = -R1(1)*C*H + R2(1)*C*G - R1(2)*F + R2(2)*E
      VMAX = AMAX1(ABS(V1(J1)),ABS(V2(J1)),ABS(V1(J2)),ABS(V2(J2)))
      DEN = G*G + H*H
      IF (DEN.LT.TOL*VMAX) GO TO 180
      IF (DEN.EQ.0.0) GO TO 120
      V1(J1) = V1(J1)/DEN
      V2(J1) = V2(J1)/DEN
      V1(J2) = V1(J2)/DEN
      V2(J2) = V2(J2)/DEN
C NEXT J
  120 J = J - 2 + 4*NJ
      GO TO 30
C COMPUTE EIGENVECTOR NORM
  130 VMAX = 0.0
      DO 140 K=KS,KF
        VMAX = VMAX + V1(K)**2 + V2(K)**2
  140 CONTINUE
      IF (NJ.EQ.1) GO TO 150
C PREPARE TO COMPUTE ROW EIGENVECTOR
      NJ = 1
      CNORM2 = VMAX
      GO TO 20
C COMPUTE CONDITION NUMBER
  150 COND(I) = SQRT(CNORM2*VMAX)
  160 IF (VALI.EQ.0.0) GO TO 170
      COND(I) = COND(I)/2.0
      COND(I+1) = COND(I)
      I = I + 1
C NEXT I
  170 I = I + 1
      GO TO 10
C DEFECTIVE CASE
  180 COND(I) = 1.0/TOL
      GO TO 160
C PLACE REAL PART OF EIGENVALUE IN V2
  190 DO 200 I=1,N
        V2(I) = A(I,I)
  200 CONTINUE
      RETURN
      END
