dhefa Subroutine

subroutine dhefa(A, Lda, N, Ipvt, Info, Job)

DESCRIPTION

This routine is a modification of the LINPACK routine DGEFA and performs an LU decomposition of an upper Hessenberg matrix A. There are two options available:

      (1)  performing a fresh factorization
      (2)  updating the LU factors by adding a row and a
           column to the matrix A.

DHEFA factors an upper Hessenberg matrix by elimination.

ON ENTRY

A

the matrix to be factored.

LDA

the leading dimension of the array A .

N

the order of the matrix A .

JOB

   JOB = 1    means that a fresh factorization of the
              matrix A is desired.
   JOB .ge. 2 means that the current factorization of A
              will be updated by the addition of a row
              and a column.

ON RETURN

A

an upper triangular matrix and the multipliers which were used to obtain it.

The factorization can be written A = L*U where L is a product of permutation and unit lower triangular matrices and U is upper triangular.

IPVT

an integer vector of pivot indices.

INFO

        = 0  normal value.
        = k  if  U(k,k) .eq. 0.0 .  This is not an error
             condition for this subroutine, but it does
             indicate that DHESL will divide by zero if called.

Arguments

Type IntentOptional Attributes Name
real(kind=dp), intent(inout) :: A(Lda,*)
integer, intent(in) :: Lda
integer, intent(in) :: N
integer, intent(inout) :: Ipvt(*)
integer, intent(out) :: Info
integer, intent(in) :: Job

Calls

proc~~dhefa~~CallsGraph proc~dhefa dhefa.inc::dhefa daxpy daxpy proc~dhefa->daxpy idamax idamax proc~dhefa->idamax

Variables

Type Visibility Attributes Name Initial
integer, public :: j
integer, public :: k
integer, public :: km1
integer, public :: kp1
integer, public :: l
integer, public :: nm1
real(kind=dp), public :: t

Source Code

subroutine dhefa(A,Lda,N,Ipvt,Info,Job)
!
integer , intent(in)          :: Lda
real(kind=dp) , intent(inout) :: A(Lda,*)
integer , intent(in)          :: N
integer , intent(inout)       :: Ipvt(*)
integer , intent(out)         :: Info
integer , intent(in)          :: Job
!
integer :: j , k , km1 , kp1 , l , nm1
real(kind=dp) :: t
!
   if ( Job>1 ) then
   !
   !  The old factorization of A will be updated.  A row and a column
   !  has been added to the matrix A.
   !  N-1 is now the old order of the matrix.
   !
      nm1 = N - 1
   !
   !  Perform row interchanges on the elements of the new column, and
   !  perform elimination operations on the elements using the multipliers.
   !
      if ( nm1>1 ) then
         do k = 2 , nm1
            km1 = k - 1
            l = Ipvt(km1)
            t = A(l,N)
            if ( l/=km1 ) then
               A(l,N) = A(km1,N)
               A(km1,N) = t
            endif
            A(k,N) = A(k,N) + A(k,km1)*t
         enddo
      endif
   !
   !  Complete update of factorization by decomposing last 2x2 block.
   !
      Info = 0
   !
   !         Find L = pivot index
   !
      l = idamax(2,A(nm1,nm1),1) + nm1 - 1
      Ipvt(nm1) = l
   !
   !         Zero pivot implies this column already triangularized
   !
      if ( A(l,nm1)==0.0D0 ) then
         Info = nm1
      else
   !
   !            Interchange if necessary
   !
         if ( l/=nm1 ) then
            t = A(l,nm1)
            A(l,nm1) = A(nm1,nm1)
            A(nm1,nm1) = t
         endif
   !
   !            Compute multipliers
   !
         t = -1.0D0/A(nm1,nm1)
         A(N,nm1) = A(N,nm1)*t
   !
   !            Row elimination with column indexing
   !
         t = A(l,N)
         if ( l/=nm1 ) then
            A(l,N) = A(nm1,N)
            A(nm1,N) = t
         endif
         A(N,N) = A(N,N) + t*A(N,nm1)
      endif
      Ipvt(N) = N
      if ( A(N,N)==0.0D0 ) Info = N
   else
   !
   !  A new facorization is desired.  This is essentially the LINPACK
   !  code with the exception that we know there is only one nonzero
   !  element below the main diagonal.
   !
   !      Gaussian elimination with partial pivoting
   !
      Info = 0
      nm1 = N - 1
      if ( nm1>=1 ) then
         do k = 1 , nm1
            kp1 = k + 1
   !
   !         Find L = pivot index
   !
            l = idamax(2,A(k,k),1) + k - 1
            Ipvt(k) = l
   !
   !         Zero pivot implies this column already triangularized
   !
            if ( A(l,k)==0.0D0 ) then
               Info = k
            else
   !
   !            Interchange if necessary
   !
               if ( l/=k ) then
                  t = A(l,k)
                  A(l,k) = A(k,k)
                  A(k,k) = t
               endif
   !
   !            Compute multipliers
   !
               t = -1.0D0/A(k,k)
               A(k+1,k) = A(k+1,k)*t
   !
   !            Row elimination with column indexing
   !
               do j = kp1 , N
                  t = A(l,j)
                  if ( l/=k ) then
                     A(l,j) = A(k,j)
                     A(k,j) = t
                  endif
                  call daxpy(N-k,t,A(k+1,k),1,A(k+1,j),1)
               enddo
            endif
         enddo
      endif
      Ipvt(N) = N
      if ( A(N,N)==0.0D0 ) Info = N
      return
   endif
end subroutine dhefa