home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / FORTRAN / LLSQ.ZIP / NNLS.FOR < prev    next >
Encoding:
Text File  |  1984-02-23  |  22.2 KB  |  279 lines

  1. C     SUBROUTINE NNLS  (A,MDA,M,N,B,X,RNORM,W,ZZ,INDEX,MODE)            NLS00100
  2. C     C.L.LAWSON AND R.J.HANSON, JET PROPULSION LABORATORY, 1973 JUNE 15NLS00200
  3. C     TO APPEAR IN 'SOLVING LEAST SQUARES PROBLEMS', PRENTICE-HALL, 1974NLS00300
  4. C                                                                       NLS00400
  5. C         **********   NONNEGATIVE LEAST SQUARES   **********           NLS00500
  6. C                                                                       NLS00600
  7. C     GIVEN AN M BY N MATRIX, A, AND AN M-VECTOR, B,  COMPUTE AN        NLS00700
  8. C     N-VECTOR, X, WHICH SOLVES THE LEAST SQUARES PROBLEM               NLS00800
  9. C                                                                       NLS00900
  10. C                      A * X = B  SUBJECT TO X .GE. 0                   NLS01000
  11. C                                                                       NLS01100
  12. C     A(),MDA,M,N     MDA IS THE FIRST DIMENSIONING PARAMETER FOR THE   NLS01200
  13. C                     ARRAY, A().   ON ENTRY A() CONTAINS THE M BY N    NLS01300
  14. C                     MATRIX, A.           ON EXIT A() CONTAINS         NLS01400
  15. C                     THE PRODUCT MATRIX, Q*A , WHERE Q IS AN           NLS01500
  16. C                     M BY M ORTHOGONAL MATRIX GENERATED IMPLICITLY BY  NLS01600
  17. C                     THIS SUBROUTINE.                                  NLS01700
  18. C     B()     ON ENTRY B() CONTAINS THE M-VECTOR, B.   ON EXIT B() CON- NLS01800
  19. C             TAINS Q*B.                                                NLS01900
  20. C     X()     ON ENTRY X() NEED NOT BE INITIALIZED.  ON EXIT X() WILL   NLS02000
  21. C             CONTAIN THE SOLUTION VECTOR.                              NLS02100
  22. C     RNORM   ON EXIT RNORM CONTAINS THE EUCLIDEAN NORM OF THE          NLS02200
  23. C             RESIDUAL VECTOR.                                          NLS02300
  24. C     W()     AN N-ARRAY OF WORKING SPACE.  ON EXIT W() WILL CONTAIN    NLS02400
  25. C             THE DUAL SOLUTION VECTOR.   W WILL SATISFY W(I) = 0.      NLS02500
  26. C             FOR ALL I IN SET P  AND W(I) .LE. 0. FOR ALL I IN SET Z   NLS02600
  27. C     ZZ()     AN M-ARRAY OF WORKING SPACE.                             NLS02700
  28. C     INDEX()     AN INTEGER WORKING ARRAY OF LENGTH AT LEAST N.        NLS02800
  29. C                 ON EXIT THE CONTENTS OF THIS ARRAY DEFINE THE SETS    NLS02900
  30. C                 P AND Z AS FOLLOWS..                                  NLS03000
  31. C                                                                       NLS03100
  32. C                 INDEX(1)   THRU INDEX(NSETP) = SET P.                 NLS03200
  33. C                 INDEX(IZ1) THRU INDEX(IZ2)   = SET Z.                 NLS03300
  34. C                 IZ1 = NSETP + 1 = NPP1                                NLS03400
  35. C                 IZ2 = N                                               NLS03500
  36. C     MODE    THIS IS A SUCCESS-FAILURE FLAG WITH THE FOLLOWING         NLS03600
  37. C             MEANINGS.                                                 NLS03700
  38. C             1     THE SOLUTION HAS BEEN COMPUTED SUCCESSFULLY.        NLS03800
  39. C             2     THE DIMENSIONS OF THE PROBLEM ARE BAD.              NLS03900
  40. C                   EITHER M .LE. 0 OR N .LE. 0.                        NLS04000
  41. C             3    ITERATION COUNT EXCEEDED.  MORE THAN 3*N ITERATIONS. NLS04100
  42. C                                                                       NLS04200
  43.       SUBROUTINE NNLS (A,MDA,M,N,B,X,RNORM,W,ZZ,INDEX,MODE)             NLS04300
  44.       DIMENSION A(MDA,N), B(M), X(N), W(N), ZZ(M)                       NLS04400
  45.       INTEGER INDEX(N)                                                  NLS04500
  46.       ZERO=0.                                                           NLS04600
  47.       ONE=1.                                                            NLS04700
  48.       TWO=2.                                                            NLS04800
  49.       FACTOR=0.01                                                       NLS04900
  50. C                                                                       NLS05000
  51.       MODE=1                                                            NLS05100
  52.       IF (M.GT.0.AND.N.GT.0) GO TO 10                                   NLS05200
  53.       MODE=2                                                            NLS05300
  54.       RETURN                                                            NLS05400
  55.    10 ITER=0                                                            NLS05500
  56.       ITMAX=3*N                                                         NLS05600
  57. C                                                                       NLS05700
  58. C                    INITIALIZE THE ARRAYS INDEX() AND X().             NLS05800
  59. C                                                                       NLS05900
  60.           DO 20 I=1,N                                                   NLS06000
  61.           X(I)=ZERO                                                     NLS06100
  62.    20     INDEX(I)=I                                                    NLS06200
  63. C                                                                       NLS06300
  64.       IZ2=N                                                             NLS06400
  65.       IZ1=1                                                             NLS06500
  66.       NSETP=0                                                           NLS06600
  67.       NPP1=1                                                            NLS06700
  68. C                             ******  MAIN LOOP BEGINS HERE  ******     NLS06800
  69.    30 CONTINUE                                                          NLS06900
  70. C                  QUIT IF ALL COEFFICIENTS ARE ALREADY IN THE SOLUTION.NLS07000
  71. C                        OR IF M COLS OF A HAVE BEEN TRIANGULARIZED.    NLS07100
  72. C                                                                       NLS07200
  73.       IF (IZ1.GT.IZ2.OR.NSETP.GE.M) GO TO 350                           NLS07300
  74. C                                                                       NLS07400
  75. C         COMPUTE COMPONENTS OF THE DUAL (NEGATIVE GRADIENT) VECTOR W().NLS07500
  76. C                                                                       NLS07600
  77.           DO 50 IZ=IZ1,IZ2                                              NLS07700
  78.           J=INDEX(IZ)                                                   NLS07800
  79.           SM=ZERO                                                       NLS07900
  80.               DO 40 L=NPP1,M                                            NLS08000
  81.    40         SM=SM+A(L,J)*B(L)                                         NLS08100
  82.    50     W(J)=SM                                                       NLS08200
  83. C                                   FIND LARGEST POSITIVE W(J).         NLS08300
  84.    60 WMAX=ZERO                                                         NLS08400
  85.           DO 70 IZ=IZ1,IZ2                                              NLS08500
  86.           J=INDEX(IZ)                                                   NLS08600
  87.           IF (W(J).LE.WMAX) GO TO 70                                    NLS08700
  88.           WMAX=W(J)                                                     NLS08800
  89.           IZMAX=IZ                                                      NLS08900
  90.    70     CONTINUE                                                      NLS09000
  91. C                                                                       NLS09100
  92. C             IF WMAX .LE. 0. GO TO TERMINATION.                        NLS09200
  93. C             THIS INDICATES SATISFACTION OF THE KUHN-TUCKER CONDITIONS.NLS09300
  94. C                                                                       NLS09400
  95.       IF (WMAX) 350,350,80                                              NLS09500
  96.    80 IZ=IZMAX                                                          NLS09600
  97.       J=INDEX(IZ)                                                       NLS09700
  98. C                                                                       NLS09800
  99. C     THE SIGN OF W(J) IS OK FOR J TO BE MOVED TO SET P.                NLS09900
  100. C     BEGIN THE TRANSFORMATION AND CHECK NEW DIAGONAL ELEMENT TO AVOID  NLS10000
  101. C     NEAR LINEAR DEPENDENCE.                                           NLS10100
  102. C                                                                       NLS10200
  103.       ASAVE=A(NPP1,J)                                                   NLS10300
  104.       CALL H12 (1,NPP1,NPP1+1,M,A(1,J),1,UP,DUMMY,1,1,0)                NLS10400
  105.       UNORM=ZERO                                                        NLS10500
  106.       IF (NSETP.EQ.0) GO TO 100                                         NLS10600
  107.           DO 90 L=1,NSETP                                               NLS10700
  108.    90     UNORM=UNORM+A(L,J)**2                                         NLS10800
  109.   100 UNORM=SQRT(UNORM)                                                 NLS10900
  110.       IF (DIFF(UNORM+ABS(A(NPP1,J))*FACTOR,UNORM)) 130,130,110          NLS11000
  111. C                                                                       NLS11100
  112. C     COL J IS SUFFICIENTLY INDEPENDENT.  COPY B INTO ZZ, UPDATE ZZ AND NLS11200
  113. C   > SOLVE FOR ZTEST ( = PROPOSED NEW VALUE FOR X(J) ).                NLS11300
  114. C                                                                       NLS11400
  115.   110     DO 120 L=1,M                                                  NLS11500
  116.   120     ZZ(L)=B(L)                                                    NLS11600
  117.       CALL H12 (2,NPP1,NPP1+1,M,A(1,J),1,UP,ZZ,1,1,1)                   NLS11700
  118.       ZTEST=ZZ(NPP1)/A(NPP1,J)                                          NLS11800
  119. C                                                                       NLS11900
  120. C                                     SEE IF ZTEST IS POSITIVE          NLS12000
  121. C     REJECT J AS A CANDIDATE TO BE MOVED FROM SET Z TO SET P.          NLS12400
  122. C     RESTORE A(NPP1,J), SET W(J)=0., AND LOOP BACK TO TEST DUAL        NLS12500
  123. C                                                                       NLS12100
  124.       IF (ZTEST) 130,130,140                                            NLS12200
  125. C                                                                       NLS12300
  126. C     COEFFS AGAIN.                                                     NLS12600
  127. C                                                                       NLS12700
  128.   130 A(NPP1,J)=ASAVE                                                   NLS12800
  129.       W(J)=ZERO                                                         NLS12900
  130.       GO TO 60                                                          NLS13000
  131. C                                                                       NLS13100
  132. C     THE INDEX  J=INDEX(IZ)  HAS BEEN SELECTED TO BE MOVED FROM        NLS13200
  133. C     SET Z TO SET P.    UPDATE B,  UPDATE INDICES,  APPLY HOUSEHOLDER  NLS13300
  134. C     TRANSFORMATIONS TO COLS IN NEW SET Z,  ZERO SUBDIAGONAL ELTS IN   NLS13400
  135. C     COL J,  SET W(J)=0.                                               NLS13500
  136. C                                                                       NLS13600
  137.   140     DO 150 L=1,M                                                  NLS13700
  138.   150     B(L)=ZZ(L)                                                    NLS13800
  139. C                                                                       NLS13900
  140.       INDEX(IZ)=INDEX(IZ1)                                              NLS14000
  141.       INDEX(IZ1)=J                                                      NLS14100
  142.       IZ1=IZ1+1                                                         NLS14200
  143.       NSETP=NPP1                                                        NLS14300
  144.       NPP1=NPP1+1                                                       NLS14400
  145. C                                                                       NLS14500
  146.       IF (IZ1.GT.IZ2) GO TO 170                                         NLS14600
  147.           DO 160 JZ=IZ1,IZ2                                             NLS14700
  148.           JJ=INDEX(JZ)                                                  NLS14800
  149.   160     CALL H12 (2,NSETP,NPP1,M,A(1,J),1,UP,A(1,JJ),1,MDA,1)         NLS14900
  150.   170 CONTINUE                                                          NLS15000
  151. C                                                                       NLS15100
  152.       IF (NSETP.EQ.M) GO TO 190                                         NLS15200
  153.           DO 180 L=NPP1,M                                               NLS15300
  154.   180     A(L,J)=ZERO                                                   NLS15400
  155.   190 CONTINUE                                                          NLS15500
  156. C                                                                       NLS15600
  157.       W(J)=ZERO                                                         NLS15700
  158. C                                SOLVE THE TRIANGULAR SYSTEM.           NLS15800
  159. C                                STORE THE SOLUTION TEMPORARILY IN ZZ().NLS15900
  160.       ASSIGN 200 TO NEXT                                                NLS16000
  161.       GO TO 400                                                         NLS16100
  162.   200 CONTINUE                                                          NLS16200
  163. C                                                                       NLS16300
  164. C                       ******  SECONDARY LOOP BEGINS HERE ******       NLS16400
  165. C                                                                       NLS16500
  166. C                          ITERATION COUNTER.                           NLS16600
  167. C                                                                       NLS16700
  168.   210 ITER=ITER+1                                                       NLS16800
  169.       IF (ITER.LE.ITMAX) GO TO 220                                      NLS16900
  170.       MODE=3                                                            NLS17000
  171.       WRITE (6,440)                                                     NLS17100
  172.       GO TO 350                                                         NLS17200
  173.   220 CONTINUE                                                          NLS17300
  174. C                                                                       NLS17400
  175. C                    SEE IF ALL NEW CONSTRAINED COEFFS ARE FEASIBLE.    NLS17500
  176. C                                  IF NOT COMPUTE ALPHA.                NLS17600
  177. C                                                                       NLS17700
  178.       ALPHA=TWO                                                         NLS17800
  179.           DO 240 IP=1,NSETP                                             NLS17900
  180.           L=INDEX(IP)                                                   NLS18000
  181.           IF (ZZ(IP)) 230,230,240                                       NLS18100
  182. C                                                                       NLS18200
  183.   230     T=-X(L)/(ZZ(IP)-X(L))                                         NLS18300
  184.           IF (ALPHA.LE.T) GO TO 240                                     NLS18400
  185.           ALPHA=T                                                       NLS18500
  186.           JJ=IP                                                         NLS18600
  187.   240     CONTINUE                                                      NLS18700
  188. C                                                                       NLS18800
  189. C          IF ALL NEW CONSTRAINED COEFFS ARE FEASIBLE THEN ALPHA WILL   NLS18900
  190. C          STILL = 2.    IF SO EXIT FROM SECONDARY LOOP TO MAIN LOOP.   NLS19000
  191. C                                                                       NLS19100
  192.       IF (ALPHA.EQ.TWO) GO TO 330                                       NLS19200
  193. C                                                                       NLS19300
  194. C          OTHERWISE USE ALPHA WHICH WILL BE BETWEEN 0. AND 1. TO       NLS19400
  195. C          INTERPOLATE BETWEEN THE OLD X AND THE NEW ZZ.                NLS19500
  196. C                                                                       NLS19600
  197.           DO 250 IP=1,NSETP                                             NLS19700
  198.           L=INDEX(IP)                                                   NLS19800
  199.   250     X(L)=X(L)+ALPHA*(ZZ(IP)-X(L))                                 NLS19900
  200. C                                                                       NLS20000
  201. C        MODIFY A AND B AND THE INDEX ARRAYS TO MOVE COEFFICIENT I      NLS20100
  202. C        FROM SET P TO SET Z.                                           NLS20200
  203. C                                                                       NLS20300
  204.       I=INDEX(JJ)                                                       NLS20400
  205.   260 X(I)=ZERO                                                         NLS20500
  206. C                                                                       NLS20600
  207.       IF (JJ.EQ.NSETP) GO TO 290                                        NLS20700
  208.       JJ=JJ+1                                                           NLS20800
  209.           DO 280 J=JJ,NSETP                                             NLS20900
  210.           II=INDEX(J)                                                   NLS21000
  211.           INDEX(J-1)=II                                                 NLS21100
  212.           CALL G1 (A(J-1,II),A(J,II),CC,SS,A(J-1,II))                   NLS21200
  213.           A(J,II)=ZERO                                                  NLS21300
  214.               DO 270 L=1,N                                              NLS21400
  215.               IF (L.NE.II) CALL G2 (CC,SS,A(J-1,L),A(J,L))              NLS21500
  216.   270         CONTINUE                                                  NLS21600
  217.   280     CALL G2 (CC,SS,B(J-1),B(J))                                   NLS21700
  218.   290 NPP1=NSETP                                                        NLS21800
  219.       NSETP=NSETP-1                                                     NLS21900
  220.       IZ1=IZ1-1                                                         NLS22000
  221.       INDEX(IZ1)=I                                                      NLS22100
  222. C                                                                       NLS22200
  223. C        SEE IF THE REMAINING COEFFS IN SET P ARE FEASIBLE.  THEY SHOULDNLS22300
  224. C        BE BECAUSE OF THE WAY ALPHA WAS DETERMINED.                    NLS22400
  225. C        IF ANY ARE INFEASIBLE IT IS DUE TO ROUND-OFF ERROR.  ANY       NLS22500
  226. C        THAT ARE NONPOSITIVE WILL BE SET TO ZERO                       NLS22600
  227. C        AND MOVED FROM SET P TO SET Z.                                 NLS22700
  228. C                                                                       NLS22800
  229.           DO 300 JJ=1,NSETP                                             NLS22900
  230.           I=INDEX(JJ)                                                   NLS23000
  231.           IF (X(I)) 260,260,300                                         NLS23100
  232.   300     CONTINUE                                                      NLS23200
  233. C                                                                       NLS23300
  234. C         COPY B( ) INTO ZZ( ).  THEN SOLVE AGAIN AND LOOP BACK.        NLS23400
  235. C                                                                       NLS23500
  236.  
  237.           DO 310 I=1,M                                                  NLS23600
  238.   310     ZZ(I)=B(I)                                                    NLS23700
  239.       ASSIGN 320 TO NEXT                                                NLS23800
  240.       GO TO 400                                                         NLS23900
  241.   320 CONTINUE                                                          NLS24000
  242.       GO TO 210                                                         NLS24100
  243. C                      ******  END OF SECONDARY LOOP  ******            NLS24200
  244. C                                                                       NLS24300
  245.   330     DO 340 IP=1,NSETP                                             NLS24400
  246.           I=INDEX(IP)                                                   NLS24500
  247.   340     X(I)=ZZ(IP)                                                   NLS24600
  248. C        ALL NEW COEFFS ARE POSITIVE.  LOOP BACK TO BEGINNING.          NLS24700
  249.       GO TO 30                                                          NLS24800
  250. C                                                                       NLS24900
  251. C                        ******  END OF MAIN LOOP  ******               NLS25000
  252. C                                                                       NLS25100
  253. C                        COME TO HERE FOR TERMINATION.                  NLS25200
  254. C                     COMPUTE THE NORM OF THE FINAL RESIDUAL VECTOR.    NLS25300
  255. C                                                                       NLS25400
  256.   350 SM=ZERO                                                           NLS25500
  257.       IF (NPP1.GT.M) GO TO 370                                          NLS25600
  258.           DO 360 I=NPP1,M                                               NLS25700
  259.   360     SM=SM+B(I)**2                                                 NLS25800
  260.       GO TO 390                                                         NLS25900
  261.   370     DO 380 J=1,N                                                  NLS26000
  262.   380     W(J)=ZERO                                                     NLS26100
  263.   390 RNORM=SQRT(SM)                                                    NLS26200
  264.       RETURN                                                            NLS26300
  265. C                                                                       NLS26400
  266. C     THE FOLLOWING BLOCK OF CODE IS USED AS AN INTERNAL SUBROUTINE     NLS26500
  267. C     TO SOLVE THE TRIANGULAR SYSTEM, PUTTING THE SOLUTION IN ZZ().     NLS26600
  268. C                                                                       NLS26700
  269.   400     DO 430 L=1,NSETP                                              NLS26800
  270.           IP=NSETP+1-L                                                  NLS26900
  271.           IF (L.EQ.1) GO TO 420                                         NLS27000
  272.               DO 410 II=1,IP                                            NLS27100
  273.   410         ZZ(II)=ZZ(II)-A(II,JJ)*ZZ(IP+1)                           NLS27200
  274.   420     JJ=INDEX(IP)                                                  NLS27300
  275.   430     ZZ(IP)=ZZ(IP)/A(IP,JJ)                                        NLS27400
  276.       GO TO NEXT, (200,320)                                             NLS27500
  277.   440 FORMAT (35H0 NNLS QUITTING ON ITERATION COUNT.)                   NLS27600
  278.       END                                                               NLS27700
  279.