comparison liboctave/UMFPACK/UMFPACK/Demo/umf4hb.f @ 5164:57077d0ddc8e

[project @ 2005-02-25 19:55:24 by jwe]
author jwe
date Fri, 25 Feb 2005 19:55:28 +0000
parents
children
comparison
equal deleted inserted replaced
5163:9f3299378193 5164:57077d0ddc8e
1 c=======================================================================
2 c== umf4hb =============================================================
3 c=======================================================================
4
5 c-----------------------------------------------------------------------
6 c UMFPACK Version 4.4, Copyright (c) 2005 by Timothy A. Davis. CISE
7 c Dept, Univ. of Florida. All Rights Reserved. See ../Doc/License for
8 c License. web: http://www.cise.ufl.edu/research/sparse/umfpack
9 c-----------------------------------------------------------------------
10
11 c umf4hb:
12 c read a sparse matrix in the Harwell/Boeing format, factorizes
13 c it, and solves Ax=b. Also saves and loads the factors to/from a
14 c file. Saving to a file is not required, it's just here to
15 c demonstrate how to use this feature of UMFPACK. This program
16 c only works on square RUA-type matrices.
17 c
18 c This is HIGHLY non-portable. It may not work with your C and
19 c FORTRAN compilers. See umf4_f77wrapper.c for more details.
20 c
21 c usage (for example):
22 c
23 c in a Unix shell:
24 c umf4hb < HB/arc130.rua
25
26 integer
27 $ nzmax, nmax
28 parameter (nzmax = 5000000, nmax = 160000)
29 integer
30 $ Ap (nmax), Ai (nzmax), n, nz, totcrd, ptrcrd, i, j, p,
31 $ indcrd, valcrd, rhscrd, ncol, nrow, nrhs, nzrhs, nel,
32 $ numeric, symbolic, status, sys, filenum
33
34 character title*72, key*30, type*3, ptrfmt*16,
35 $ indfmt*16, valfmt*20, rhsfmt*20
36 double precision Ax (nzmax), x (nmax), b (nmax), aij, xj,
37 $ r (nmax), control (20), info (90)
38 character rhstyp*3
39
40 c ----------------------------------------------------------------
41 c read the Harwell/Boeing matrix
42 c ----------------------------------------------------------------
43
44 read (5, 10, err = 998)
45 $ title, key,
46 $ totcrd, ptrcrd, indcrd, valcrd, rhscrd,
47 $ type, nrow, ncol, nz, nel,
48 $ ptrfmt, indfmt, valfmt, rhsfmt
49 if (rhscrd .gt. 0) then
50 c new Harwell/Boeing format:
51 read (5, 20, err = 998) rhstyp, nrhs, nzrhs
52 endif
53 10 format (a72, a8 / 5i14 / a3, 11x, 4i14 / 2a16, 2a20)
54 20 format (a3, 11x, 2i14)
55
56 print *, 'Matrix key: ', key
57
58 n = nrow
59 if (type .ne. 'RUA' .or. nrow .ne. ncol) then
60 print *, 'Error: can only handle square RUA matrices'
61 stop
62 endif
63 if (n .ge. nmax .or. nz .gt. nzmax) then
64 print *, ' Matrix too big!'
65 stop
66 endif
67
68 c read the matrix (1-based)
69 read (5, ptrfmt, err = 998) (Ap (p), p = 1, ncol+1)
70 read (5, indfmt, err = 998) (Ai (p), p = 1, nz)
71 read (5, valfmt, err = 998) (Ax (p), p = 1, nz)
72
73 c ----------------------------------------------------------------
74 c create the right-hand-side, assume x (i) = 1 + i/n
75 c ----------------------------------------------------------------
76
77 do 30 i = 1,n
78 b (i) = 0
79 30 continue
80 c b = A*x
81 do 50 j = 1,n
82 xj = j
83 xj = 1 + xj / n
84 do 40 p = Ap (j), Ap (j+1)-1
85 i = Ai (p)
86 aij = Ax (p)
87 b (i) = b (i) + aij * xj
88 40 continue
89 50 continue
90
91 c ----------------------------------------------------------------
92 c convert from 1-based to 0-based
93 c ----------------------------------------------------------------
94
95 do 60 j = 1, n+1
96 Ap (j) = Ap (j) - 1
97 60 continue
98 do 70 p = 1, nz
99 Ai (p) = Ai (p) - 1
100 70 continue
101
102 c ----------------------------------------------------------------
103 c factor the matrix and save to a file
104 c ----------------------------------------------------------------
105
106 c set default parameters
107 call umf4def (control)
108
109 c print control parameters. set control (1) to 1 to print
110 c error messages only
111 control (1) = 2
112 call umf4pcon (control)
113
114 c pre-order and symbolic analysis
115 call umf4sym (n, n, Ap, Ai, Ax, symbolic, control, info)
116
117 c print statistics computed so far
118 c call umf4pinf (control, info) could also be done.
119 print 80, info (1), info (16),
120 $ (info (21) * info (4)) / 2**20,
121 $ (info (22) * info (4)) / 2**20,
122 $ info (23), info (24), info (25)
123 80 format ('symbolic analysis:',/,
124 $ ' status: ', f5.0, /,
125 $ ' time: ', e10.2, ' (sec)'/,
126 $ ' estimates (upper bound) for numeric LU:', /,
127 $ ' size of LU: ', f10.2, ' (MB)', /,
128 $ ' memory needed: ', f10.2, ' (MB)', /,
129 $ ' flop count: ', e10.2, /
130 $ ' nnz (L): ', f10.0, /
131 $ ' nnz (U): ', f10.0)
132
133 c check umf4sym error condition
134 if (info (1) .lt. 0) then
135 print *, 'Error occurred in umf4sym: ', info (1)
136 stop
137 endif
138
139 c numeric factorization
140 call umf4num (Ap, Ai, Ax, symbolic, numeric, control, info)
141
142 c print statistics for the numeric factorization
143 c call umf4pinf (control, info) could also be done.
144 print 90, info (1), info (66),
145 $ (info (41) * info (4)) / 2**20,
146 $ (info (42) * info (4)) / 2**20,
147 $ info (43), info (44), info (45)
148 90 format ('numeric factorization:',/,
149 $ ' status: ', f5.0, /,
150 $ ' time: ', e10.2, /,
151 $ ' actual numeric LU statistics:', /,
152 $ ' size of LU: ', f10.2, ' (MB)', /,
153 $ ' memory needed: ', f10.2, ' (MB)', /,
154 $ ' flop count: ', e10.2, /
155 $ ' nnz (L): ', f10.0, /
156 $ ' nnz (U): ', f10.0)
157
158 c check umf4num error condition
159 if (info (1) .lt. 0) then
160 print *, 'Error occurred in umf4num: ', info (1)
161 stop
162 endif
163
164 c save the symbolic analysis to the file s0.umf
165 c note that this is not needed until another matrix is
166 c factorized, below.
167 filenum = 0
168 call umf4ssym (symbolic, filenum, status)
169 if (status .lt. 0) then
170 print *, 'Error occurred in umf4ssym: ', status
171 stop
172 endif
173
174 c save the LU factors to the file n0.umf
175 call umf4snum (numeric, filenum, status)
176 if (status .lt. 0) then
177 print *, 'Error occurred in umf4snum: ', status
178 stop
179 endif
180
181 c free the symbolic analysis
182 call umf4fsym (symbolic)
183
184 c free the numeric factorization
185 call umf4fnum (numeric)
186
187 c No LU factors (symbolic or numeric) are in memory at this point.
188
189 c ----------------------------------------------------------------
190 c load the LU factors back in, and solve the system
191 c ----------------------------------------------------------------
192
193 c At this point the program could terminate and load the LU
194 C factors (numeric) from the n0.umf file, and solve the
195 c system (see below). Note that the symbolic object is not
196 c required.
197
198 c load the numeric factorization back in (filename: n0.umf)
199 call umf4lnum (numeric, filenum, status)
200 if (status .lt. 0) then
201 print *, 'Error occurred in umf4lnum: ', status
202 stop
203 endif
204
205 c solve Ax=b, without iterative refinement
206 sys = 0
207 call umf4sol (sys, x, b, numeric, control, info)
208 if (info (1) .lt. 0) then
209 print *, 'Error occurred in umf4sol: ', info (1)
210 stop
211 endif
212
213 c free the numeric factorization
214 call umf4fnum (numeric)
215
216 c No LU factors (symbolic or numeric) are in memory at this point.
217
218 c print final statistics
219 call umf4pinf (control, info)
220
221 c print the residual. x (i) should be 1 + i/n
222 call resid (n, nz, Ap, Ai, Ax, x, b, r)
223
224 c ----------------------------------------------------------------
225 c load the symbolic analysis back in, and factorize a new matrix
226 c ----------------------------------------------------------------
227
228 c Again, the program could terminate here, recreate the matrix,
229 c and refactorize. Note that umf4sym is not called.
230
231 c load the symbolic factorization back in (filename: s0.umf)
232 call umf4lsym (symbolic, filenum, status)
233 if (status .lt. 0) then
234 print *, 'Error occurred in umf4lsym: ', status
235 stop
236 endif
237
238 c arbitrarily change the values of the matrix but not the pattern
239 do 100 p = 1, nz
240 Ax (p) = Ax (p) + 3.14159 / 100.0
241 100 continue
242
243 c numeric factorization of the modified matrix
244 call umf4num (Ap, Ai, Ax, symbolic, numeric, control, info)
245 if (info (1) .lt. 0) then
246 print *, 'Error occurred in umf4num: ', info (1)
247 stop
248 endif
249
250 c free the symbolic analysis
251 call umf4fsym (symbolic)
252
253 c create a new right-hand-side, assume x (i) = 7 - i/n
254 do 110 i = 1,n
255 b (i) = 0
256 110 continue
257 c b = A*x, with the modified matrix A (note that A is now 0-based)
258 do 130 j = 1,n
259 xj = j
260 xj = 7 - xj / n
261 do 120 p = Ap (j) + 1, Ap (j+1)
262 i = Ai (p) + 1
263 aij = Ax (p)
264 b (i) = b (i) + aij * xj
265 120 continue
266 130 continue
267
268 c ----------------------------------------------------------------
269 c solve Ax=b, with iterative refinement
270 c ----------------------------------------------------------------
271
272 sys = 0
273 call umf4solr (sys, Ap, Ai, Ax, x, b, numeric, control, info)
274 if (info (1) .lt. 0) then
275 print *, 'Error occurred in umf4solr: ', info (1)
276 stop
277 endif
278
279 c print the residual. x (i) should be 7 - i/n
280 call resid (n, nz, Ap, Ai, Ax, x, b, r)
281
282 c ----------------------------------------------------------------
283 c solve Ax=b, without iterative refinement, broken into steps
284 c ----------------------------------------------------------------
285
286 c the factorization is PAQ=LU, PRAQ=LU, or P(R\A)Q=LU.
287
288 c x = R*b (or x=R\b, or x=b, as appropriate)
289 call umf4scal (x, b, numeric, status)
290 if (status .lt. 0) then
291 print *, 'Error occurred in umf4scal: ', status
292 stop
293 endif
294
295 c solve P'Lr=x for r (using r as workspace)
296 sys = 3
297 call umf4sol (sys, r, x, numeric, control, info)
298 if (info (1) .lt. 0) then
299 print *, 'Error occurred in umf4sol: ', info (1)
300 stop
301 endif
302
303 c solve UQ'x=r for x
304 sys = 9
305 call umf4sol (sys, x, r, numeric, control, info)
306 if (info (1) .lt. 0) then
307 print *, 'Error occurred in umf4sol: ', info (1)
308 stop
309 endif
310
311 c free the numeric factorization
312 call umf4fnum (numeric)
313
314 c print the residual. x (i) should be 7 - i/n
315 call resid (n, nz, Ap, Ai, Ax, x, b, r)
316
317 stop
318 998 print *, 'Read error: Harwell/Boeing matrix'
319 stop
320 end
321
322 c=======================================================================
323 c== resid ==============================================================
324 c=======================================================================
325
326 c Compute the residual, r = Ax-b, its max-norm, and print the max-norm
327 C Note that A is zero-based.
328
329 subroutine resid (n, nz, Ap, Ai, Ax, x, b, r)
330 integer
331 $ n, nz, Ap (n+1), Ai (n), j, i, p
332 double precision Ax (nz), x (n), b (n), r (n), rmax, aij
333
334 do 10 i = 1, n
335 r (i) = -b (i)
336 10 continue
337
338 do 30 j = 1,n
339 do 20 p = Ap (j) + 1, Ap (j+1)
340 i = Ai (p) + 1
341 aij = Ax (p)
342 r (i) = r (i) + aij * x (j)
343 20 continue
344 30 continue
345
346 rmax = 0
347 do 40 i = 1, n
348 rmax = max (rmax, r (i))
349 40 continue
350
351 print *, 'norm (A*x-b): ', rmax
352 return
353 end