next up previous contents
Next: BLAS-subroutines Up: Program layout Previous: Pseudo-code

Example

  In this section we give an example of the layout of a subroutine according to the rules given above.

      subroutine profun ( amat, intdia, intpro, n, nmat )
c ======================================================================
c
c
c        programmer     Guus Segal
c        version 1.1    date   26-11-93 (New type of error messages)
c        version 1.0    date   10-11-91
c
c
c
c   copyright (c) 1991,1993  "Ingenieursbureau SEPRA"
c   permission to copy or distribute this software or documentation
c   in hard copy or soft copy granted only by written licence
c   obtained from "Ingenieursbureau SEPRA".
c   all rights reserved. no part of this publication may be reproduced,
c   stored in a retrieval system ( e.g., in memory, disk, or core)
c   or be transmitted by any means, electronic, mechanical, photocopy,
c   recording, or otherwise, without written permission from the
c   publisher.
c
c
c ********************************************************************
c
c                         DESCRIPTION
c
c     SEPRAN subroutine to compute the L U  decomposition of a
c     non-symmetric real matrix.
c     The matrix is supposed to be stored as a profile matrix.
c
c
c     The result of the decomposition may depend on the accuracy of the
c     computer and the condition of the matrix.
c     There is no pivoting applied in this subroutine.
c
c     For a 32-bits machine double precision is almost always necessary in
c     order to guarantee accuracy.
c ********************************************************************
c
c                      KEYWORDS
c
c    linear_solver
c    lu_decomposition
c    profile_storage
c ********************************************************************
c
c                  INPUT / OUTPUT   PARAMETERS
c
      implicit none
      integer n, intdia(n), intpro(n), nmat
      double precision amat(nmat)

c     amat    i/o   In this real array the parts of the matrix to be
c                   decomposed are stored at input. At output the decomposition
c                   overwrites the input
c                   For the matrix a profile storage is assumed as described
c                   in the SEPRAN Programmer's Guide 13.6
c     intdia   i    Integer array of length n containing the positions of the
c                   diagonal elements in amat, i.e. A   = amat ( intdia(i) )
c                                                    ii
c     intpro   i    Integer array of length n containing the column numbers
c                   of the at most left elements in a row in amat
c     n        i    Number of rows of the matrix (n x n )
c     nmat     i    Size of the matrix
c ********************************************************************
c
c                   COMMON BLOCKS

      double precision epsmac, sqreps, rinfin
      common /cmcdpr/ epsmac, sqreps, rinfin
c
c                 /cmcdpr/
c    Machine dependent constants.
c
c    epsmac   i   Machine accuracy
c    sqreps   i   Square root of machine accuracy
c    rinfin   i   Approximation of infinity
c ********************************************************************
c
c                      LOCAL PARAMETERS
c
      integer icolpi, icol, ii, i, j, jj, ij, ji
      double precision rowsum

c     i       Counting variable
c     icol    Max (pi, pj)
c     icolpi  Column number of at most left non-zero element in row i
c     ii      Position of i th diagonal element in array amat
c     ij      Position of element ij in array amat
c     j       Counting variable
c     ji      Position of element ji in array amat
c     jj      Position of j th diagonal element in array amat
c     rowsum  Row norm of matrix
c  *******************************************************************
c
c                              I/O
c
c     none
c ********************************************************************
c
c                SUBROUTINES CALLED

      double precision dasum, ddot

c     DASUM   (SASUM)   Sum of magnitudes of vector components
c     DDOT    (CDOT)    Inner product of two vectors
c     ERCLOS  Resets old name of previous subroutine of higher level
c     EROPEN  Produces concatenated name of local subroutine
c     ERREAL  Put real in error message
c     ERRINT  Put integer in error message
c     ERRSUB  Error messages
c     INSTOP  Stop the program
c ********************************************************************
c
c                ERROR MESSAGES
c
c     104   matrix is singular
c    1820   The matrix found in the solver is completely zero
c ********************************************************************
c
c                    PSEUDO CODE
c
c
c                      METHOD
c
c      The L U   decomposition of the matrix A is based on the following
c      formulas:
c
c              n
c      a   =  sum   l    u                  l   = 1
c       ij    k=1    ik   kj                 kk
c
c      this implies:
c
c                     j-1
c      u   = a   -    sum      l   u       ( j=P  (1) i-1 )
c       ji    ji   k=max(P ,P ) jk  ki          i
c                         i  j
c
c
c                        j-1
c      l   = ( a   -     sum      l    u   ) / d      ( j=P  (1) i-1 )
c       ij      ij   k=max(P ,P )  ik   kj      jj         i
c                           i  j
c
c
c                         i-1
c      u  = d   =   a   - sum  l    u
c       ii   ii      ii   k=P   ik   ki
c                            i
c
c      Here P   denotes the column number of the first non-zero element in row i
c            i
c
c
c      The decomposition is stopped if |d  | < ||A|| * epsmac
c                                        ii
c
c      For the matrix norm we use the maximum row norm, i.e.
c
c      ||A|| = max  sum  |a  |
c               i    j     ij
c
c
c     Pseudo code
c
c     Compute row norm of matrix and multiply by machine accuracy
c     For i = 1 (1) n
c         For j = P  (1) i-1
c                  i
c
c             P = max ( P , P )
c                        i   j
c
c             If ( P < j ) then
c
c                 adapt u   with inner product
c                        ji
c
c                 adapt l   with inner product
c                        ij
c
c             l   = l   / d
c              ij    ij    ii
c
c         adapt d   with inner product
c                ii
c
c         if (d   < ||A|| epsmac ) then
c              ii
c
c            Give error message and stop the program
c ======================================================================
c
c     --- compute row norm of part of the matrix in order to be able to check
c         the stopping criterion for the pivot process
c
      rowsum = 0d0
      do 100  i = 1, n
         rowsum = max ( rowsum, dasum (2*i-intpro(i)+1,
     +                  amat(intdia(i)-i-intpro(i)), 1) )
100   continue
      if ( rowsum.eq.0d0 ) then
         call eropen ( 'profun' )
         call errsub ( 1820, 0, 0, 0 )
         call erclos ( 'profun' )
         call instop
      end if
      rowsum = rowsum*epsmac

c     --- decomposition algorithm
c         Row loop

      do 150 i = 1, n

         ii = intdia(i)
         icolpi = intpro(i)
         if ( icolpi.lt.i ) then

c        --- pi < i
c            Loop over columns

            do 110 j = icolpi, i-1

               icol = max ( icolpi, intpro(j) )
               jj = intdia(j)
               ij = ii-i+j
               if ( icol.lt.j ) then

c              --- p < j

                  ji=ii+i-j
                  amat(ji) = amat(ji) - ddot ( j-icol, amat(jj-j+icol),
     +                                         1, amat(ji+1), -1 )
                  amat(ij) = amat(ij) - ddot ( j-icol, amat(ii-i+icol),
     +                                         1, amat(jj+1), -1 )
               end if
               amat(ij) = amat(ij)/amat(jj)

110         continue

c           --- Diagonal element

            amat(ii) = amat(ii) - ddot ( i-icolpi, amat(ii-i+icolpi),
     +                            1, amat(ii+1), -1 )
         end if

c        --- Check pivot element:

         if ( abs(amat(ii)).lt.rowsum ) then
            call eropen ( 'profun' )
            call errint ( i, 1 )
            call erreal ( amat(ii), 1 )
            call erreal ( rowsum, 2 )
            call errsub ( 104, 1, 2, 0 )
            call erclos ( 'profun' )
            call instop
         end if

150   continue

c     --- end of decomposition

      end


ISNaS ontwikkeling
Wed May 24 08:37:14 METDST 1995