next up previous contents
Next: Pivotal LU Decomposition Up: LU Decomposition Previous: LU Decomposition

Solution

   MODULE Mapping_Info
    !HPF$ PROCESSORS, DIMENSION(2) :: P
   END MODULE Mapping_Info

   MODULE LU_Decomp_Solver

    IMPLICIT NONE

   CONTAINS

    SUBROUTINE LU_Decomp(LU,rc)
     USE Mapping_Info
     REAL, DIMENSION(:,:), INTENT(INOUT) :: LU
     INTEGER, INTENT(OUT)                :: rc
     REAL, DIMENSION(SIZE(LU,1))         :: MaxElts
     REAL, PARAMETER                     :: Tol=1.0e-20
     INTEGER                             :: i, j, k
     INTEGER                             :: n
!HPF$ DISTRIBUTE *(*,CYCLIC) ONTO *P     :: LU
!HPF$ DISTRIBUTE (CYCLIC) ONTO P         :: MaxElts
      n = SIZE(LU,1)
      rc    = 0
      MaxElts = MAXVAL(ABS(LU),DIM=2)
       IF (ANY(MaxElts < Tol)) THEN
        rc = -1
       ELSE
        n = SIZE(LU,DIM=1)
        DO k=1,n-1
         LU(k+1:n,k) = LU(k+1:n,k)/LU(k,k)
         FORALL(i=k+1:n, j=k+1:n) LU(i,j) = LU(i,j)-LU(i,k)*LU(k,j)
        END DO
       END IF
    END SUBROUTINE LU_Decomp

!------------------------------------------------------------------------


    SUBROUTINE Forward_Substitution(L,B,y,rc)
     USE Mapping_Info
     REAL, DIMENSION(:,:), INTENT(IN) :: L
     REAL, DIMENSION(:), INTENT(IN)   :: B
     REAL, DIMENSION(:), INTENT(OUT)  :: y
     INTEGER, INTENT(OUT)             :: rc
     INTEGER                          :: n, i

!HPF$ ALIGN (:) WITH *L(:,*)          :: B, y
!HPF$ DISTRIBUTE *(*,CYCLIC) ONTO *P  :: L

      n = SIZE(L,DIM=1)
      rc = 0

! calculate first element of Y: y(1) = b(1)/L(1,1). L(1,1) is always 1

      y(1) = b(1)

! Calculate rest of Y. This loop is SEQUENTIAL due to data dependencies

      DO i=2,N
       y(i) = b(i) - SUM(L(i,1:i-1) * y(1:i-1))
      END DO

    END SUBROUTINE Forward_Substitution

!------------------------------------------------------------------------

    SUBROUTINE Backward_Substitution(U,x,y,rc)
     USE Mapping_Info
     REAL, DIMENSION(:,:), INTENT(IN) :: U
     REAL, DIMENSION(:), INTENT(IN)   :: y
     REAL, DIMENSION(:), INTENT(OUT)  :: x
     INTEGER, INTENT(OUT)             :: rc
     INTEGER                          :: n, i

!HPF$ ALIGN (:) WITH *U(:,*)          :: x, y
!HPF$ DISTRIBUTE *(*,CYCLIC) ONTO *P  :: U

      n = SIZE(U,DIM=1)
      rc = 0

! Calculate first element of X:

      x(n) = y(n)/U(n,n)

! Calculate rest of X. This loop is SEQUENTIAL due to data dependencies

      DO i=N-1,1,-1
       X(i) = (Y(i) - SUM(U(i,i+1:N) * X(i+1:N))) / U(i,i)
      END DO

    END SUBROUTINE Backward_Substitution


   END MODULE LU_Decomp_Solver


   PROGRAM LU_Decomp_Test
    USE Mapping_Info
    USE LU_Decomp_Solver
    IMPLICIT NONE
    REAL, DIMENSION(:,:), ALLOCATABLE :: A
    REAL, DIMENSION(:), ALLOCATABLE   :: B, x, y
    INTEGER                           :: rc, n
    LOGICAL                           :: OK = .TRUE.

    !HPF$ ALIGN WITH A(:,*)            :: B, x, y
    !HPF$ DISTRIBUTE (*,CYCLIC) ONTO P :: A

     n = 3

     ALLOCATE (A(n,n), STAT = rc)
     IF (rc == 0) THEN
      A = RESHAPE((/ 1,  2,  3, &
                     2, -1,  1, &
                     3,  4, -1 /), (/3,3/), ORDER=(/2,1/))
     ELSE
      OK = .FALSE.
     END IF

     ALLOCATE (B(n), STAT = rc)
     IF (rc == 0) THEN
      B = (/ 14, 3, 8 /)
     ELSE
      OK = .FALSE.
     END IF

     ALLOCATE (X(n), STAT = rc)
     IF (rc /= 0) THEN
      OK = .FALSE.
     END IF

     ALLOCATE (Y(n), STAT = rc)
     IF (rc /= 0) THEN
      OK = .FALSE.
     END IF

     IF (OK) THEN
      CALL LU_Decomp(A,rc)

      IF (rc == 0) THEN

       PRINT*, "The LU Matrix:"

       DO rc = 1,n
        PRINT*, A(rc,:)
       END DO

      END IF

      CALL Forward_Substitution(A,b,y,rc)

      IF (rc == 0) THEN

       CALL Backward_Substitution(A,x,y,rc)

       IF (rc == 0) THEN

        PRINT*, "Y vector is"
        PRINT*, Y
        PRINT*, " "
        PRINT*, "The solution X is"
        PRINT*, X

       ELSE

        PRINT*, "Error during Backward Substitution"

       END IF

      ELSE

       PRINT*, "Error during Forward Substitution"

      END IF

     ELSE
      PRINT*, "Not enough room to ALLOCATE all the required arrays"
     END IF

   END PROGRAM LU_Decomp_Test


next up previous contents
Next: Pivotal LU Decomposition Up: LU Decomposition Previous: LU Decomposition

©University of Liverpool, 1997
Thu May 29 10:11:26 BST 1997
Not for commercial use.