SUBROUTINE WNLIT(W,MDW,M,N,L,IPIVOT,ITYPE,H,SCALE,RNORM,IDOPE,
     1   DOPE,DONE)
C***BEGIN PROLOGUE  WNLIT
C***REFER TO  WNNLS
C
C     This is a companion subprogram to WNNLS( ).
C     The documentation for WNNLS( ) has more complete
C     usage instructions.
C
C     Note  The M by (N+1) matrix W( , ) contains the rt. hand side
C           B as the (N+1)st col.
C
C     Triangularize L1 by L1 subsystem, where L1=MIN(M,L), with
C     col interchanges.
C     Revised March 4, 1982.
C***ROUTINES CALLED  H12,ISAMAX,SCOPY,SROTM,SROTMG,SSCAL,SSWAP
C***END PROLOGUE  WNLIT
C
C     THE EDITING REQUIRED TO CONVERT THIS SUBROUTINE FROM SINGLE TO
C     DOUBLE PRECISION INVOLVES THE FOLLOWING CHARACTER STRING CHANGES.
C     USE AN EDITING COMMAND (CHANGE) /STRING-1/(TO)STRING-2/.
C     (BEGIN CHANGES AT LINE WITH C++ IN COLS. 1-3.)
C     /REAL (12 BLANKS)/DOUBLE PRECISION/,/SCOPY/DCOPY/,/SROTM/DROTM/,
C     /SSCAL/DSCAL/,
C     /SSWAP/DSWAP/,/AMAX1/DMAX1/,/ISAMAX/IDAMAX/,/.E-/.D-/,/E0/D0/
C
C++
      USE setparms
c
      REAL             W(MDW,1), H(1), SCALE(1), DOPE(4), SPARAM(5)
      REAL             ALSQ, AMAX, EANORM, FAC, FACTOR, HBAR, ONE, RN
      REAL             RNORM, SN, T, TAU, TENM3, ZERO
      REAL             AMAX1
      INTEGER ITYPE(1), IPIVOT(1), IDOPE(8)
      integer(kind = int_single) ISAMAX,IDAMAX
      LOGICAL INDEP, DONE, RECALC
      DATA TENM3 /1.E-3/, ZERO /0.E0/, ONE /1.E0/
C
C***FIRST EXECUTABLE STATEMENT  WNLIT
      ME = IDOPE(1)
      MEP1 = IDOPE(2)
      KRANK = IDOPE(3)
      KRP1 = IDOPE(4)
      NSOLN = IDOPE(5)
      NIV = IDOPE(6)
      NIV1 = IDOPE(7)
      L1 = IDOPE(8)
C
      ALSQ = DOPE(1)
      EANORM = DOPE(2)
      FAC = DOPE(3)
      TAU = DOPE(4)
      NP1 = N + 1
      LB = MIN0(M-1,L)
      RECALC = .TRUE.
      RNORM = ZERO
      KRANK = 0
C     WE SET FACTOR=1.E0 SO THAT THE HEAVY WEIGHT ALAMDA WILL BE
C     INCLUDED IN THE TEST FOR COL INDEPENDENCE.
      FACTOR = 1.E0
      I = 1
      IP1 = 2
      LEND = L
   10 IF (.NOT.(I.LE.LB)) GO TO 150
C
C     SET IR TO POINT TO THE I-TH ROW.
      IR = I
      MEND = M
C      ASSIGN 20 TO IGO996
C     HRW: updated to remove assigned go-to.
      IGO996 = 20
      GO TO 460
C
C     UPDATE-COL-SS-AND-FIND-PIVOT-COL
C     20   ASSIGN 30 TO IGO993
C     HRW: updated to remove assigned go-to.
 20   IGO993 = 30 
      
      GO TO 560
C
C     PERFORM-COL-INTERCHANGE
C
C     SET IC TO POINT TO I-TH COL.
 30   IC = I
C     ASSIGN 40 TO IGO990
C     HRW: updated to remove assigned go-to.
      IGO990 = 40
      GO TO 520
C
C     TEST-INDEP-OF-INCOMING-COL
   40 IF (.NOT.(INDEP)) GO TO 110
C
C     ELIMINATE I-TH COL BELOW DIAG. USING MOD. GIVENS TRANSFORMATIONS
C     APPLIED TO (A B).
      J = M
      DO 100 JJ=IP1,M
        JM1 = J - 1
        JP = JM1
C     WHEN OPERATING NEAR THE ME LINE, USE THE LARGEST ELT.
C     ABOVE IT AS THE PIVOT.
        IF (.NOT.(J.EQ.MEP1)) GO TO 80
        IMAX = ME
        AMAX = SCALE(ME)*W(ME,I)**2
   50   IF (.NOT.(JP.GE.I)) GO TO 70
        T = SCALE(JP)*W(JP,I)**2
        IF (.NOT.(T.GT.AMAX)) GO TO 60
        IMAX = JP
        AMAX = T
   60   JP = JP - 1
        GO TO 50
   70   JP = IMAX
   80   IF (.NOT.(W(J,I).NE.ZERO)) GO TO 90
        CALL SROTMG(SCALE(JP), SCALE(J), W(JP,I), W(J,I), SPARAM)
        W(J,I) = ZERO
        CALL SROTM(NP1-I, W(JP,IP1), MDW, W(J,IP1), MDW, SPARAM)
   90   J = JM1
  100 CONTINUE
      GO TO 140
  110 CONTINUE
      IF (.NOT.(LEND.GT.I)) GO TO 130
C
C     COL I IS DEPENDENT. SWAP WITH COL LEND.
      MAX = LEND
C
C     PERFORM-COL-INTERCHANGE
C      ASSIGN 120 TO IGO993
C     HRW: updated to remove assigned go-to.
      IGO993 = 120
      GO TO 560
  120 CONTINUE
      LEND = LEND - 1
C
C     FIND COL IN REMAINING SET WITH LARGEST SS.
      if (kind(H) == real_single) then
        MAX = ISAMAX(LEND-I+1,H(I),1) + I - 1
      else if (kind(H) == real_double) then
        MAX = IDAMAX(LEND-I+1,H(I),1) + I - 1
      endif
      HBAR = H(MAX)
      GO TO 30
  130 CONTINUE
      KRANK = I - 1
      GO TO 160
  140 I = IP1
      IP1 = IP1 + 1
      GO TO 10
  150 KRANK = L1
  160 CONTINUE
      KRP1 = KRANK + 1
      IF (.NOT.(KRANK.LT.ME)) GO TO 290
      FACTOR = ALSQ
      DO 170 I=KRP1,ME
        IF (L.GT.0) W(I,1) = ZERO
        if (kind(W) == real_single) then
          CALL SCOPY(L, W(I,1), 0, W(I,1), MDW)
        else if (kind(W) == real_double) then
          CALL DCOPY(L, W(I,1), 0, W(I,1), MDW)
        endif
  170 CONTINUE
C
C     DETERMINE THE RANK OF THE REMAINING EQUALITY CONSTRAINT
C     EQUATIONS BY ELIMINATING WITHIN THE BLOCK OF CONSTRAINED
C     VARIABLES.  REMOVE ANY REDUNDANT CONSTRAINTS.
      LP1 = L + 1
      RECALC = .TRUE.
      LB = MIN0(L+ME-KRANK,N)
      I = LP1
      IP1 = I + 1
  180 IF (.NOT.(I.LE.LB)) GO TO 280
      IR = KRANK + I - L
      LEND = N
      MEND = ME
C     ASSIGN 190 TO IGO996
C     HRW: updated to remove assigned go-to.
      IGO996 = 190
      GO TO 460
C
C     UPDATE-COL-SS-AND-FIND-PIVOT-COL
C  190 ASSIGN 200 TO IGO993
C     HRW: updated to remove assigned go-to.
 190  IGO993 = 200
      GO TO 560
C
C     PERFORM-COL-INTERCHANGE
C
C     ELIMINATE ELEMENTS IN THE I-TH COL.
  200 J = ME
  210 IF (.NOT.(J.GT.IR)) GO TO 230
      JM1 = J - 1
      IF (.NOT.(W(J,I).NE.ZERO)) GO TO 220
      CALL SROTMG(SCALE(JM1), SCALE(J), W(JM1,I), W(J,I), SPARAM)
      W(J,I) = ZERO
      CALL SROTM(NP1-I, W(JM1,IP1), MDW, W(J,IP1), MDW, SPARAM)
  220 J = JM1
      GO TO 210
C
C     SET IC=I=COL BEING ELIMINATED
  230 IC = I
C      ASSIGN 240 TO IGO990
C     HRW: updated to remove assigned go-to.
      IGO990 = 240
      GO TO 520
C
C     TEST-INDEP-OF-INCOMING-COL
  240 IF (INDEP) GO TO 270
C
C     REMOVE ANY REDUNDANT OR DEPENDENT EQUALITY CONSTRAINTS.
      JJ = IR
  250 IF (.NOT.(IR.LE.ME)) GO TO 260
      W(IR,1) = ZERO

      if (kind(W) == real_single) then
        CALL SCOPY(N, W(IR,1), 0, W(IR,1), MDW)
      else if (kind(W) == real_double) then
        CALL DCOPY(N, W(IR,1), 0, W(IR,1), MDW)
      endif

      RNORM = RNORM + (SCALE(IR)*W(IR,NP1)/ALSQ)*W(IR,NP1)
      W(IR,NP1) = ZERO
      SCALE(IR) = ONE
C     RECLASSIFY THE ZEROED ROW AS A LEAST SQUARES EQUATION.
      ITYPE(IR) = 1
      IR = IR + 1
      GO TO 250
C
C     REDUCE ME TO REFLECT ANY DISCOVERED DEPENDENT EQUALITY
C     CONSTRAINTS.
  260 CONTINUE
      ME = JJ - 1
      MEP1 = ME + 1
      GO TO 300
  270 I = IP1
      IP1 = IP1 + 1
      GO TO 180
  280 CONTINUE
  290 CONTINUE
  300 CONTINUE
      IF (.NOT.(KRANK.LT.L1)) GO TO 420
C
C     TRY TO DETERMINE THE VARIABLES KRANK+1 THROUGH L1 FROM THE
C     LEAST SQUARES EQUATIONS.  CONTINUE THE TRIANGULARIZATION WITH
C     PIVOT ELEMENT W(MEP1,I).
C
      RECALC = .TRUE.
C
C     SET FACTOR=ALSQ TO REMOVE EFFECT OF HEAVY WEIGHT FROM
C     TEST FOR COL INDEPENDENCE.
      FACTOR = ALSQ
      KK = KRP1
      I = KK
      IP1 = I + 1
  310 IF (.NOT.(I.LE.L1)) GO TO 410
C
C     SET IR TO POINT TO THE MEP1-ST ROW.
      IR = MEP1
      LEND = L
      MEND = M
C     ASSIGN 320 TO IGO996
C     HRW: updated to remove assigned go-to.
      IGO996 = 320
      GO TO 460
C
C     UPDATE-COL-SS-AND-FIND-PIVOT-COL
C     320 ASSIGN 330 TO IGO993
C     HRW: updated to remove assigned go-to.
320   IGO993 = 330
      GO TO 560
C
C     PERFORM-COL-INTERCHANGE
C
C     ELIMINATE I-TH COL BELOW THE IR-TH ELEMENT.
  330 IRP1 = IR + 1
      J = M
      DO 350 JJ=IRP1,M
        JM1 = J - 1
        IF (.NOT.(W(J,I).NE.ZERO)) GO TO 340
        CALL SROTMG(SCALE(JM1), SCALE(J), W(JM1,I), W(J,I), SPARAM)
        W(J,I) = ZERO
        CALL SROTM(NP1-I, W(JM1,IP1), MDW, W(J,IP1), MDW, SPARAM)
  340   J = JM1
  350 CONTINUE
C
C     TEST IF NEW PIVOT ELEMENT IS NEAR ZERO. IF SO, THE COL IS
C     DEPENDENT.
      T = SCALE(IR)*W(IR,I)**2
      INDEP = T.GT.TAU**2*EANORM**2
      IF (.NOT.INDEP) GO TO 380
C
C     COL TEST PASSED. NOW MUST PASS ROW NORM TEST TO BE CLASSIFIED
C     AS INDEPENDENT.
      RN = ZERO
      DO 370 I1=IR,M
        DO 360 J1=IP1,N
          RN = AMAX1(RN,SCALE(I1)*W(I1,J1)**2)
  360   CONTINUE
  370 CONTINUE
      INDEP = T.GT.TAU**2*RN
C
C     IF INDEPENDENT, SWAP THE IR-TH AND KRP1-ST ROWS TO MAINTAIN THE
C     TRIANGULAR FORM.  UPDATE THE RANK INDICATOR KRANK AND THE
C     EQUALITY CONSTRAINT POINTER ME.
  380 IF (.NOT.(INDEP)) GO TO 390
      if (kind(W) == real_single) then
        CALL SSWAP(NP1, W(KRP1,1), MDW, W(IR,1), MDW)
      else if (kind(W) == real_double) then
        CALL DSWAP(NP1, W(KRP1,1), MDW, W(IR,1), MDW)
      endif
      if (kind(SCALE) == real_single) then
        CALL SSWAP(1, SCALE(KRP1), 1, SCALE(IR), 1)
      else if (kind(SCALE) == real_double) then
        CALL DSWAP(1, SCALE(KRP1), 1, SCALE(IR), 1)
      endif
C     RECLASSIFY THE LEAST SQ. EQUATION AS AN EQUALITY CONSTRAINT AND
C     RESCALE IT.
      ITYPE(IR) = 0
      T = SQRT(SCALE(KRP1))

      if (kind(W) == real_single) then
        CALL SSCAL(NP1, T, W(KRP1,1), MDW)
      else if (kind(W) == real_double) then
        CALL DSCAL(NP1, T, W(KRP1,1), MDW)
      endif

      SCALE(KRP1) = ALSQ
      ME = MEP1
      MEP1 = ME + 1
      KRANK = KRP1
      KRP1 = KRANK + 1
      GO TO 400
  390 GO TO 430
  400 I = IP1
      IP1 = IP1 + 1
      GO TO 310
  410 CONTINUE
  420 CONTINUE
  430 CONTINUE
C
C     IF PSEUDORANK IS LESS THAN L, APPLY HOUSEHOLDER TRANS.
C     FROM RIGHT.
      IF (.NOT.(KRANK.LT.L)) GO TO 450
      DO 440 I=1,KRANK
        J = KRP1 - I
        CALL H12(1, J, KRP1, L, W(J,1), MDW, H(J), W, MDW, 1, J-1)
  440 CONTINUE
  450 NIV = KRANK + NSOLN - L
      NIV1 = NIV + 1
      IF (L.EQ.N) DONE = .TRUE.
C
C  END OF INITIAL TRIANGULARIZATION.
      IDOPE(1) = ME
      IDOPE(2) = MEP1
      IDOPE(3) = KRANK
      IDOPE(4) = KRP1
      IDOPE(5) = NSOLN
      IDOPE(6) = NIV
      IDOPE(7) = NIV1
      IDOPE(8) = L1
      RETURN
  460 CONTINUE
C
C     TO UPDATE-COL-SS-AND-FIND-PIVOT-COL
C
C     THE COL SS VECTOR WILL BE UPDATED AT EACH STEP. WHEN
C     NUMERICALLY NECESSARY, THESE VALUES WILL BE RECOMPUTED.
C
      IF (.NOT.(IR.NE.1 .AND. (.NOT.RECALC))) GO TO 480
C     UPDATE COL SS =SUM OF SQUARES.
      DO 470 J=I,LEND
        H(J) = H(J) - SCALE(IR-1)*W(IR-1,J)**2
  470 CONTINUE
C
C     TEST FOR NUMERICAL ACCURACY.
      if (kind(H) == real_single) then
        MAX = ISAMAX(LEND-I+1,H(I),1) + I - 1
      else if (kind(H) == real_double) then
        MAX = IDAMAX(LEND-I+1,H(I),1) + I - 1
      endif
      RECALC = HBAR + TENM3*H(MAX).EQ.HBAR
C
C     IF REQUIRED, RECALCULATE COL SS, USING ROWS IR THROUGH MEND.
  480 IF (.NOT.(RECALC)) GO TO 510
      DO 500 J=I,LEND
        H(J) = ZERO
        DO 490 K=IR,MEND
          H(J) = H(J) + SCALE(K)*W(K,J)**2
  490   CONTINUE
  500 CONTINUE
C
C     FIND COL WITH LARGEST SS.
      if (kind(H) == real_single) then
        MAX = ISAMAX(LEND-I+1,H(I),1) + I - 1
      else if (kind(H) == real_double) then
        MAX = IDAMAX(LEND-I+1,H(I),1) + I - 1
      endif

      HBAR = H(MAX)
  510 GO TO 600
  520 CONTINUE
C
C     TO TEST-INDEP-OF-INCOMING-COL
C
C     TEST THE COL IC TO DETERMINE IF IT IS LINEARLY INDEPENDENT
C     OF THE COLS ALREADY IN THE BASIS.  IN THE INIT TRI
C     STEP, WE USUALLY WANT THE HEAVY WEIGHT ALAMDA TO
C     BE INCLUDED IN THE TEST FOR INDEPENDENCE.  IN THIS CASE THE
C     VALUE OF FACTOR WILL HAVE BEEN SET TO 1.E0 BEFORE THIS
C     PROCEDURE IS INVOKED.  IN THE POTENTIALLY RANK DEFICIENT
C     PROBLEM, THE VALUE OF FACTOR WILL HAVE BEEN
C     SET TO ALSQ=ALAMDA**2 TO REMOVE THE EFFECT OF THE HEAVY WEIGHT
C     FROM THE TEST FOR INDEPENDENCE.
C
C     WRITE NEW COL AS PARTITIONED VECTOR
C             (A1)  NUMBER OF COMPONENTS IN SOLN SO FAR = NIV
C             (A2)  M-NIV COMPONENTS
C     AND COMPUTE  SN = INVERSE WEIGHTED LENGTH OF A1
C                  RN = INVERSE WEIGHTED LENGTH OF A2
C     CALL THE COL INDEPENDENT WHEN RN .GT. TAU*SN
      SN = ZERO
      RN = ZERO
      DO 550 J=1,MEND
        T = SCALE(J)
        IF (J.LE.ME) T = T/FACTOR
        T = T*W(J,IC)**2
        IF (.NOT.(J.LT.IR)) GO TO 530
        SN = SN + T
        GO TO 540
  530   RN = RN + T
  540   CONTINUE
  550 CONTINUE
      INDEP = RN.GT.TAU**2*SN
      GO TO 590
  560 CONTINUE
C
C     TO PERFORM-COL-INTERCHANGE
C
      IF (.NOT.(MAX.NE.I)) GO TO 570
C     EXCHANGE ELEMENTS OF PERMUTED INDEX VECTOR AND PERFORM COL
C     INTERCHANGES.
      ITEMP = IPIVOT(I)
      IPIVOT(I) = IPIVOT(MAX)
      IPIVOT(MAX) = ITEMP

      if (kind(W) == real_single) then
        CALL SSWAP(M, W(1,MAX), 1, W(1,I), 1)
      else if (kind(W) == real_double) then
        CALL DSWAP(M, W(1,MAX), 1, W(1,I), 1)
      endif

      T = H(MAX)
      H(MAX) = H(I)
      H(I) = T
  570 GO TO 580
C     HRW: updated to remove assigned go-to.
580   CONTINUE
      IF (IGO993 == 30) GO TO 30
      IF (IGO993 == 200) GO TO 200
      IF (IGO993 == 330) GO TO 330
      IF (IGO993 == 120) GO TO 120
C     HRW: updated to remove assigned go-to.
590   CONTINUE
      IF (IGO990 == 40) GO TO 40
      IF (IGO990 == 240) GO TO 240
C     HRW: updated to remove assigned go-to.
600   CONTINUE
      IF (IGO996 == 20) GO TO 20
      IF (IGO996 == 190) GO TO 190
      IF (IGO996 == 320) GO TO 320

      END