Chris@22
|
1
|
Chris@22
|
2 double precision FUNCTION DIFF(X,Y)
|
Chris@22
|
3 c
|
Chris@22
|
4 c Function used in tests that depend on machine precision.
|
Chris@22
|
5 c
|
Chris@22
|
6 c The original version of this code was developed by
|
Chris@22
|
7 c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
Chris@22
|
8 c 1973 JUN 7, and published in the book
|
Chris@22
|
9 c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
Chris@22
|
10 c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
Chris@22
|
11 C
|
Chris@22
|
12 double precision X, Y
|
Chris@22
|
13 DIFF=X-Y
|
Chris@22
|
14 RETURN
|
Chris@22
|
15 END
|
Chris@22
|
16
|
Chris@22
|
17
|
Chris@22
|
18 SUBROUTINE G1 (A,B,CTERM,STERM,SIG)
|
Chris@22
|
19 c
|
Chris@22
|
20 C COMPUTE ORTHOGONAL ROTATION MATRIX..
|
Chris@22
|
21 c
|
Chris@22
|
22 c The original version of this code was developed by
|
Chris@22
|
23 c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
Chris@22
|
24 c 1973 JUN 12, and published in the book
|
Chris@22
|
25 c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
Chris@22
|
26 c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
Chris@22
|
27 C
|
Chris@22
|
28 C COMPUTE.. MATRIX (C, S) SO THAT (C, S)(A) = (SQRT(A**2+B**2))
|
Chris@22
|
29 C (-S,C) (-S,C)(B) ( 0 )
|
Chris@22
|
30 C COMPUTE SIG = SQRT(A**2+B**2)
|
Chris@22
|
31 C SIG IS COMPUTED LAST TO ALLOW FOR THE POSSIBILITY THAT
|
Chris@22
|
32 C SIG MAY BE IN THE SAME LOCATION AS A OR B .
|
Chris@22
|
33 C ------------------------------------------------------------------
|
Chris@22
|
34 double precision A, B, CTERM, ONE, SIG, STERM, XR, YR, ZERO
|
Chris@22
|
35 parameter(ONE = 1.0d0, ZERO = 0.0d0)
|
Chris@22
|
36 C ------------------------------------------------------------------
|
Chris@22
|
37 if (abs(A) .gt. abs(B)) then
|
Chris@22
|
38 XR=B/A
|
Chris@22
|
39 YR=sqrt(ONE+XR**2)
|
Chris@22
|
40 CTERM=sign(ONE/YR,A)
|
Chris@22
|
41 STERM=CTERM*XR
|
Chris@22
|
42 SIG=abs(A)*YR
|
Chris@22
|
43 RETURN
|
Chris@22
|
44 endif
|
Chris@22
|
45
|
Chris@22
|
46 if (B .ne. ZERO) then
|
Chris@22
|
47 XR=A/B
|
Chris@22
|
48 YR=sqrt(ONE+XR**2)
|
Chris@22
|
49 STERM=sign(ONE/YR,B)
|
Chris@22
|
50 CTERM=STERM*XR
|
Chris@22
|
51 SIG=abs(B)*YR
|
Chris@22
|
52 RETURN
|
Chris@22
|
53 endif
|
Chris@22
|
54
|
Chris@22
|
55 SIG=ZERO
|
Chris@22
|
56 CTERM=ZERO
|
Chris@22
|
57 STERM=ONE
|
Chris@22
|
58 RETURN
|
Chris@22
|
59 END
|
Chris@22
|
60
|
Chris@22
|
61
|
Chris@22
|
62 C SUBROUTINE H12 (MODE,LPIVOT,L1,M,U,IUE,UP,C,ICE,ICV,NCV)
|
Chris@22
|
63 C
|
Chris@22
|
64 C CONSTRUCTION AND/OR APPLICATION OF A SINGLE
|
Chris@22
|
65 C HOUSEHOLDER TRANSFORMATION.. Q = I + U*(U**T)/B
|
Chris@22
|
66 C
|
Chris@22
|
67 c The original version of this code was developed by
|
Chris@22
|
68 c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
Chris@22
|
69 c 1973 JUN 12, and published in the book
|
Chris@22
|
70 c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
Chris@22
|
71 c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
Chris@22
|
72 C ------------------------------------------------------------------
|
Chris@22
|
73 c Subroutine Arguments
|
Chris@22
|
74 c
|
Chris@22
|
75 C MODE = 1 OR 2 Selects Algorithm H1 to construct and apply a
|
Chris@22
|
76 c Householder transformation, or Algorithm H2 to apply a
|
Chris@22
|
77 c previously constructed transformation.
|
Chris@22
|
78 C LPIVOT IS THE INDEX OF THE PIVOT ELEMENT.
|
Chris@22
|
79 C L1,M IF L1 .LE. M THE TRANSFORMATION WILL BE CONSTRUCTED TO
|
Chris@22
|
80 C ZERO ELEMENTS INDEXED FROM L1 THROUGH M. IF L1 GT. M
|
Chris@22
|
81 C THE SUBROUTINE DOES AN IDENTITY TRANSFORMATION.
|
Chris@22
|
82 C U(),IUE,UP On entry with MODE = 1, U() contains the pivot
|
Chris@22
|
83 c vector. IUE is the storage increment between elements.
|
Chris@22
|
84 c On exit when MODE = 1, U() and UP contain quantities
|
Chris@22
|
85 c defining the vector U of the Householder transformation.
|
Chris@22
|
86 c on entry with MODE = 2, U() and UP should contain
|
Chris@22
|
87 c quantities previously computed with MODE = 1. These will
|
Chris@22
|
88 c not be modified during the entry with MODE = 2.
|
Chris@22
|
89 C C() ON ENTRY with MODE = 1 or 2, C() CONTAINS A MATRIX WHICH
|
Chris@22
|
90 c WILL BE REGARDED AS A SET OF VECTORS TO WHICH THE
|
Chris@22
|
91 c HOUSEHOLDER TRANSFORMATION IS TO BE APPLIED.
|
Chris@22
|
92 c ON EXIT C() CONTAINS THE SET OF TRANSFORMED VECTORS.
|
Chris@22
|
93 C ICE STORAGE INCREMENT BETWEEN ELEMENTS OF VECTORS IN C().
|
Chris@22
|
94 C ICV STORAGE INCREMENT BETWEEN VECTORS IN C().
|
Chris@22
|
95 C NCV NUMBER OF VECTORS IN C() TO BE TRANSFORMED. IF NCV .LE. 0
|
Chris@22
|
96 C NO OPERATIONS WILL BE DONE ON C().
|
Chris@22
|
97 C ------------------------------------------------------------------
|
Chris@22
|
98 SUBROUTINE H12 (MODE,LPIVOT,L1,M,U,IUE,UP,C,ICE,ICV,NCV)
|
Chris@22
|
99 C ------------------------------------------------------------------
|
Chris@22
|
100 integer I, I2, I3, I4, ICE, ICV, INCR, IUE, J
|
Chris@22
|
101 integer L1, LPIVOT, M, MODE, NCV
|
Chris@22
|
102 double precision B, C(*), CL, CLINV, ONE, SM
|
Chris@22
|
103 c double precision U(IUE,M)
|
Chris@22
|
104 double precision U(IUE,*)
|
Chris@22
|
105 double precision UP
|
Chris@22
|
106 parameter(ONE = 1.0d0)
|
Chris@22
|
107 C ------------------------------------------------------------------
|
Chris@22
|
108 IF (0.GE.LPIVOT.OR.LPIVOT.GE.L1.OR.L1.GT.M) RETURN
|
Chris@22
|
109 CL=abs(U(1,LPIVOT))
|
Chris@22
|
110 IF (MODE.EQ.2) GO TO 60
|
Chris@22
|
111 C ****** CONSTRUCT THE TRANSFORMATION. ******
|
Chris@22
|
112 DO 10 J=L1,M
|
Chris@22
|
113 10 CL=MAX(abs(U(1,J)),CL)
|
Chris@22
|
114 IF (CL) 130,130,20
|
Chris@22
|
115 20 CLINV=ONE/CL
|
Chris@22
|
116 SM=(U(1,LPIVOT)*CLINV)**2
|
Chris@22
|
117 DO 30 J=L1,M
|
Chris@22
|
118 30 SM=SM+(U(1,J)*CLINV)**2
|
Chris@22
|
119 CL=CL*SQRT(SM)
|
Chris@22
|
120 IF (U(1,LPIVOT)) 50,50,40
|
Chris@22
|
121 40 CL=-CL
|
Chris@22
|
122 50 UP=U(1,LPIVOT)-CL
|
Chris@22
|
123 U(1,LPIVOT)=CL
|
Chris@22
|
124 GO TO 70
|
Chris@22
|
125 C ****** APPLY THE TRANSFORMATION I+U*(U**T)/B TO C. ******
|
Chris@22
|
126 C
|
Chris@22
|
127 60 IF (CL) 130,130,70
|
Chris@22
|
128 70 IF (NCV.LE.0) RETURN
|
Chris@22
|
129 B= UP*U(1,LPIVOT)
|
Chris@22
|
130 C B MUST BE NONPOSITIVE HERE. IF B = 0., RETURN.
|
Chris@22
|
131 C
|
Chris@22
|
132 IF (B) 80,130,130
|
Chris@22
|
133 80 B=ONE/B
|
Chris@22
|
134 I2=1-ICV+ICE*(LPIVOT-1)
|
Chris@22
|
135 INCR=ICE*(L1-LPIVOT)
|
Chris@22
|
136 DO 120 J=1,NCV
|
Chris@22
|
137 I2=I2+ICV
|
Chris@22
|
138 I3=I2+INCR
|
Chris@22
|
139 I4=I3
|
Chris@22
|
140 SM=C(I2)*UP
|
Chris@22
|
141 DO 90 I=L1,M
|
Chris@22
|
142 SM=SM+C(I3)*U(1,I)
|
Chris@22
|
143 90 I3=I3+ICE
|
Chris@22
|
144 IF (SM) 100,120,100
|
Chris@22
|
145 100 SM=SM*B
|
Chris@22
|
146 C(I2)=C(I2)+SM*UP
|
Chris@22
|
147 DO 110 I=L1,M
|
Chris@22
|
148 C(I4)=C(I4)+SM*U(1,I)
|
Chris@22
|
149 110 I4=I4+ICE
|
Chris@22
|
150 120 CONTINUE
|
Chris@22
|
151 130 RETURN
|
Chris@22
|
152 END
|
Chris@22
|
153
|
Chris@22
|
154
|
Chris@22
|
155
|
Chris@22
|
156 C SUBROUTINE NNLS (A,MDA,M,N,B,X,RNORM,W,ZZ,INDEX,MODE)
|
Chris@22
|
157 C
|
Chris@22
|
158 C Algorithm NNLS: NONNEGATIVE LEAST SQUARES
|
Chris@22
|
159 C
|
Chris@22
|
160 c The original version of this code was developed by
|
Chris@22
|
161 c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
Chris@22
|
162 c 1973 JUN 15, and published in the book
|
Chris@22
|
163 c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
Chris@22
|
164 c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
Chris@22
|
165 c
|
Chris@22
|
166 C GIVEN AN M BY N MATRIX, A, AND AN M-VECTOR, B, COMPUTE AN
|
Chris@22
|
167 C N-VECTOR, X, THAT SOLVES THE LEAST SQUARES PROBLEM
|
Chris@22
|
168 C
|
Chris@22
|
169 C A * X = B SUBJECT TO X .GE. 0
|
Chris@22
|
170 C ------------------------------------------------------------------
|
Chris@22
|
171 c Subroutine Arguments
|
Chris@22
|
172 c
|
Chris@22
|
173 C A(),MDA,M,N MDA IS THE FIRST DIMENSIONING PARAMETER FOR THE
|
Chris@22
|
174 C ARRAY, A(). ON ENTRY A() CONTAINS THE M BY N
|
Chris@22
|
175 C MATRIX, A. ON EXIT A() CONTAINS
|
Chris@22
|
176 C THE PRODUCT MATRIX, Q*A , WHERE Q IS AN
|
Chris@22
|
177 C M BY M ORTHOGONAL MATRIX GENERATED IMPLICITLY BY
|
Chris@22
|
178 C THIS SUBROUTINE.
|
Chris@22
|
179 C B() ON ENTRY B() CONTAINS THE M-VECTOR, B. ON EXIT B() CON-
|
Chris@22
|
180 C TAINS Q*B.
|
Chris@22
|
181 C X() ON ENTRY X() NEED NOT BE INITIALIZED. ON EXIT X() WILL
|
Chris@22
|
182 C CONTAIN THE SOLUTION VECTOR.
|
Chris@22
|
183 C RNORM ON EXIT RNORM CONTAINS THE EUCLIDEAN NORM OF THE
|
Chris@22
|
184 C RESIDUAL VECTOR.
|
Chris@22
|
185 C W() AN N-ARRAY OF WORKING SPACE. ON EXIT W() WILL CONTAIN
|
Chris@22
|
186 C THE DUAL SOLUTION VECTOR. W WILL SATISFY W(I) = 0.
|
Chris@22
|
187 C FOR ALL I IN SET P AND W(I) .LE. 0. FOR ALL I IN SET Z
|
Chris@22
|
188 C ZZ() AN M-ARRAY OF WORKING SPACE.
|
Chris@22
|
189 C INDEX() AN INTEGER WORKING ARRAY OF LENGTH AT LEAST N.
|
Chris@22
|
190 C ON EXIT THE CONTENTS OF THIS ARRAY DEFINE THE SETS
|
Chris@22
|
191 C P AND Z AS FOLLOWS..
|
Chris@22
|
192 C
|
Chris@22
|
193 C INDEX(1) THRU INDEX(NSETP) = SET P.
|
Chris@22
|
194 C INDEX(IZ1) THRU INDEX(IZ2) = SET Z.
|
Chris@22
|
195 C IZ1 = NSETP + 1 = NPP1
|
Chris@22
|
196 C IZ2 = N
|
Chris@22
|
197 C MODE THIS IS A SUCCESS-FAILURE FLAG WITH THE FOLLOWING
|
Chris@22
|
198 C MEANINGS.
|
Chris@22
|
199 C 1 THE SOLUTION HAS BEEN COMPUTED SUCCESSFULLY.
|
Chris@22
|
200 C 2 THE DIMENSIONS OF THE PROBLEM ARE BAD.
|
Chris@22
|
201 C EITHER M .LE. 0 OR N .LE. 0.
|
Chris@22
|
202 C 3 ITERATION COUNT EXCEEDED. MORE THAN 3*N ITERATIONS.
|
Chris@22
|
203 C
|
Chris@22
|
204 C ------------------------------------------------------------------
|
Chris@22
|
205 SUBROUTINE NNLS (A,MDA,M,N,B,X,RNORM,W,ZZ,INDEX,MODE)
|
Chris@22
|
206 C ------------------------------------------------------------------
|
Chris@22
|
207 integer I, II, IP, ITER, ITMAX, IZ, IZ1, IZ2, IZMAX, J, JJ, JZ, L
|
Chris@22
|
208 integer M, MDA, MODE,N, NPP1, NSETP, RTNKEY
|
Chris@22
|
209 c integer INDEX(N)
|
Chris@22
|
210 c double precision A(MDA,N), B(M), W(N), X(N), ZZ(M)
|
Chris@22
|
211 integer INDEX(*)
|
Chris@22
|
212 double precision A(MDA,*), B(*), W(*), X(*), ZZ(*)
|
Chris@22
|
213 double precision ALPHA, ASAVE, CC, DIFF, DUMMY, FACTOR, RNORM
|
Chris@22
|
214 double precision SM, SS, T, TEMP, TWO, UNORM, UP, WMAX
|
Chris@22
|
215 double precision ZERO, ZTEST
|
Chris@22
|
216 parameter(FACTOR = 0.01d0)
|
Chris@22
|
217 parameter(TWO = 2.0d0, ZERO = 0.0d0)
|
Chris@22
|
218 C ------------------------------------------------------------------
|
Chris@22
|
219 MODE=1
|
Chris@22
|
220 IF (M .le. 0 .or. N .le. 0) then
|
Chris@22
|
221 MODE=2
|
Chris@22
|
222 RETURN
|
Chris@22
|
223 endif
|
Chris@22
|
224 ITER=0
|
Chris@22
|
225 ITMAX=3*N
|
Chris@22
|
226 C
|
Chris@22
|
227 C INITIALIZE THE ARRAYS INDEX() AND X().
|
Chris@22
|
228 C
|
Chris@22
|
229 DO 20 I=1,N
|
Chris@22
|
230 X(I)=ZERO
|
Chris@22
|
231 20 INDEX(I)=I
|
Chris@22
|
232 C
|
Chris@22
|
233 IZ2=N
|
Chris@22
|
234 IZ1=1
|
Chris@22
|
235 NSETP=0
|
Chris@22
|
236 NPP1=1
|
Chris@22
|
237 C ****** MAIN LOOP BEGINS HERE ******
|
Chris@22
|
238 30 CONTINUE
|
Chris@22
|
239 C QUIT IF ALL COEFFICIENTS ARE ALREADY IN THE SOLUTION.
|
Chris@22
|
240 C OR IF M COLS OF A HAVE BEEN TRIANGULARIZED.
|
Chris@22
|
241 C
|
Chris@22
|
242 IF (IZ1 .GT.IZ2.OR.NSETP.GE.M) GO TO 350
|
Chris@22
|
243 C
|
Chris@22
|
244 C COMPUTE COMPONENTS OF THE DUAL (NEGATIVE GRADIENT) VECTOR W().
|
Chris@22
|
245 C
|
Chris@22
|
246 DO 50 IZ=IZ1,IZ2
|
Chris@22
|
247 J=INDEX(IZ)
|
Chris@22
|
248 SM=ZERO
|
Chris@22
|
249 DO 40 L=NPP1,M
|
Chris@22
|
250 40 SM=SM+A(L,J)*B(L)
|
Chris@22
|
251 W(J)=SM
|
Chris@22
|
252 50 continue
|
Chris@22
|
253 C FIND LARGEST POSITIVE W(J).
|
Chris@22
|
254 60 continue
|
Chris@22
|
255 WMAX=ZERO
|
Chris@22
|
256 DO 70 IZ=IZ1,IZ2
|
Chris@22
|
257 J=INDEX(IZ)
|
Chris@22
|
258 IF (W(J) .gt. WMAX) then
|
Chris@22
|
259 WMAX=W(J)
|
Chris@22
|
260 IZMAX=IZ
|
Chris@22
|
261 endif
|
Chris@22
|
262 70 CONTINUE
|
Chris@22
|
263 C
|
Chris@22
|
264 C IF WMAX .LE. 0. GO TO TERMINATION.
|
Chris@22
|
265 C THIS INDICATES SATISFACTION OF THE KUHN-TUCKER CONDITIONS.
|
Chris@22
|
266 C
|
Chris@22
|
267 IF (WMAX .le. ZERO) go to 350
|
Chris@22
|
268 IZ=IZMAX
|
Chris@22
|
269 J=INDEX(IZ)
|
Chris@22
|
270 C
|
Chris@22
|
271 C THE SIGN OF W(J) IS OK FOR J TO BE MOVED TO SET P.
|
Chris@22
|
272 C BEGIN THE TRANSFORMATION AND CHECK NEW DIAGONAL ELEMENT TO AVOID
|
Chris@22
|
273 C NEAR LINEAR DEPENDENCE.
|
Chris@22
|
274 C
|
Chris@22
|
275 ASAVE=A(NPP1,J)
|
Chris@22
|
276 CALL H12 (1,NPP1,NPP1+1,M,A(1,J),1,UP,DUMMY,1,1,0)
|
Chris@22
|
277 UNORM=ZERO
|
Chris@22
|
278 IF (NSETP .ne. 0) then
|
Chris@22
|
279 DO 90 L=1,NSETP
|
Chris@22
|
280 90 UNORM=UNORM+A(L,J)**2
|
Chris@22
|
281 endif
|
Chris@22
|
282 UNORM=sqrt(UNORM)
|
Chris@22
|
283 IF (DIFF(UNORM+ABS(A(NPP1,J))*FACTOR,UNORM) .gt. ZERO) then
|
Chris@22
|
284 C
|
Chris@22
|
285 C COL J IS SUFFICIENTLY INDEPENDENT. COPY B INTO ZZ, UPDATE ZZ
|
Chris@22
|
286 C AND SOLVE FOR ZTEST ( = PROPOSED NEW VALUE FOR X(J) ).
|
Chris@22
|
287 C
|
Chris@22
|
288 DO 120 L=1,M
|
Chris@22
|
289 120 ZZ(L)=B(L)
|
Chris@22
|
290 CALL H12 (2,NPP1,NPP1+1,M,A(1,J),1,UP,ZZ,1,1,1)
|
Chris@22
|
291 ZTEST=ZZ(NPP1)/A(NPP1,J)
|
Chris@22
|
292 C
|
Chris@22
|
293 C SEE IF ZTEST IS POSITIVE
|
Chris@22
|
294 C
|
Chris@22
|
295 IF (ZTEST .gt. ZERO) go to 140
|
Chris@22
|
296 endif
|
Chris@22
|
297 C
|
Chris@22
|
298 C REJECT J AS A CANDIDATE TO BE MOVED FROM SET Z TO SET P.
|
Chris@22
|
299 C RESTORE A(NPP1,J), SET W(J)=0., AND LOOP BACK TO TEST DUAL
|
Chris@22
|
300 C COEFFS AGAIN.
|
Chris@22
|
301 C
|
Chris@22
|
302 A(NPP1,J)=ASAVE
|
Chris@22
|
303 W(J)=ZERO
|
Chris@22
|
304 GO TO 60
|
Chris@22
|
305 C
|
Chris@22
|
306 C THE INDEX J=INDEX(IZ) HAS BEEN SELECTED TO BE MOVED FROM
|
Chris@22
|
307 C SET Z TO SET P. UPDATE B, UPDATE INDICES, APPLY HOUSEHOLDER
|
Chris@22
|
308 C TRANSFORMATIONS TO COLS IN NEW SET Z, ZERO SUBDIAGONAL ELTS IN
|
Chris@22
|
309 C COL J, SET W(J)=0.
|
Chris@22
|
310 C
|
Chris@22
|
311 140 continue
|
Chris@22
|
312 DO 150 L=1,M
|
Chris@22
|
313 150 B(L)=ZZ(L)
|
Chris@22
|
314 C
|
Chris@22
|
315 INDEX(IZ)=INDEX(IZ1)
|
Chris@22
|
316 INDEX(IZ1)=J
|
Chris@22
|
317 IZ1=IZ1+1
|
Chris@22
|
318 NSETP=NPP1
|
Chris@22
|
319 NPP1=NPP1+1
|
Chris@22
|
320 C
|
Chris@22
|
321 IF (IZ1 .le. IZ2) then
|
Chris@22
|
322 DO 160 JZ=IZ1,IZ2
|
Chris@22
|
323 JJ=INDEX(JZ)
|
Chris@22
|
324 CALL H12 (2,NSETP,NPP1,M,A(1,J),1,UP,A(1,JJ),1,MDA,1)
|
Chris@22
|
325 160 continue
|
Chris@22
|
326 endif
|
Chris@22
|
327 C
|
Chris@22
|
328 IF (NSETP .ne. M) then
|
Chris@22
|
329 DO 180 L=NPP1,M
|
Chris@22
|
330 180 A(L,J)=ZERO
|
Chris@22
|
331 endif
|
Chris@22
|
332 C
|
Chris@22
|
333 W(J)=ZERO
|
Chris@22
|
334 C SOLVE THE TRIANGULAR SYSTEM.
|
Chris@22
|
335 C STORE THE SOLUTION TEMPORARILY IN ZZ().
|
Chris@22
|
336 RTNKEY = 1
|
Chris@22
|
337 GO TO 400
|
Chris@22
|
338 200 CONTINUE
|
Chris@22
|
339 C
|
Chris@22
|
340 C ****** SECONDARY LOOP BEGINS HERE ******
|
Chris@22
|
341 C
|
Chris@22
|
342 C ITERATION COUNTER.
|
Chris@22
|
343 C
|
Chris@22
|
344 210 continue
|
Chris@22
|
345 ITER=ITER+1
|
Chris@22
|
346 IF (ITER .gt. ITMAX) then
|
Chris@22
|
347 MODE=3
|
Chris@25
|
348 c write (*,'(/a)') ' NNLS quitting on iteration count.'
|
Chris@22
|
349 GO TO 350
|
Chris@22
|
350 endif
|
Chris@22
|
351 C
|
Chris@22
|
352 C SEE IF ALL NEW CONSTRAINED COEFFS ARE FEASIBLE.
|
Chris@22
|
353 C IF NOT COMPUTE ALPHA.
|
Chris@22
|
354 C
|
Chris@22
|
355 ALPHA=TWO
|
Chris@22
|
356 DO 240 IP=1,NSETP
|
Chris@22
|
357 L=INDEX(IP)
|
Chris@22
|
358 IF (ZZ(IP) .le. ZERO) then
|
Chris@22
|
359 T=-X(L)/(ZZ(IP)-X(L))
|
Chris@22
|
360 IF (ALPHA .gt. T) then
|
Chris@22
|
361 ALPHA=T
|
Chris@22
|
362 JJ=IP
|
Chris@22
|
363 endif
|
Chris@22
|
364 endif
|
Chris@22
|
365 240 CONTINUE
|
Chris@22
|
366 C
|
Chris@22
|
367 C IF ALL NEW CONSTRAINED COEFFS ARE FEASIBLE THEN ALPHA WILL
|
Chris@22
|
368 C STILL = 2. IF SO EXIT FROM SECONDARY LOOP TO MAIN LOOP.
|
Chris@22
|
369 C
|
Chris@22
|
370 IF (ALPHA.EQ.TWO) GO TO 330
|
Chris@22
|
371 C
|
Chris@22
|
372 C OTHERWISE USE ALPHA WHICH WILL BE BETWEEN 0. AND 1. TO
|
Chris@22
|
373 C INTERPOLATE BETWEEN THE OLD X AND THE NEW ZZ.
|
Chris@22
|
374 C
|
Chris@22
|
375 DO 250 IP=1,NSETP
|
Chris@22
|
376 L=INDEX(IP)
|
Chris@22
|
377 X(L)=X(L)+ALPHA*(ZZ(IP)-X(L))
|
Chris@22
|
378 250 continue
|
Chris@22
|
379 C
|
Chris@22
|
380 C MODIFY A AND B AND THE INDEX ARRAYS TO MOVE COEFFICIENT I
|
Chris@22
|
381 C FROM SET P TO SET Z.
|
Chris@22
|
382 C
|
Chris@22
|
383 I=INDEX(JJ)
|
Chris@22
|
384 260 continue
|
Chris@22
|
385 X(I)=ZERO
|
Chris@22
|
386 C
|
Chris@22
|
387 IF (JJ .ne. NSETP) then
|
Chris@22
|
388 JJ=JJ+1
|
Chris@22
|
389 DO 280 J=JJ,NSETP
|
Chris@22
|
390 II=INDEX(J)
|
Chris@22
|
391 INDEX(J-1)=II
|
Chris@22
|
392 CALL G1 (A(J-1,II),A(J,II),CC,SS,A(J-1,II))
|
Chris@22
|
393 A(J,II)=ZERO
|
Chris@22
|
394 DO 270 L=1,N
|
Chris@22
|
395 IF (L.NE.II) then
|
Chris@22
|
396 c
|
Chris@22
|
397 c Apply procedure G2 (CC,SS,A(J-1,L),A(J,L))
|
Chris@22
|
398 c
|
Chris@22
|
399 TEMP = A(J-1,L)
|
Chris@22
|
400 A(J-1,L) = CC*TEMP + SS*A(J,L)
|
Chris@22
|
401 A(J,L) =-SS*TEMP + CC*A(J,L)
|
Chris@22
|
402 endif
|
Chris@22
|
403 270 CONTINUE
|
Chris@22
|
404 c
|
Chris@22
|
405 c Apply procedure G2 (CC,SS,B(J-1),B(J))
|
Chris@22
|
406 c
|
Chris@22
|
407 TEMP = B(J-1)
|
Chris@22
|
408 B(J-1) = CC*TEMP + SS*B(J)
|
Chris@22
|
409 B(J) =-SS*TEMP + CC*B(J)
|
Chris@22
|
410 280 continue
|
Chris@22
|
411 endif
|
Chris@22
|
412 c
|
Chris@22
|
413 NPP1=NSETP
|
Chris@22
|
414 NSETP=NSETP-1
|
Chris@22
|
415 IZ1=IZ1-1
|
Chris@22
|
416 INDEX(IZ1)=I
|
Chris@22
|
417 C
|
Chris@22
|
418 C SEE IF THE REMAINING COEFFS IN SET P ARE FEASIBLE. THEY SHOULD
|
Chris@22
|
419 C BE BECAUSE OF THE WAY ALPHA WAS DETERMINED.
|
Chris@22
|
420 C IF ANY ARE INFEASIBLE IT IS DUE TO ROUND-OFF ERROR. ANY
|
Chris@22
|
421 C THAT ARE NONPOSITIVE WILL BE SET TO ZERO
|
Chris@22
|
422 C AND MOVED FROM SET P TO SET Z.
|
Chris@22
|
423 C
|
Chris@22
|
424 DO 300 JJ=1,NSETP
|
Chris@22
|
425 I=INDEX(JJ)
|
Chris@22
|
426 IF (X(I) .le. ZERO) go to 260
|
Chris@22
|
427 300 CONTINUE
|
Chris@22
|
428 C
|
Chris@22
|
429 C COPY B( ) INTO ZZ( ). THEN SOLVE AGAIN AND LOOP BACK.
|
Chris@22
|
430 C
|
Chris@22
|
431 DO 310 I=1,M
|
Chris@22
|
432 310 ZZ(I)=B(I)
|
Chris@22
|
433 RTNKEY = 2
|
Chris@22
|
434 GO TO 400
|
Chris@22
|
435 320 CONTINUE
|
Chris@22
|
436 GO TO 210
|
Chris@22
|
437 C ****** END OF SECONDARY LOOP ******
|
Chris@22
|
438 C
|
Chris@22
|
439 330 continue
|
Chris@22
|
440 DO 340 IP=1,NSETP
|
Chris@22
|
441 I=INDEX(IP)
|
Chris@22
|
442 340 X(I)=ZZ(IP)
|
Chris@22
|
443 C ALL NEW COEFFS ARE POSITIVE. LOOP BACK TO BEGINNING.
|
Chris@22
|
444 GO TO 30
|
Chris@22
|
445 C
|
Chris@22
|
446 C ****** END OF MAIN LOOP ******
|
Chris@22
|
447 C
|
Chris@22
|
448 C COME TO HERE FOR TERMINATION.
|
Chris@22
|
449 C COMPUTE THE NORM OF THE FINAL RESIDUAL VECTOR.
|
Chris@22
|
450 C
|
Chris@22
|
451 350 continue
|
Chris@22
|
452 SM=ZERO
|
Chris@22
|
453 IF (NPP1 .le. M) then
|
Chris@22
|
454 DO 360 I=NPP1,M
|
Chris@22
|
455 360 SM=SM+B(I)**2
|
Chris@22
|
456 else
|
Chris@22
|
457 DO 380 J=1,N
|
Chris@22
|
458 380 W(J)=ZERO
|
Chris@22
|
459 endif
|
Chris@22
|
460 RNORM=sqrt(SM)
|
Chris@22
|
461 RETURN
|
Chris@22
|
462 C
|
Chris@22
|
463 C THE FOLLOWING BLOCK OF CODE IS USED AS AN INTERNAL SUBROUTINE
|
Chris@22
|
464 C TO SOLVE THE TRIANGULAR SYSTEM, PUTTING THE SOLUTION IN ZZ().
|
Chris@22
|
465 C
|
Chris@22
|
466 400 continue
|
Chris@22
|
467 DO 430 L=1,NSETP
|
Chris@22
|
468 IP=NSETP+1-L
|
Chris@22
|
469 IF (L .ne. 1) then
|
Chris@22
|
470 DO 410 II=1,IP
|
Chris@22
|
471 ZZ(II)=ZZ(II)-A(II,JJ)*ZZ(IP+1)
|
Chris@22
|
472 410 continue
|
Chris@22
|
473 endif
|
Chris@22
|
474 JJ=INDEX(IP)
|
Chris@22
|
475 ZZ(IP)=ZZ(IP)/A(IP,JJ)
|
Chris@22
|
476 430 continue
|
Chris@22
|
477 go to (200, 320), RTNKEY
|
Chris@22
|
478 END
|
Chris@22
|
479
|