123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- *DECK WNLIT
- SUBROUTINE WNLIT (W, MDW, M, N, L, IPIVOT, ITYPE, H, SCALE, RNORM,
- + IDOPE, DOPE, DONE)
- C***BEGIN PROLOGUE WNLIT
- C***SUBSIDIARY
- C***PURPOSE Subsidiary to WNNLS
- C***LIBRARY SLATEC
- C***TYPE SINGLE PRECISION (WNLIT-S, DWNLIT-D)
- C***AUTHOR Hanson, R. J., (SNLA)
- C Haskell, K. H., (SNLA)
- C***DESCRIPTION
- C
- C This is a companion subprogram to WNNLS( ).
- C The documentation for WNNLS( ) has complete 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
- C***SEE ALSO WNNLS
- C***ROUTINES CALLED H12, ISAMAX, SCOPY, SROTM, SROTMG, SSCAL, SSWAP,
- C WNLT1, WNLT2, WNLT3
- C***REVISION HISTORY (YYMMDD)
- C 790701 DATE WRITTEN
- C 890531 Changed all specific intrinsics to generic. (WRB)
- C 890618 Completely restructured and revised. (WRB & RWC)
- C 890620 Revised to make WNLT1, WNLT2, and WNLT3 subroutines. (RWC)
- C 891214 Prologue converted to Version 4.0 format. (BAB)
- C 900328 Added TYPE section. (WRB)
- C***END PROLOGUE WNLIT
- INTEGER IDOPE(*), IPIVOT(*), ITYPE(*), L, M, MDW, N
- REAL DOPE(*), H(*), RNORM, SCALE(*), W(MDW,*)
- LOGICAL DONE
- C
- EXTERNAL H12, ISAMAX, SCOPY, SROTM, SROTMG, SSCAL, SSWAP, WNLT1,
- * WNLT2, WNLT3
- INTEGER ISAMAX
- LOGICAL WNLT2
- C
- REAL ALSQ, AMAX, EANORM, FACTOR, HBAR, RN, SPARAM(5),
- * T, TAU
- INTEGER I, I1, IMAX, IR, J, J1, JJ, JP, KRANK, L1, LB, LEND, ME,
- * MEND, NIV, NSOLN
- LOGICAL INDEP, RECALC
- C
- C***FIRST EXECUTABLE STATEMENT WNLIT
- ME = IDOPE(1)
- NSOLN = IDOPE(2)
- L1 = IDOPE(3)
- C
- ALSQ = DOPE(1)
- EANORM = DOPE(2)
- TAU = DOPE(3)
- C
- LB = MIN(M-1,L)
- RECALC = .TRUE.
- RNORM = 0.E0
- KRANK = 0
- C
- C We set FACTOR=1.0 so that the heavy weight ALAMDA will be
- C included in the test for column independence.
- C
- FACTOR = 1.E0
- LEND = L
- DO 180 I=1,LB
- C
- C Set IR to point to the I-th row.
- C
- IR = I
- MEND = M
- CALL WNLT1 (I, LEND, M, IR, MDW, RECALC, IMAX, HBAR, H, SCALE,
- + W)
- C
- C Update column SS and find pivot column.
- C
- CALL WNLT3 (I, IMAX, M, MDW, IPIVOT, H, W)
- C
- C Perform column interchange.
- C Test independence of incoming column.
- C
- 130 IF (WNLT2(ME, MEND, IR, FACTOR, TAU, SCALE, W(1,I))) THEN
- C
- C Eliminate I-th column below diagonal using modified Givens
- C transformations applied to (A B).
- C
- C When operating near the ME line, use the largest element
- C above it as the pivot.
- C
- DO 160 J=M,I+1,-1
- JP = J-1
- IF (J.EQ.ME+1) THEN
- IMAX = ME
- AMAX = SCALE(ME)*W(ME,I)**2
- DO 150 JP=J-1,I,-1
- T = SCALE(JP)*W(JP,I)**2
- IF (T.GT.AMAX) THEN
- IMAX = JP
- AMAX = T
- ENDIF
- 150 CONTINUE
- JP = IMAX
- ENDIF
- C
- IF (W(J,I).NE.0.E0) THEN
- CALL SROTMG (SCALE(JP), SCALE(J), W(JP,I), W(J,I),
- + SPARAM)
- W(J,I) = 0.E0
- CALL SROTM (N+1-I, W(JP,I+1), MDW, W(J,I+1), MDW,
- + SPARAM)
- ENDIF
- 160 CONTINUE
- ELSE IF (LEND.GT.I) THEN
- C
- C Column I is dependent. Swap with column LEND.
- C Perform column interchange,
- C and find column in remaining set with largest SS.
- C
- CALL WNLT3 (I, LEND, M, MDW, IPIVOT, H, W)
- LEND = LEND - 1
- IMAX = ISAMAX(LEND-I+1, H(I), 1) + I - 1
- HBAR = H(IMAX)
- GO TO 130
- ELSE
- KRANK = I - 1
- GO TO 190
- ENDIF
- 180 CONTINUE
- KRANK = L1
- C
- 190 IF (KRANK.LT.ME) THEN
- FACTOR = ALSQ
- DO 200 I=KRANK+1,ME
- CALL SCOPY (L, 0.E0, 0, W(I,1), MDW)
- 200 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.
- C
- RECALC = .TRUE.
- LB = MIN(L+ME-KRANK, N)
- DO 270 I=L+1,LB
- IR = KRANK + I - L
- LEND = N
- MEND = ME
- CALL WNLT1 (I, LEND, ME, IR, MDW, RECALC, IMAX, HBAR, H,
- + SCALE, W)
- C
- C Update col ss and find pivot col
- C
- CALL WNLT3 (I, IMAX, M, MDW, IPIVOT, H, W)
- C
- C Perform column interchange
- C Eliminate elements in the I-th col.
- C
- DO 240 J=ME,IR+1,-1
- IF (W(J,I).NE.0.E0) THEN
- CALL SROTMG (SCALE(J-1), SCALE(J), W(J-1,I), W(J,I),
- + SPARAM)
- W(J,I) = 0.E0
- CALL SROTM (N+1-I, W(J-1,I+1), MDW,W(J,I+1), MDW,
- + SPARAM)
- ENDIF
- 240 CONTINUE
- C
- C I=column being eliminated.
- C Test independence of incoming column.
- C Remove any redundant or dependent equality constraints.
- C
- IF (.NOT.WNLT2(ME, MEND, IR, FACTOR,TAU,SCALE,W(1,I))) THEN
- JJ = IR
- DO 260 IR=JJ,ME
- CALL SCOPY (N, 0.E0, 0, W(IR,1), MDW)
- RNORM = RNORM + (SCALE(IR)*W(IR,N+1)/ALSQ)*W(IR,N+1)
- W(IR,N+1) = 0.E0
- SCALE(IR) = 1.E0
- C
- C Reclassify the zeroed row as a least squares equation.
- C
- ITYPE(IR) = 1
- 260 CONTINUE
- C
- C Reduce ME to reflect any discovered dependent equality
- C constraints.
- C
- ME = JJ - 1
- GO TO 280
- ENDIF
- 270 CONTINUE
- ENDIF
- 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(ME+1,I).
- C
- 280 IF (KRANK.LT.L1) THEN
- RECALC = .TRUE.
- C
- C Set FACTOR=ALSQ to remove effect of heavy weight from
- C test for column independence.
- C
- FACTOR = ALSQ
- DO 350 I=KRANK+1,L1
- C
- C Set IR to point to the ME+1-st row.
- C
- IR = ME+1
- LEND = L
- MEND = M
- CALL WNLT1 (I, L, M, IR, MDW, RECALC, IMAX, HBAR, H, SCALE,
- + W)
- C
- C Update column SS and find pivot column.
- C
- CALL WNLT3 (I, IMAX, M, MDW, IPIVOT, H, W)
- C
- C Perform column interchange.
- C Eliminate I-th column below the IR-th element.
- C
- DO 320 J=M,IR+1,-1
- IF (W(J,I).NE.0.E0) THEN
- CALL SROTMG (SCALE(J-1), SCALE(J), W(J-1,I), W(J,I),
- + SPARAM)
- W(J,I) = 0.E0
- CALL SROTM (N+1-I, W(J-1,I+1), MDW, W(J,I+1), MDW,
- + SPARAM)
- ENDIF
- 320 CONTINUE
- C
- C Test if new pivot element is near zero.
- C If so, the column is dependent.
- C Then check row norm test to be classified as independent.
- C
- T = SCALE(IR)*W(IR,I)**2
- INDEP = T .GT. (TAU*EANORM)**2
- IF (INDEP) THEN
- RN = 0.E0
- DO 340 I1=IR,M
- DO 330 J1=I+1,N
- RN = MAX(RN, SCALE(I1)*W(I1,J1)**2)
- 330 CONTINUE
- 340 CONTINUE
- INDEP = T .GT. RN*TAU**2
- ENDIF
- C
- C If independent, swap the IR-th and KRANK+1-th rows to
- C maintain the triangular form. Update the rank indicator
- C KRANK and the equality constraint pointer ME.
- C
- IF (.NOT.INDEP) GO TO 360
- CALL SSWAP(N+1, W(KRANK+1,1), MDW, W(IR,1), MDW)
- CALL SSWAP(1, SCALE(KRANK+1), 1, SCALE(IR), 1)
- C
- C Reclassify the least square equation as an equality
- C constraint and rescale it.
- C
- ITYPE(IR) = 0
- T = SQRT(SCALE(KRANK+1))
- CALL SSCAL(N+1, T, W(KRANK+1,1), MDW)
- SCALE(KRANK+1) = ALSQ
- ME = ME+1
- KRANK = KRANK+1
- 350 CONTINUE
- ENDIF
- C
- C If pseudorank is less than L, apply Householder transformation.
- C from right.
- C
- 360 IF (KRANK.LT.L) THEN
- DO 370 J=KRANK,1,-1
- CALL H12 (1, J, KRANK+1, L, W(J,1), MDW, H(J), W, MDW, 1,
- + J-1)
- 370 CONTINUE
- ENDIF
- C
- NIV = KRANK + NSOLN - L
- IF (L.EQ.N) DONE = .TRUE.
- C
- C End of initial triangularization.
- C
- IDOPE(1) = ME
- IDOPE(2) = KRANK
- IDOPE(3) = NIV
- RETURN
- END
|