diff liboctave/UMFPACK/UMFPACK/Demo/umf4hb64.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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/UMFPACK/UMFPACK/Demo/umf4hb64.f	Fri Feb 25 19:55:28 2005 +0000
@@ -0,0 +1,353 @@
+c=======================================================================
+c== umf4hb =============================================================
+c=======================================================================
+
+c-----------------------------------------------------------------------
+c UMFPACK Version 4.4, Copyright (c) 2005 by Timothy A. Davis.  CISE
+c Dept, Univ. of Florida.  All Rights Reserved.  See ../Doc/License for
+c License.  web: http://www.cise.ufl.edu/research/sparse/umfpack
+c-----------------------------------------------------------------------
+
+c umf4hb64:
+c       read a sparse matrix in the Harwell/Boeing format, factorizes
+c       it, and solves Ax=b.  Also saves and loads the factors to/from a
+c       file.  Saving to a file is not required, it's just here to
+c       demonstrate how to use this feature of UMFPACK.  This program
+c       only works on square RUA-type matrices.
+c
+c       This is HIGHLY non-portable.  It may not work with your C and
+c       FORTRAN compilers.  See umf4_f77wrapper.c for more details.
+c
+c usage (for example):
+c
+c       in a Unix shell:
+c       umf4hb64 < HB/arc130.rua
+
+        integer*8
+     $          nzmax, nmax
+        parameter (nzmax = 5000000, nmax = 160000)
+        integer*8
+     $          Ap (nmax), Ai (nzmax), n, nz, totcrd, ptrcrd, i, j, p,
+     $          indcrd, valcrd, rhscrd, ncol, nrow, nrhs, nzrhs, nel,
+     $          numeric, symbolic, status, sys, filenum
+
+        character title*72, key*30, type*3, ptrfmt*16,
+     $          indfmt*16, valfmt*20, rhsfmt*20
+        double precision Ax (nzmax), x (nmax), b (nmax), aij, xj,
+     $          r (nmax), control (20), info (90)
+        character rhstyp*3
+
+c       ----------------------------------------------------------------
+c       read the Harwell/Boeing matrix
+c       ----------------------------------------------------------------
+
+        read (5, 10, err = 998)
+     $          title, key,
+     $          totcrd, ptrcrd, indcrd, valcrd, rhscrd,
+     $          type, nrow, ncol, nz, nel,
+     $          ptrfmt, indfmt, valfmt, rhsfmt
+        if (rhscrd .gt. 0) then
+c          new Harwell/Boeing format:
+           read (5, 20, err = 998) rhstyp, nrhs, nzrhs
+           endif
+10      format (a72, a8 / 5i14 / a3, 11x, 4i14 / 2a16, 2a20)
+20      format (a3, 11x, 2i14)
+
+        print *, 'Matrix key: ', key
+
+        n = nrow
+        if (type .ne. 'RUA' .or. nrow .ne. ncol) then
+           print *, 'Error: can only handle square RUA matrices'
+           stop
+        endif
+        if (n .ge. nmax .or. nz .gt. nzmax) then
+           print *, ' Matrix too big!'
+           stop
+        endif
+
+c       read the matrix (1-based)
+        read (5, ptrfmt, err = 998) (Ap (p), p = 1, ncol+1)
+        read (5, indfmt, err = 998) (Ai (p), p = 1, nz)
+        read (5, valfmt, err = 998) (Ax (p), p = 1, nz)
+
+c       ----------------------------------------------------------------
+c       create the right-hand-side, assume x (i) = 1 + i/n
+c       ----------------------------------------------------------------
+
+        do 30 i = 1,n
+            b (i) = 0
+30      continue
+c       b = A*x
+        do 50 j = 1,n
+            xj = j
+            xj = 1 + xj / n
+            do 40 p = Ap (j), Ap (j+1)-1
+                i = Ai (p)
+                aij = Ax (p)
+                b (i) = b (i) + aij * xj
+40          continue
+50      continue
+
+c       ----------------------------------------------------------------
+c       convert from 1-based to 0-based
+c       ----------------------------------------------------------------
+
+        do 60 j = 1, n+1
+            Ap (j) = Ap (j) - 1
+60      continue
+        do 70 p = 1, nz
+            Ai (p) = Ai (p) - 1
+70      continue
+
+c       ----------------------------------------------------------------
+c       factor the matrix and save to a file
+c       ----------------------------------------------------------------
+
+c       set default parameters
+        call umf4def (control)
+
+c       print control parameters.  set control (1) to 1 to print
+c       error messages only
+        control (1) = 2
+        call umf4pcon (control)
+
+c       pre-order and symbolic analysis
+        call umf4sym (n, n, Ap, Ai, Ax, symbolic, control, info)
+
+c       print statistics computed so far
+c       call umf4pinf (control, info) could also be done.
+        print 80, info (1), info (16),
+     $      (info (21) * info (4)) / 2**20,
+     $      (info (22) * info (4)) / 2**20,
+     $      info (23), info (24), info (25)
+80      format ('symbolic analysis:',/,
+     $      '   status:  ', f5.0, /,
+     $      '   time:    ', e10.2, ' (sec)'/,
+     $      '   estimates (upper bound) for numeric LU:', /,
+     $      '   size of LU:    ', f10.2, ' (MB)', /,
+     $      '   memory needed: ', f10.2, ' (MB)', /,
+     $      '   flop count:    ', e10.2, /
+     $      '   nnz (L):       ', f10.0, /
+     $      '   nnz (U):       ', f10.0)
+
+c       check umf4sym error condition
+        if (info (1) .lt. 0) then
+            print *, 'Error occurred in umf4sym: ', info (1)
+            stop
+        endif
+
+c       numeric factorization
+        call umf4num (Ap, Ai, Ax, symbolic, numeric, control, info)
+
+c       print statistics for the numeric factorization
+c       call umf4pinf (control, info) could also be done.
+        print 90, info (1), info (66),
+     $      (info (41) * info (4)) / 2**20,
+     $      (info (42) * info (4)) / 2**20,
+     $      info (43), info (44), info (45)
+90      format ('numeric factorization:',/,
+     $      '   status:  ', f5.0, /,
+     $      '   time:    ', e10.2, /,
+     $      '   actual numeric LU statistics:', /,
+     $      '   size of LU:    ', f10.2, ' (MB)', /,
+     $      '   memory needed: ', f10.2, ' (MB)', /,
+     $      '   flop count:    ', e10.2, /
+     $      '   nnz (L):       ', f10.0, /
+     $      '   nnz (U):       ', f10.0)
+
+c       check umf4num error condition
+        if (info (1) .lt. 0) then
+            print *, 'Error occurred in umf4num: ', info (1)
+            stop
+        endif
+
+c       save the symbolic analysis to the file s0.umf
+c       note that this is not needed until another matrix is
+c       factorized, below.
+	filenum = 0
+        call umf4ssym (symbolic, filenum, status)
+        if (status .lt. 0) then
+            print *, 'Error occurred in umf4ssym: ', status
+            stop
+        endif
+
+c       save the LU factors to the file n0.umf
+        call umf4snum (numeric, filenum, status)
+        if (status .lt. 0) then
+            print *, 'Error occurred in umf4snum: ', status
+            stop
+        endif
+
+c       free the symbolic analysis
+        call umf4fsym (symbolic)
+
+c       free the numeric factorization
+        call umf4fnum (numeric)
+
+c       No LU factors (symbolic or numeric) are in memory at this point.
+
+c       ----------------------------------------------------------------
+c       load the LU factors back in, and solve the system
+c       ----------------------------------------------------------------
+
+c       At this point the program could terminate and load the LU
+C       factors (numeric) from the n0.umf file, and solve the
+c       system (see below).  Note that the symbolic object is not
+c       required.
+
+c       load the numeric factorization back in (filename: n0.umf)
+        call umf4lnum (numeric, filenum, status)
+        if (status .lt. 0) then
+            print *, 'Error occurred in umf4lnum: ', status
+            stop
+        endif
+
+c       solve Ax=b, without iterative refinement
+        sys = 0
+        call umf4sol (sys, x, b, numeric, control, info)
+        if (info (1) .lt. 0) then
+            print *, 'Error occurred in umf4sol: ', info (1)
+            stop
+        endif
+
+c       free the numeric factorization
+        call umf4fnum (numeric)
+
+c       No LU factors (symbolic or numeric) are in memory at this point.
+
+c       print final statistics
+        call umf4pinf (control, info)
+
+c       print the residual.  x (i) should be 1 + i/n
+        call resid (n, nz, Ap, Ai, Ax, x, b, r)
+
+c       ----------------------------------------------------------------
+c       load the symbolic analysis back in, and factorize a new matrix
+c       ----------------------------------------------------------------
+
+c       Again, the program could terminate here, recreate the matrix,
+c       and refactorize.  Note that umf4sym is not called.
+
+c       load the symbolic factorization back in (filename: s0.umf)
+        call umf4lsym (symbolic, filenum, status)
+        if (status .lt. 0) then
+            print *, 'Error occurred in umf4lsym: ', status
+            stop
+        endif
+
+c       arbitrarily change the values of the matrix but not the pattern
+        do 100 p = 1, nz
+            Ax (p) = Ax (p) + 3.14159 / 100.0
+100     continue
+
+c       numeric factorization of the modified matrix
+        call umf4num (Ap, Ai, Ax, symbolic, numeric, control, info)
+        if (info (1) .lt. 0) then
+            print *, 'Error occurred in umf4num: ', info (1)
+            stop
+        endif
+
+c       free the symbolic analysis
+        call umf4fsym (symbolic)
+
+c       create a new right-hand-side, assume x (i) = 7 - i/n
+        do 110 i = 1,n
+            b (i) = 0
+110     continue
+c       b = A*x, with the modified matrix A (note that A is now 0-based)
+        do 130 j = 1,n
+            xj = j
+            xj = 7 - xj / n
+            do 120 p = Ap (j) + 1, Ap (j+1)
+                i = Ai (p) + 1
+                aij = Ax (p)
+                b (i) = b (i) + aij * xj
+120         continue
+130     continue
+
+c       ----------------------------------------------------------------
+c       solve Ax=b, with iterative refinement
+c       ----------------------------------------------------------------
+
+        sys = 0
+        call umf4solr (sys, Ap, Ai, Ax, x, b, numeric, control, info)
+        if (info (1) .lt. 0) then
+            print *, 'Error occurred in umf4solr: ', info (1)
+            stop
+        endif
+
+c       print the residual.  x (i) should be 7 - i/n
+        call resid (n, nz, Ap, Ai, Ax, x, b, r)
+
+c       ----------------------------------------------------------------
+c       solve Ax=b, without iterative refinement, broken into steps
+c       ----------------------------------------------------------------
+
+c       the factorization is PAQ=LU, PRAQ=LU, or P(R\A)Q=LU.
+
+c       x = R*b (or x=R\b, or x=b, as appropriate)
+        call umf4scal (x, b, numeric, status)
+        if (status .lt. 0) then
+            print *, 'Error occurred in umf4scal: ', status
+            stop
+        endif
+
+c       solve P'Lr=x for r (using r as workspace)
+        sys = 3
+        call umf4sol (sys, r, x, numeric, control, info)
+        if (info (1) .lt. 0) then
+            print *, 'Error occurred in umf4sol: ', info (1)
+            stop
+        endif
+
+c       solve UQ'x=r for x
+        sys = 9
+        call umf4sol (sys, x, r, numeric, control, info)
+        if (info (1) .lt. 0) then
+            print *, 'Error occurred in umf4sol: ', info (1)
+            stop
+        endif
+
+c       free the numeric factorization
+        call umf4fnum (numeric)
+
+c       print the residual.  x (i) should be 7 - i/n
+        call resid (n, nz, Ap, Ai, Ax, x, b, r)
+
+        stop
+998     print *, 'Read error: Harwell/Boeing matrix'
+        stop
+        end
+
+c=======================================================================
+c== resid ==============================================================
+c=======================================================================
+
+c Compute the residual, r = Ax-b, its max-norm, and print the max-norm
+C Note that A is zero-based.
+
+        subroutine resid (n, nz, Ap, Ai, Ax, x, b, r)
+        integer*8
+     $      n, nz, Ap (n+1), Ai (n), j, i, p
+        double precision Ax (nz), x (n), b (n), r (n), rmax, aij
+
+        do 10 i = 1, n
+            r (i) = -b (i)
+10      continue
+
+        do 30 j = 1,n
+            do 20 p = Ap (j) + 1, Ap (j+1)
+                i = Ai (p) + 1
+                aij = Ax (p)
+                r (i) = r (i) + aij * x (j)
+20          continue
+30      continue
+
+        rmax = 0
+        do 40 i = 1, n
+            rmax = max (rmax, r (i))
+40      continue
+
+        print *, 'norm (A*x-b): ', rmax
+        return
+        end