1 SUBROUTINE PCGQS
(NN
,AA
,LENAA
,MAXA
,PP
,YP
,RHO
,START
,WORK
,IFLAG
)
3 C THIS SUBROUTINE SOLVES A SYSTEM OF EQUATION USING THE METHOD OF
4 C CONJUGATE GRADIENTS. THE SYSTEM TO BE SOLVED IS IN THE FORM
13 C AUG = | | | , B = | -RHO |
14 C +--------------+ | |
20 C THE SYSTEM IS SOLVED BY SPLITTING AUG INTO TWO MATRICES
25 C | AA | C | | -PP-C |
26 C M = | | | , L = U * [E(NN+1)**T], U = | | ,
27 C +------+---+ +-------+
31 C E(NN+1) IS THE (NN+1) X 1 VECTOR CONSISTING OF ALL ZEROS EXCEPT FOR
32 C A '1' IN ITS LAST POSITION.
34 C THE FINAL SOLUTION VECTOR, X, IS GIVEN BY
37 C | [SOL(U)]*[E(NN+1)**T] |
38 C X = | I - ----------------------------- | * SOL(B)
39 C | {[(SOL(U))**T]*E(NN+1)}+1.0 |
42 C WHERE SOL(A)=[M**(-1)]*A. THE TWO SYSTEMS (MZ=U, MZ=B) ARE SOLVED
43 C BY A PRECONDITIONED CONJUGATE GRADIENT ALGORITHM.
48 C NN = THE DIMENSION OF THE MATRIX PACKED IN AA.
50 C AA(1:LENAA) CONTAINS THE MATRIX AA, STORED IN PACKED SKYLINE
51 C FORMAT. LENAA AND MAXA DESCRIBE THE DATA STRUCTURE.
53 C LENAA = THE LENGTH OF THE ONE-DIMENSIONAL ARRAY AA.
55 C MAXA(1:NN+2) IN ITS FIRST N+1 COMPONENTS CONTAINS THE INDICES OF
56 C THE DIAGONAL ELEMENTS OF THE MATRIX STORED IN AA.
57 C MAXA(NN+2) IS ASSIGNED THE VALUE LENNAA + NN + 2.
59 C AS AN EXAMPLE OF THE PACKED SKYLINE STORAGE FORMAT, CONSIDER THE
71 C THIS WOULD RESULT IN NN=5, LENAA=9, MAXA=(1,2,4,5,8,10,16),
72 C AND AA=(1,2,3,4,5,6,7,8,9).
74 C PP(1:NN) = THE NEGATIVE OF THE LAST COLUMN OF AUG.
76 C YP(1:NN+1) = THE LAST ROW OF AUG.
78 C RHO(1:NN+1) = THE NEGATIVE OF THE RIGHT HAND SIDE OF THE EQUATION TO
81 C WORK(1:6*(NN+1)+LENAA) IS A WORK ARRAY DIVIDED UP AS FOLLOWS:
83 C WORK(1:NN+1) = TEMPORARY WORKING STORAGE.
85 C WORK(NN+2:2*NN+2) = INTERMEDIATE SOLUTION VECTOR Z FOR MZ=U.
86 C THE INPUT VALUE IS USED AS THE INITIAL ESTIMATE FOR Z.
88 C WORK(2*NN+3:3*NN+3) = INTERMEDIATE SOLUTION VECTOR Z FOR MZ=B.
90 C WORK(3*NN+4:4*NN+4) = STORAGE FOR THE RESIDUAL VECTORS.
92 C WORK(4*NN+5:5*NN+5) = STORAGE FOR THE DIRECTION VECTORS.
94 C WORK(5*NN+6:6*NN+6+LENAA) = STORAGE FOR THE PRECONDITIONING
100 C NN, AA, LENAA, MAXA, PP, YP, AND RHO ARE UNCHANGED.
102 C START(1:N+1) CONTAINS THE SOLUTION VECTOR X.
104 C IFLAG IS UNCHANGED UNLESS THE CONJUGATE GRADIENT ITERATION
105 C FAILS TO CONVERGE IN 10*(NN+1) ITERATIONS (MOST LIKELY DUE
106 C TO A SINGULAR JACOBIAN MATRIX). IN THIS CASE, PCGQS RETURNS
107 C IFLAG = 4, AND DOES NOT COMPUTE X.
110 C CALLS D1MACH, DAXPY, DCOPY, DDOT, DNRM2, DSCAL, GMFADS, MULTDS,
113 C ***** DECLARATIONS *****
115 C FUNCTION DECLARATIONS
117 DOUBLE PRECISION D1MACH
, DDOT
, DNRM2
121 DOUBLE PRECISION AB
, AU
, BB
, BU
, DZNRM
, PBNPRD
, PUNPRD
,
122 $ RBNPRD
, RBTOL
, RNPRD
, RUNPRD
, RUTOL
, TEMP
, ZLEN
, ZTOL
123 INTEGER DIR
, IMAX
, J
, LENQ
, NP1
, Q
, RES
, ZB
, ZU
124 LOGICAL STILLU
, STILLB
128 INTEGER NN
, LENAA
, IFLAG
132 DOUBLE PRECISION AA
(LENAA
), PP
(NN
), YP
(NN
+1), RHO
(NN
+1),
133 $ START
(NN
+1), WORK
(6*(NN
+1)+LENAA
)
136 C ***** END OF DECLARATIONS *****
138 C ***** FIRST EXECUTABLE STATEMENT *****
140 C SET UP BASES FOR VECTORS STORED IN WORK ARRAY.
149 C INITIALIZE PRECONDITIONING MATRIX Q, SET VALUES OF MAXA(NN+1)
150 C AND MAXA(NN+2), COMPUTE PRECONDITIONER.
152 CALL DCOPY
(LENAA
,AA
,1,WORK
(Q
),1)
153 CALL DCOPY
(NP1
,YP
,1,WORK
(Q
+LENAA
),1)
155 MAXA
(NN
+2)=LENAA
+NN
+2
157 CALL GMFADS
(NP1
,WORK
(Q
),LENQ
,MAXA
)
159 C COMPUTE ALL TOLERANCES NEEDED FOR EXIT CRITERIA.
161 CALL DCOPY
(NN
,PP
,1,WORK
,1)
163 CALL DAXPY
(NP1
,1.0D0
,YP
,1,WORK
,1)
168 RUTOL
=ZTOL*DNRM2
(NP1
,WORK
,1)
169 RBTOL
=ZTOL*DNRM2
(NP1
,RHO
,1)
171 C ***** END OF INITIALIZATION *****
173 C ***** SOLVE SYSTEM M Z = U *****
175 C COMPUTE INITIAL RESIDUAL VECTOR FOR THE SYSTEM M Z = U .
176 C RES = (Q**(-1))*(U - M*Z.)
178 CALL MULTDS
(WORK
(RES
),AA
,WORK
(ZU
),MAXA
,NN
,LENAA
)
179 WORK
(RES
+NN
)= DDOT
(NN
,YP
,1,WORK
(ZU
),1)
180 CALL DAXPY
(NP1
,WORK
(ZU
+NN
),YP
,1,WORK
(RES
),1)
181 CALL DSCAL
(NP1
,-1.0D0
,WORK
(RES
),1)
182 CALL DAXPY
(NN
,-1.0D0
,PP
,1,WORK
(RES
),1)
183 CALL DAXPY
(NN
,-1.0D0
,YP
,1,WORK
(RES
),1)
184 CALL SOLVDS
(NP1
,WORK
(Q
),LENQ
,MAXA
,WORK
(RES
))
186 C COMPUTE INITIAL DIRECTION VECTOR.
187 C DIR = (A**T)*(Q**(-T))*RES.
189 CALL DCOPY
(NP1
,WORK
(RES
),1,WORK
,1)
190 CALL SOLVDS
(NP1
,WORK
(Q
),LENQ
,MAXA
,WORK
)
191 CALL MULTDS
(WORK
(DIR
),AA
,WORK
,MAXA
,NN
,LENAA
)
192 WORK
(DIR
+NN
)=DDOT
(NN
,YP
,1,WORK
,1)
193 CALL DAXPY
(NP1
,WORK
(NP1
),YP
,1,WORK
(DIR
),1)
195 C COMPUTE INITIAL INNER PRODUCTS.
197 RUNPRD
=DDOT
(NP1
,WORK
(RES
),1,WORK
(RES
),1)
198 PUNPRD
=DDOT
(NP1
,WORK
(DIR
),1,WORK
(DIR
),1)
200 C REPEAT UNTIL CONVERGENCE OR TOO MANY ITERATIONS.
204 C DO WHILE ((STILLU) .AND. (J .LE. IMAX))
205 100 IF (.NOT
. ((STILLU
) .AND
. (J
.LE
. IMAX
)) ) GO TO 200
207 C IF ||RESIDUAL|| IS STILL NOT SMALL ENOUGH, CONTINUE.
209 IF (SQRT
(RUNPRD
) .GT
. RUTOL
) THEN
211 C IF DIRECTION VECTOR IS ZERO, THEN RE-COMPUTE RESIDUAL,
212 C DIRECTION VECTOR, AND INNER PRODUCTS FROM SCRATCH
213 C (RATHER THAN FROM UPDATES OF PREVIOUS VALUES).
215 IF (PUNPRD
.EQ
. 0.0) THEN
219 CALL MULTDS
(WORK
(RES
),AA
,WORK
(ZU
),MAXA
,NN
,LENAA
)
220 WORK
(RES
+NN
)= DDOT
(NN
,YP
,1,WORK
(ZU
),1)
221 CALL DAXPY
(NP1
,WORK
(ZU
+NN
),YP
,1,WORK
(RES
),1)
222 CALL DSCAL
(NP1
,-1.0D0
,WORK
(RES
),1)
223 CALL DAXPY
(NN
,-1.0D0
,PP
,1,WORK
(RES
),1)
224 CALL DAXPY
(NN
,-1.0D0
,YP
,1,WORK
(RES
),1)
225 CALL SOLVDS
(NP1
,WORK
(Q
),LENQ
,MAXA
,WORK
(RES
))
227 C COMPUTE DIRECTION VECTOR.
229 CALL DCOPY
(NP1
,WORK
(RES
),1,WORK
,1)
230 CALL SOLVDS
(NP1
,WORK
(Q
),LENQ
,MAXA
,WORK
)
231 CALL MULTDS
(WORK
(DIR
),AA
,WORK
,MAXA
,NN
,LENAA
)
232 WORK
(DIR
+NN
)=DDOT
(NN
,YP
,1,WORK
,1)
233 CALL DAXPY
(NP1
,WORK
(NP1
),YP
,1,WORK
(DIR
),1)
235 C COMPUTE INNER PRODUCTS
237 RUNPRD
=DDOT
(NP1
,WORK
(RES
),1,WORK
(RES
),1)
238 PUNPRD
=DDOT
(NP1
,WORK
(DIR
),1,WORK
(DIR
),1)
240 C CHECK FOR CONVERGENCE.
242 IF (SQRT
(RUNPRD
) .LE
. RUTOL
) THEN
248 C UPDATE SOLUTION VECTOR.
249 C Z = Z + AU*DIR, WHERE AU= RUNPRD/PUNPRD.
252 CALL DAXPY
(NP1
,AU
,WORK
(DIR
),1,WORK
(ZU
),1)
254 C COMPUTE RELATIVE CHANGE IN THE SOLUTION.
256 DZNRM
=AU*SQRT
(PUNPRD
)
257 ZLEN
=DNRM2
(NP1
,WORK
(ZU
),1)
259 C IF RELATIVE CHANGE IN SOLUTIONS IS SMALL ENOUGH, EXIT.
261 IF ( (DZNRM
/ZLEN
) .LT
. ZTOL
) STILLU
=.FALSE
.
267 C IF NO EXIT CRITERIA FOR MZ=U HAVE BEEN MET, UPDATE RESIDUAL,
268 C DIRECTION VECTORS, AND INNER PRODUCTS FOR NEXT ITERATION.
272 C UPDATE RESIDUAL VECTOR; COMPUTE <RES,RES>.
273 C RES = RES - AU*(Q**(-1))*M*DIR.
275 CALL MULTDS
(WORK
,AA
,WORK
(DIR
),MAXA
,NN
,LENAA
)
276 WORK
(NP1
)=DDOT
(NN
,YP
,1,WORK
(DIR
),1)
277 CALL DAXPY
(NP1
,WORK
(DIR
+NN
),YP
,1,WORK
,1)
278 CALL SOLVDS
(NP1
,WORK
(Q
),LENQ
,MAXA
,WORK
)
279 CALL DAXPY
(NP1
,-AU
,WORK
,1,WORK
(RES
),1)
280 RNPRD
=DDOT
(NP1
,WORK
(RES
),1,WORK
(RES
),1)
282 C UPDATE DIRECTION VECTOR; COMPUTE <DIR,DIR>.
283 C DIR = (M**T)*(Q**(-T))*RES + BU*DIR,
284 C WHERE BU = RNPRD/RUNPRD. (NOTE: START IS USED AS
285 C A WORK ARRAY HERE).
289 CALL DCOPY
(NP1
,WORK
(RES
),1,WORK
,1)
290 CALL SOLVDS
(NP1
,WORK
(Q
),LENQ
,MAXA
,WORK
)
291 CALL MULTDS
(START
,AA
,WORK
,MAXA
,NN
,LENAA
)
292 START
(NP1
)=DDOT
(NN
,YP
,1,WORK
,1)
293 CALL DAXPY
(NP1
,WORK
(NP1
),YP
,1,START
,1)
294 CALL DAXPY
(NP1
,BU
,WORK
(DIR
),1,START
,1)
295 CALL DCOPY
(NP1
,START
,1,WORK
(DIR
),1)
296 PUNPRD
=DDOT
(NP1
,WORK
(DIR
),1,WORK
(DIR
),1)
304 C SET ERROR FLAG IF THE CONJUGATE GRADIENT ITERATION DID NOT CONVERGE.
306 IF (J
.GT
. IMAX
) THEN
311 C ***** END OF M Z = U SYSTEM *****
313 C ***** SOLVE SYSTEM M Z = B *****
316 C COMPUTE INITIAL RESIDUAL VECTOR FOR THE SYSTEM M Z = B .
318 CALL MULTDS
(WORK
(RES
),AA
,WORK
(ZB
),MAXA
,NN
,LENAA
)
319 WORK
(RES
+NN
)=DDOT
(NN
,YP
,1,WORK
(ZB
),1)
320 CALL DAXPY
(NP1
,WORK
(ZB
+NN
),YP
,1,WORK
(RES
),1)
321 CALL DSCAL
(NP1
,-1.0D0
,WORK
(RES
),1)
322 CALL DAXPY
(NP1
,-1.0D0
,RHO
,1,WORK
(RES
),1)
323 CALL SOLVDS
(NP1
,WORK
(Q
),LENQ
,MAXA
,WORK
(RES
))
325 C COMPUTE INITIAL DIRECTION VECTOR.
327 CALL DCOPY
(NP1
,WORK
(RES
),1,WORK
,1)
328 CALL SOLVDS
(NP1
,WORK
(Q
),LENQ
,MAXA
,WORK
)
329 CALL MULTDS
(WORK
(DIR
),AA
,WORK
,MAXA
,NN
,LENAA
)
330 WORK
(DIR
+NN
)=DDOT
(NN
,YP
,1,WORK
,1)
331 CALL DAXPY
(NP1
,WORK
(NP1
),YP
,1,WORK
(DIR
),1)
333 C COMPUTE INITIAL INNER PRODUCTS.
335 RBNPRD
=DDOT
(NP1
,WORK
(RES
),1,WORK
(RES
),1)
336 PBNPRD
=DDOT
(NP1
,WORK
(DIR
),1,WORK
(DIR
),1)
338 C REPEAT UNTIL CONVERGENCE, OR TOO MANY ITERATIONS.
342 C DO WHILE ( STILLB .AND. (J .LE. IMAX) )
343 300 IF (.NOT
. ( STILLB
.AND
. (J
.LE
. IMAX
) ) ) GO TO 400
345 C IF ||RESIDUAL|| IS STILL NOT SMALL ENOUGH, CONTINUE.
347 IF (SQRT
(RBNPRD
) .GT
. RBTOL
) THEN
349 C IF DIRECTION VECTOR IS ZERO, RE-COMPUTE RESIDUAL,
350 C DIRECTION VECTOR, AND INNER PRODUCTS FROM SCRATCH.
352 IF (PBNPRD
.EQ
. 0.0) THEN
356 CALL MULTDS
(WORK
(RES
),AA
,WORK
(ZB
),MAXA
,NN
,LENAA
)
357 WORK
(RES
+NN
)=DDOT
(NN
,YP
,1,WORK
(ZB
),1)
358 CALL DAXPY
(NP1
,WORK
(ZB
+NN
),YP
,1,WORK
(RES
),1)
359 CALL DSCAL
(NP1
,-1.0D0
,WORK
(RES
),1)
360 CALL DAXPY
(NP1
,-1.0D0
,RHO
,1,WORK
(RES
),1)
361 CALL SOLVDS
(NP1
,WORK
(Q
),LENQ
,MAXA
,WORK
(RES
))
363 C COMPUTE DIRECTION VECTOR.
365 CALL DCOPY
(NP1
,WORK
(RES
),1,WORK
,1)
366 CALL SOLVDS
(NP1
,WORK
(Q
),LENQ
,MAXA
,WORK
)
367 CALL MULTDS
(WORK
(DIR
),AA
,WORK
,MAXA
,NN
,LENAA
)
368 WORK
(DIR
+NN
)=DDOT
(NN
,YP
,1,WORK
,1)
369 CALL DAXPY
(NP1
,WORK
(NP1
),YP
,1,WORK
(DIR
),1)
371 C COMPUTE INNER PRODUCTS.
373 RBNPRD
=DDOT
(NP1
,WORK
(RES
),1,WORK
(RES
),1)
374 PBNPRD
=DDOT
(NP1
,WORK
(DIR
),1,WORK
(DIR
),1)
376 C CHECK FOR CONVERGENCE.
378 IF (SQRT
(RBNPRD
) .LE
. RBTOL
) THEN
384 C UPDATE SOLUTION VECTOR.
385 C Z = Z + AB*DIR, WHERE AB=RBNPRD/PBNPRD.
388 CALL DAXPY
(NP1
,AB
,WORK
(DIR
),1,WORK
(ZB
),1)
390 C COMPUTE RELATIVE CHANGE IN SOLUTIONS.
392 DZNRM
=AB*SQRT
(PBNPRD
)
393 ZLEN
=DNRM2
(NP1
,WORK
(ZB
),1)
395 C IF RELATIVE CHANGE IN SOLUTIONS IS SMALL ENOUGH, EXIT.
397 IF ( (DZNRM
/ZLEN
) .LT
. ZTOL
) STILLB
=.FALSE
.
403 C IF NO EXIT CRITERIA FOR MZ=B HAVE BEEN MET, UPDATE RESIDUAL,
404 C DIRECTION VECTORS, AND INNER PRODUCTS.
408 C UPDATE RESIDUAL VECTOR; COMPUTE <RES,RES>.
409 C RES = RES - AB*(Q**(-1))*M*DIR.
411 CALL MULTDS
(WORK
,AA
,WORK
(DIR
),MAXA
,NN
,LENAA
)
412 WORK
(NP1
)=DDOT
(NN
,YP
,1,WORK
(DIR
),1)
413 CALL DAXPY
(NP1
,WORK
(DIR
+NN
),YP
,1,WORK
,1)
414 CALL SOLVDS
(NP1
,WORK
(Q
),LENQ
,MAXA
,WORK
)
415 CALL DAXPY
(NP1
,-AB
,WORK
,1,WORK
(RES
),1)
416 RNPRD
=DDOT
(NP1
,WORK
(RES
),1,WORK
(RES
),1)
418 C UPDATE DIRECTION VECTOR; COMPUTE <DIR,DIR>.
419 C DIR = (M**T)*(Q**(-T))*RES + BB*DIR,
420 C WHERE BB=RNPRD/RBNPRD.
421 C (NOTE: START IS USED AS A WORK ARRAY HERE).
425 CALL DCOPY
(NP1
,WORK
(RES
),1,WORK
,1)
426 CALL SOLVDS
(NP1
,WORK
(Q
),LENQ
,MAXA
,WORK
)
427 CALL MULTDS
(START
,AA
,WORK
,MAXA
,NN
,LENAA
)
428 START
(NP1
)=DDOT
(NN
,YP
,1,WORK
,1)
429 CALL DAXPY
(NP1
,WORK
(NP1
),YP
,1,START
,1)
430 CALL DAXPY
(NP1
,BB
,WORK
(DIR
),1,START
,1)
431 CALL DCOPY
(NP1
,START
,1,WORK
(DIR
),1)
432 PBNPRD
=DDOT
(NP1
,WORK
(DIR
),1,WORK
(DIR
),1)
440 C SET ERROR FLAG IF THE CONJUGATE GRADIENT ITERATION DID NOT CONVERGE.
442 IF (J
.GT
. IMAX
) THEN
447 C ***** END OF M Z = B SYSTEM *****
449 C COMPUTE FINAL SOLUTION VECTOR X, AND RETURN IT IN START.
451 TEMP
=-WORK
(ZB
+NN
)/(1.0D0
+WORK
(ZU
+NN
))
452 CALL DCOPY
(NP1
,WORK
(ZB
),1,START
,1)
453 CALL DAXPY
(NP1
,TEMP
,WORK
(ZU
),1,START
,1)